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.
“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.
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:
- Code added to the root of the inheritance tree causes big overhead, as almost everything in your game is an entity.
- Code added to the leafs of the tree tends to get copied and thus makes your whole system more error-prone.
- 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.
- Mick West. Evolve Your Hierarchy. http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/, January 2007.
- Levi Baker. Entity Systems Part 1: Entity and EntityManager. http://blog.chronoclast.com/2010/12/entity-systems-part-1-entity-and.html, December 2010.
- Kyle Wilson. Game Object Structure: Inheritance vs. Aggregation. http://gamearchitect.net/Articles/GameObjects1.html, July 2002.
- Adam Martin. Entity Systems are the future of MMOG development – Part 1. http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/, September 2007.
- Adam Martin. Entity Systems: what makes good Components? good Entities? http://t-machine.org/index.php/2012/03/16/entity-systems-what-makes-good-components-good-entities/, March 2012.
- Scott Bilas. A Data-Driven Game Object System. http://scottbilas.com/files/2002/gdc_san_jose/game_objects_slides_with_notes.pdf, Slides, GDC 2002.
- Scott Bilas. A Data-Driven Game Object System. http://scottbilas.com/files/2002/gdc_san_jose/game_objects_paper.pdf, Paper, GDC 2002.
- Insomniac Games. A Dynamic Component Architecture for High Performance Gameplay. http://www.insomniacgames.com/a-dynamic-component-architecture-for-high-performance-gameplay/, June 2010.