Adam's blog formerly game development, now just casual madness

Prototypin' around

Time for a new project! After strolling around in the realms of potential development headlines, I finally seem to have found something worth doing again.

It has been quite a way to figure it out; the only thought that came into my mind after finishing Nullpunkt was “God, I really hate content creation”. But maybe it was just one of these days. The following weeks I chewed a lot on the how’s and where’s of procedual content generation but didn’t quite get to actually design or prototype something. It turned out to be just another mind experiment.

However, I’m currently pretty interested in game engine design, so I’m doing just that: Designing a game engine.

If anyone of you knows or remembers ZweiDe, this is nothing like it. ZweiDe was a framework to make game development easier but not a game engine at all; it was a bunch of helper classes and API for graphics, audio, input and such. I now want to approach a general-purpose 2D game engine. To be specific: Written in C#, based on OpenTK and using a component-based gameobject system I am just about to implement.

So, what is a component-based gameobject system? It’s easier to begin with what it’s not: A “classic” approach on modelling object classes and behaviours is some kind of inheritance tree that might look like this:

  • GameObject
    • InteractiveObject
      • Vehicle
        • Car
        • Tank
      • Crate
    • BackgroundObject
      • Billboard
      • Vegetation

Its structure depends on the games actual needs. Tanks and Cars make noise, so they’re likely to need some kind of sound emitting logic. As they’re both vehicles, we may directly implement the sound-emitting logic in Vehicle.

“Well”, says the experienced programmer, “a Crate might also be noisy”, so he has to move the audio logic up again: It is now located in any InteractiveObject. But what if we, one day, want to have a Billboard that can also make noises? Or a talking plant? The more flexible we want to be, the more logic travels upwards on the inheritance tree. In worst case, GameObject gets crowded with specialized logic because any object might need some of it one day. One step later, you will ask yourself why you maintain an inheritance tree at all.

To be utmost flexile, why not implement all the logic in GameObject? That sounds really bad. No object will actually use all of the existing functionality. In fact, most objects will only use a very small potion of it. There must be a way to split the GameObjects logic into small, isolated chunks and handle them properly. Well, and here we are: This is what component-based gameobjects are all about.

The idea behind it is that a GameObject is nothing more than a container and manager of Components. Each Component handles a chunk of specific logic and we are free to compose a GameObject out of any combination of Components at runtime. Here’s a list of reasonable Components to give you a more concrete idea of it:

  1. Transform: The objects position, rotation and scale in the scene
  2. Renderer: Abstract component that handles the objects visual representation. Requires Transform.
    1. SpriteRenderer
    2. ShapeRenderer
  3. Camera: Renders the scene from the objects point of view. Requires Transform.
  4. SoundEmitter: Emits a 3D sound. Requires Transform.
  5. etc.

To avoid ambiguity trouble, a GameObject may in general only contain one Component of each type. So much for the summary. There are a lot of details to think about; how Components communicate with each other, how they are queried in the scene and a lot of stuff that will come into my mind when stumbling upon it.

72 of 74