Tuesday, January 26, 2010

What actually is Litterbox?

Yes, another gargantuan post, and as always I have way to much to say about way too few things.

A most of the times when I talk about my pet game engine I mention really vague stuff like I'm working on the entity system, or collision system or whatever. This works great during conversations as a quick way to say "I'm actually doing something that doesn't involve scratching my butt", however if you're reading this blog then you're either minimally interested in what actually my engine is about or you have too much spare time and are wasting it reading random blogs from the LudumDare feed(in which case you've probably already read more interesting blogs like Hamumu's or Bleck's and are just too lazy to do anything else than read the less interesting ones) and being this the case you'll probably won't mind if I describe how my pet engine works. If I'm lucky it won't derail as my last post did (yeah, originally I was just going to talk about my engine a bit, but then I got distracted and ended up doing a rant/tutorial about the ever so useful macros).

As said in previous posts my engine name is Litterbox,its goal is to be a great resource of easily reusable modules which I can use in different games, it is also the result of many engine iterations.

So how does it all works?

Everything is loosely hierarchical on top of everything we have SDL and openGL for everything involving input and output. After that we have a loosely defined state machine. The game can have many states like Menu, Game Credits and anything else you can think of, however it does allow to run more than one state at the same time and thus adding the possibility of adding a GUI that is rendered/ran on top of the game itself, taking the input/output away from it.
However the GUI itself, though present two versions ago, was not implemented this time as there was a lot of code waste and it wasn't quite practical.

after the state machine we have what I actually call the game engine itself.
It consists of several interconnected components:

GameManager- is responsible for determining which levels are loaded, which is the
collision system used, he's also responsible for running the EntityManager.

EntityManager- as the name suggest he's the one that adds, removes, saves, loads and calls the entities' think() and render() members

TextureManager- all the texture loading is done through this singleton so no texture is needed to be loaded more than once. He can also reload all textures at once if necessary (useful on window resizing)

RCL-Registered Class List - Even though it's technically a list, being that list isn't the only reason of it's existence. RCL is responsible for storing every single spawn-able entity information on how to spawn it. For every class that can be spawned in game as a BaseGameEntity offspring there is a Shell and Builder object assigned. a Shell is basically the keeper of all the variables that need to be saved whilst the Builder is responsible for actually creating the instances before it can be added to the EntityManager entity list.

BaseGameEntity- the single most important class. it is the parent of every other class that can be spawned inside the game. It comes with a big handful of macros in order to aid in adding new classes to the game (in my past experience adding new entities was difficult as not only I had to rewrite a lot of code but also the organization of the classes themselves was horrid compared to what I have now). It also has inbuilt heritage checking so you can easily know if an entity inherits from a given class.

CollisionSys-This one is (still) the system I'm working on as it proved to be difficult to figure out how to make a "pluggable" collision system for my entities. It is complete with a binary tree based collision checking so it's all good.

DisplayLayerMgr- all the drawing on the screen is based on a Layer system, I have only implemented a very rough placeholder class for this only to see the the results of my work, however this is what I plan to do: Each layer has a number of registered entities it draws, each layer has an independent transformation so you can draw a non scrolling background and a scrolling foreground, you can draw them with different scales,rotations and any other transformations you want. to define which entities should be drawn every entry on the display layer should have a visual bounding box which must have contain all the drawing region. The camera/view bounding box is then transformed by the inverse of the layer's transformation and it checks every entity if it's inside the drawing range.

ParticleSys- one of the pieces of code I'm most proud of right besides the state machine I wrote. It has survived 4 iterations of the engine without a single change. it is easy to set up, easy to create new systems (fire, rain, snowing, sparks and even vampire sparkles), and best of all every system can have a number of effectors. Effectors basically are entities that affect the behavior of the particles, allowing for any behavior change from collision to making the particles fall into a vortex.
Probably the only reasons I see to change this system is to add macros that will make the setup code even easier or adding a scripted behavior support. So I won't have to recompile every time I add an effector or a new particle system.

So basically this is it! It's neither a bare bones engine but it's not a full fledged one either. It's a heap of recyclable code I can use on any of my future projects. Animations, Scripting, Sound and other similar systems will be added only when I'll actually start making games with this, and if they follow the same philosophy I'll have a nice library of reusable assets to create future games and thus perfecting the engine.

I'll make another blog post explaining why I'm making this engine sometime in the near future.
See you later!

ps: some of the terms I use may not be understandable for most people
-by "engine iteration" I mean every time I have to modify the core structure of the engine to add a feature/change the work-flow. At the end of the iteration the engine has to be left at such a state that it is technically possible to make a game on it(even if with tremendous effort from lack of automated level loading). So at the end of every iteration I must be able to have a guy jumping/walking around doing generic game-related things.

-by "engine" I mean a collection of libraries that work together enabling me to build a game from that. Yes, even though it's not anywhere near being finished you could do something you could call a game.

-by "finishing an engine" I mean to have at least one game made for it, and leaving it alone, reusing only a small portion of it on later projects, otherwise if I use most of the code I call it "finishing an iteration" (or giving up on it if I didn't do any game on that engine and didn't reuse most of it core features).

No comments:

Post a Comment