Game Models – A Different Approach

It’s been quite some time since the InnoGames Game Jam #3 where I’ve been working together with – and learned a lot from – Christian Oeing. It was the first time I heard about component-based game models, and I’ve spent a lot of time learning more about this approach to game programming since then.

My intention was to pump out a huge blog post summarizing all advantages of this type of game architecture, but as it turned out, there’s a quite a lot to consider, and so I decided to start a small post series about this topic. In case you’ve never heard of entity systems in games, I advise you to read this series (and its references) carefully, because it’s very likely to make your programming life a lot easier. The last I’d like to add before we dive right in: Please feel free to share your opinion and any feedback in the comments, I’d love to hear from you.

Preliminaries

“So let’s get into the main topic here. Say you’re an engineer set out to create a new Game Object System from scratch, and you’re going to ‘do it right the first time’. You talk to your designer and say ‘What kind of content are we going to have in this game?’ They respond with ‘Oh lots of stuff, trees, and birds, and bushes, and keys and locks and … <trailing off>’ and your eyes glaze over as you start thinking of fancy C++ ways to solve the problem.

The object oriented programming sages tell you to try to determine Is-A relationships and abstract functionality and all that other fun stuff. You go to the book store and buy a C++ book just to be sure, and it tells you to fire up your $5000 UML editor. […]”

– Scott Bilas

Usually your game mainly consists of some sort of game entities: An entity is an object in your game world that can (or cannot) be visible, move around, attack, explode, be targeted, become selected or follow a path, just to name a few. This could be anything from a unit in a classic real-time strategy game to a projectile in a first-person shooter. Sometimes these entities are referred to as actors or game objects, but I’ll stick to the term entity now as that’s the one being used in most references.

Inheritance

The most common approach to implement entities might be to create some kind of Entity base class and have that class and its subclasses encapsulate the main part of your game logic. The Unreal Engine 3 features a base class called Actor which provides functionality for rendering and animating game objects, playing sounds, applying physics and much more. Almost everything in Unreal is an Actor, and there are subclasses like Pawn or Projectile extending that functionality by taking damage or spawning impact effects, for example.

At first, this approach seems natural to object-oriented programmers and totally makes sense for diving right into game development, “getting stuff done”. However, it has a lot of disadvantages which are going to be a real pain in the ass as soon as your game grows and your designers come up with new, great ideas day-to-day.

First, inheritance-based game models are subject to the diamond of death: Let’s assume you create a base Entity class and add two subclasses Selectable and Destructible that provide additional functionality for units in your new kick-ass RTS game. Why? Because the player should be able to select some of your game entities, enabling him to interact with them, whereas some others such as trees or abandoned buildings are just supposed to drop down as soon as your awesome particle-loaded missile explosion puts the sky on fire right next to them.

Next, you want to introduce your first real game logic class called Unit. Units are supposed to be selectable and destructible at the same time. In most cases the language of your choice won’t feature multiple inheritance, and you’ll be forced to abandon one class and move some functionality into your Entity, increasing the overhead for all subclasses.

These game systems show three undesirable characteristics that are hard to get rid of:

  1. Code added to the root of the inheritance tree causes big overhead, as almost everything in your game is an entity.
  2. Code added to the leafs of the tree tends to get copied and thus makes your whole system more error-prone.
  3. Root and leaf classes tend to get very big and are difficult to keep track of.

And there’s another downside to this approach. Changes to the base classes propagate along your class hierarchy, leading to further drawbacks:

  • Programmers that want to implement a new feature need to understand all base classes along the inheritance tree. New programmers in the team will be afraid of breaking something whenever they try to add any tiny new feature.
  • It’s impossible to enforce calling base class functions in every overwritten function. Someone will forget it. Trust me. And you’re gonna spend your whole evening finding that one missing base.Update().
  • The deeper your class hierarchy gets, the more likely you’ll run into call order issues. Subclasses might want to perform some operations after the base class has done its job, and all of a sudden further down your hierarchy you’ll find a class that needs to do so before.

I guess all of us have experienced the above problems, and we’ve done so several times. In my next post I’ll examine a different way of organizing your game logic and point out its advantages and disadvantages in comparison to the inheritance-based model. Again, please feel free to add any thoughts in the comments while I put the remaining stuff down on paper.

(next: Game Models – A Different Approach (Part 2))

References

Author: npruehs

Nick Pruehs is a Co-Founder of Slash Games, Hamburg. In 2009, he graduated as “Best Bachelor” in computer science at Kiel University. Two years later Nick finished his master’s degree in “Sound, Vision, Games” at Hamburg University of Applied Sciences, becoming the Lead Programmer of Daedalic Entertainment shortly after.

2 thoughts on “Game Models – A Different Approach”

    1. Interesting – I’m glad to see that he basically comes to the same conclusion 😉

      Component communication (or system communication, as we’ll see in the next post) can be anything from method calls to events. All of them have their up- and downsides. In a really sophisticated game model you might want to use command objects instead of pure method calls passed between systems, as these objects can easily be serialized and thus sent over the network or stored in a match replay file.

      I think there’s no silver bullet for finding the right granularity. According to Bilas, Dungeon Siege has had hundreds of them, most of them script components however. Just don’t flood your system with unnecessary component types: Think carefully about introducing a new component, just as you would with introducing a new subclass in inheritance-based models. Also, you’ll want to make components sealed so no one runs into danger of extending components instead of introducing new ones.

Questions? Comments? Suggestions? Your turn! :)