Object-Oriented Game Design

Hi, you’ve probably come here from some of the sites that link to this article. This post is an old one, though, and I’ve written a more up-to-date post called State of the Art Game Objects that you probably want to check out that has a lot more research links and info.

I’ve mentioned Object-Oriented Game Design by Britt L. Hannah before, but I wanted to write a bit more about it.

The article is not named very well. Game Design and Software Engineering are two different things entirely. The article isn’t actually about object-oriented game design, whatever that means, so much as object-oriented software development for games. It doesn’t make the information any less valid, however.

It basically discusses a component-based design for game objects. In a recent issue of Game Developer magazine, Mick West wrote “Evolve Your Hierarchy” which gives an overview of the topic. Some references listed in the article:

To summarize, there is a tendency to use object-oriented languages to create deep hiearchies. Scott Bila’s slides #7 and #8 show how inflexible and unwieldy these hierarchies can be. So if you can’t just have objects inherit from Drawable, Collidable, Shootable, or similar abstractions, what can you do?

You give an entity states in the form of objects. But rather than give a class private members to hold state like you usually would, you create a separate class for each state you would like to store. So instead of the following:


class Ship
{
int hitPoints;
string name;
}

you would do:


class Ship
{
State hitPoints;
State name;
}

What’s the difference? What happens if you need a new type of ship? Or an asteroid? Or a base? Or an alien? It is conceivable that you might have different types of entities that need to track the state of their hit points or names. It is also conceivable that those entities might not need to inherit the behaviors of a ship. So the states are placed into their own objects and assigned to Entity objects. You don’t really need to create a Ship class since a Ship is really nothing more than an entity that has the states that belong to a Ship.

Now the part that was a real eye-opener to me. It is very intuitive to create classes for things we think of as objects. In computer science class, we’re taught that classes have state and functions to manipulate that state. A class is created for a noun, and the functions in the class are the verbs.

Well, it turns out that the verbs can be encapsulated in classes. If we use the first example of a Ship above, actions would be functions defined in Ship:

class Ship
{
void setName( string);
string getName( );
void setHitPoints( int );
void adjustHitPoints( int );
int getHitPoints( );
}

Each time you add some state to a class, you need to add functionality to access such state. It can get really messy, really fast.

If you separate State into its own classes, however, then you can create Action objects to interact between entities. In the second Ship example, you can create an Action called AdjustHitPoints:

class Action
{
void doAction( ) = 0;
}


class AdjustHitPoints : public Action
{
void doAction() { entity.hasState( HIT_POINTS)->hp += amount; }
}

An Entity needs some way for the Action objects to grab state, so hasState() fills that role. Action objects have a function called doAction() that manipuates the states from an Entity.

Can you see how powerful this design is? Instead of hard-coding state into entity classes, you can construct entities at run-time. Instead of giving individual entities the methods to manipulate the state, you separate the events into their own classes. You can add a bunch of Actions to an Entity’s queue. The Entity can then pop the Actions off one-by-one and run doAction(). You don’t call adjustHitPoints(). You just activate the AdjustHitPoints Action object for the entity.

Normally if you have an abstract class called Human, you might derive Man and Woman classes from it. Let’s say you have a pointer to a Human, human, and it points to a PoliceOfficer object. You can’t say human->catchCriminal() because a Human doesn’t have the functionality of a PoliceOfficer. It is sometimes difficult and/or dangerous to dynamic_cast to the proper object type, so it seems overly difficult to get a PoliceOfficer to catch a crook since you don’t know who the PoliceOfficer is. If you change the code so that you know who the PoliceOfficer is, what was the point of needing to use a pointer to Human? Or inheritance, for that matter?

However, if you use the separate components to handle state, you can say human->activateAction( CATCH_CRIMINAL ). If it isn’t a PoliceOfficer, then it won’t have that Action. Nothing happens, just as we would expect. A PoliceOfficer, on the other hand, will have that Action object in its repertoire, and so the CatchCriminal Action will be activated. Eventually some code will run when the PoliceOfficer object updates that will look something like:

action->doActions();

Even better than the above example is that you could create a different type of Human-derived object: a Deputy. A Deputy isn’t a PoliceOfficer, but it should also have the ability to catch criminals. There’s no need to duplicate code. You just give it its own instance of the Action.

Separating state into components and encapsulating events into their own objects allows for more flexibility in your game code. I’ve already found that this design was both easy to implement and fun to use. I have been writing a text-based board game, and I was surprised with how easy it was to construct entities. I sometimes find myself writing code that resembles the deep game entity hierarchy, but whenever I do it is a source of pain. Refactoring the code so that it resembles the component-based model has always made it easier to work with.

15 comments to Object-Oriented Game Design

  • [...] GBGames has a nice introduction to object oriented design for game development. [...]

  • Nice article GB. I’ve used these ideas quite a bit in my real-life day job, but for some reason I had not considered them for games. I was probably too busy trying to figure out what the heck I was doing to concentrate on good design practices.

    It’s very easy to fall back on the deep class hierarchy pattern and it seems to always come back to haunt you as you try to refactor code months or even years later.

    Another great concept is to use container objects as arguments to methods as well.

    So, instead of:
    int DoSomething(int param1, int param2)

    do this:
    ReturnState DoSomething(ActionParameterWrapper params)

    So when you need to change the number of parameters the method takes or what info it returns, you alter the wrapper objects not the method signatures.

    Again, thanks for the reminder!

  • And thank you for the tip, too!

  • Hi Gianfranco, I tried to relate object oriented game design and game development in my thesis a while ago. Yet, I have not discovered Britt’s article (which is indeed a bit off-topic) until I saw your posting. Thanks a lot for that.

  • Lenny: Your thesis is 13MB! Sounds like bedtime reading for the next year for me. B-)

  • This is an interesting idea, unfortunately i’m just starting to learn c++. So I think it goes over my head a little

  • Keith, it’s actually not too hard to understand once you start digging in it. Most likely your game objects have the hierarchy that I describe. You provide all of the data and functions in the class itself. It is how people are taught in school and in books.

    This component-based system is just abstracting it a bit more. Instead of having all of the data and functionality defined in an entity, the entity can be made up of State and Action objects. I can send you my text-based board game code to see what I have so far. It might help you understand it. And the article I referenced has source code in C#. You don’t need to compile it to read through it. I admit, however, that it was a bit confusing to figure out at first.

  • wes

    good article…i’m trying to wrap my head around an implemenation of this….but eveything i’ve come up with seems a bit clunky and seems not to scale up….i’m strongly againsted deep heriarchies GO trees and believe in this component based design. you mention that you avoid dynamic casting but dont u do a dynamic cast in the following (since hasState will return a genaric State class or interface and you will have to cast in into an hp type).

    class AdjustHitPoints : public Action
    {
    void doAction() { entity.hasState( HIT_POINTS)->hp += amount; }
    }

    also how in my impl i find that my actions need to query the game objects for multiple states..is this natural to this design?? i just find its a bit clunky to have to handle behavoir differently depending on what states are registered with the entity. For instnace my rendering action needs the WorldPosition attribute and a Sprite attribute. please any insight would be appriciated.

    There doesnt seem to be much more on this topic outside of the articles you mentioned…. I’ve studied most of the ppt i’ve found (Scott Bilas, GDC 2002), and a couple of others… i googled it and ended up stumbling across this blog. I’ve implemented the Theif 3 data-centric design (as outlined by Alex Duran, gdc 2003).. but found it was a bit of a performance hog…

  • Rick

    I realize that this blog is WAY out of date, but do you have any code samples to share here?

    I’m interested in learning more about the component model, but it’s hard to find good information.

    Anyway, thanks if you get this!

  • Hello, Rick! Check out http://gbgames.com/downloads/componentgame/ which is a text-based, Monopoly-themed game that I had to put together for my day job as a test. It was my first real attempt at trying out what I wrote above. Hope it helps!

  • Roman

    Hi there.

    Good atricle. Now i am looking for some information about OO game design. I found component model is very useful.

    Can you share some links, where i can find more information?

  • Hi again, this is Rick, I left the post on January 13th 2008.

    Thanks for the monopoly example, it has proven very useful in understanding this design pattern. I’ve probably read over the article (http://www.devmaster.net/articles/oo-game-design/) 15 times now and have a pretty good understanding of the concept.

    I’m having a little trouble grasping the concept of the form though. I understand the idea, but the implementation is what is throwing me off. The idea is to separate the tangible from the intangible entities, but they have to relate in some way in order for the tangible object to be drawn for the tangible object. My problem is where and how are they related / stored and processed.

    The example included with the article I’ve found hard to follow, and I don’t think your example goes into this since it’s using console output.

    I’m attempting this game design on a flash game, and so far it’s working out great, but now it’s time to add the visual elements and I’m trying to find the best solution. Any input is greatly appreciated!

  • liam

    hi my name is liam and i am doing a assignment on OO design for games but i can’t find any good sites where there are arguments for and against why oo desing is the best way to go.

    Can anyone help please????

  • Liam: Perhaps you might want to look into OO development versus procedural development in general, and not just for games. I do not know if games have any special benefits compared to other software.

  • [...] of the Art Game Objects By GBGames, on October 27th, 2010 Years ago, I wrote about Component-based Game Design, in which I talked about the advantages of breaking down your game objects into components. [...]

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Follow GBGames on Google Plus and Facebook!

Association of Software Professionals

Twitter: GBGames