CANINE Engine Revisted

Lo and behold, I have returned!

More than just to my blog, though. I’m revisiting the CANINE engine, a Wolfenstein-3D-style game engine that I said I was going to focus on and then forgot about! Sadly, more important things came up and it got pushed too far back. I am really interested in getting this game done, because I really like the retro feel it gave off.

Its current status is less than optimal. There is a working C++/Allegro5 code base that looks like what I had shown in my last video, but with a cruddy attempt at a skybox and support for see-through grates. I forked it to add Google V8 JavaScript to it, but V8 ended up feeling too bulky and I couldn’t think of a good way to integrate it into the engine. Largely, this was caused by the engine’s poor design. The raycaster’s great, the renderer’s great-ish, the resource management is where things broke down.

I started managing resources in a way that is just too complicated. Unsigned 8-bit integers (usually represented as ASCII printable characters) map resources in a palette which the level associates with itself. The renderer pulls textures from it, but it’s even more complicated than that. The palette doesn’t actually manage resources, it stores a table of identifier-filename pairs, and gets the bitmaps for each request from a dedicated resource manager. The resource manager stores data in filename-pointer pairs and handles loading automatically.

This entire architecture makes me sad and I can’t go on with it. Instead, I’m going to rewrite the engine. Yes, for a third time, but read on! This time I’m going to plan things out, and I’m making the process public.

I’ve decided to release CANINE as free/libre and open source software under the GNU General Public License. This means it will grant you the right to run CANINE for any purpose, modify it and redistribute original/modified versions (even commercially). All that the license requires is that you share these rights with anyone you redistribute CANINE, and any modifications, to.

Initially I’m going to do is upload the three editions I have. First is Alpha-1, which is written in C and supports a basic textured environment. Next is Alpha-2, a rewrite in C++ that supports the weird palette-resource system, skyboxes and transparency in walls. Lastly is Alpha-2J, which sports some initial bindings to JavaScript.

My plan for the next version is to write a few libraries and run some tests before writing the main game. I believe the project modularity will help me create a clean system: each project is created and maintained separately, allowing each one to be completed individually so that the final product requires little work in comparison.

The first library, codename “Jewel,” will provide a simple menu engine in C built on top of the Allegro game programming library. The idea is to design the entire menu as one multidimensional array with callback support. Here’s an example of what I have in mind:

static const MENU *game_menu = {
   { MENU_BUTTON, "Start", &start_game },
   { MENU_SUBMENU, "Options", NULL },
      { MENU_SUBMENU, "Video", NULL },
         { MENU_TOGGLE, "Fullscreen?", &set_fullscreen },
         { MENU_TOGGLE, "Blood/Gore?", &set_blood_gore },
         { MENU_END, NULL, NULL },
      { MENU_SUBMENU, "Audio", NULL },
         { MENU_SLIDER, "Music Volume", &set_music_volume },
         { MENU_SLIDER, "Sfx Volume", &set_sfx_volume },
         { MENU_END, NULL, NULL },
      { MENU_END, NULL, NULL },
   { MENU_SUBMENU, "Quit", NULL },
      { MENU_MESSAGE, "Are you sure you want to quit?", NULL },
      { MENU_BUTTON, "Yes", &quit_game },
      { MENU_BACK, "No", NULL },
      { MENU_END, NULL, NULL },

Inspired by the Fast Light Toolkit’s menu system, I believe it’s easy for people to work with and allows for a really lightweight implementation. We’ll see how it goes.

Afterwards will be a scripting language, codename “Orange.” What held me up in each version of CANINE was trying to figure out a good way to implement scripting. In CANINE Alpha-1 it lead me to believe the design was flawed. In CANINE Alpha-2 the primary problem was my inability to select a language.

I have a problem with pretty much every language I encountered. Squirrel’s too slow, AngleScript doesn’t have enough documentation of the actual language, Pawn doesn’t compile on 64-bit GNU/Linux, TinyScheme is also slow, GameMonkey makes me feel like I’m downloading a virus, PSL’s design just doesn’t fit, and Lua is insecure. There’s some cross-over there, but I just listed my major grievances with each one. GameMonkey could fair well with a better website.

For this reason, I’m going to implement my own scripting language. I’m going to keep it small and simple, considering it’s going to be my first implementation of a programming language since my Tiny BASIC compiler. I’m shooting for a bit of a combo between PSL (PLIB Scripting Language/Library) and Dink-C (from the anti-hit title Dink Smallwood). The language will be a dumbed-down version of C designed for an event-driven game engine. All that I’ll implement in the beginning is file-level globals, int/float/const-string variables, int/float arithmetic, public/private functions and the if-statement.

That’s right. The if-statement. Not for, not while, not do-while. For the stuff I’m starting out with, I won’t need loops. Eventually I will implement them, but I want to get something working first.

The idea is that each script defines handlers for an object. For instance, the “zombie.script” file will define the “update” function to handle its movement each loop and the “collision_bullet” function to handle getting shot. The point of the public/private function system is to allow me to add as many callbacks as I want over time without worrying about accidentally calling a private helper function from older scripts that just so happens to have the same name.

The compiler will be separate from the virtual machine so that game loading won’t be affected by compilation efficiency. I’m still pretty n00b at compilers so I don’t want to have to worry about that. Scripts will be stored in a portable, CPU-independent format so that you won’t have to worry about switching between 32/64-bit and big/little-endian machines.

The last thing I’m going to do is write a little client-server chat program and experiment with the networking libraries out there. Why? I think it’d be cool if CANINE had multiplayer support, because playing against friends (or enemies, really) is fun. The Enet library is looking particularly enticing… more on that later.

Throughout this process, I’m going to try and blog as much as possible (without overdoing it). I believe that talking about it constantly will help me stay focused on the project(s). Of course, I’ll still have normal work to do, but I’ll make time.

That’s all I have to say. Noch guten tag!

More information

  • The last post I had on CANINE
  • PSL and Dink-C, so you have an idea of what I’m thinking about
  • Enet, same reason as above
  • Google Translate, to figure out what that last thing I said was
Be Sociable, Share!

Comments are closed.