Continuing a series of posts where I try to detail the past, present and maybe have a glimpse at some possibilities of where the Game Entity might evolve in the future.

Components

Just over twelve years ago I was putting together additional content for one of my previous games. The content included a new trap that you created like a trap, placed like a trap, even interacted with it as a trap but when it was sprung it would jump off the ground and move around behaving like a creature before eventually returning to a trap again. It sounded great when the designers walked me through the idea the reality of actually implementing it however hit as soon as I sat down to write it, the first issue was where to place it in the entity tree structure.

At the time the game used a traditional game entity structure similar to this:

All the trap functionality of the entity existed obviously in the Trap, and all the creature functionality like navigation and piloting, A.I. behaviors, etc all existed off the Character. Where you place it in the tree also has other knock-on issues to other areas of importance such as the GUI and A.I. systems.

In the end since the object was for all intents and purposes a trap I attached it coming off the Trap Entity. What this meant was that I then had thousands of lines of code in the creature that I either had to relocate up the entity tree to the base entity or I used the infamous cut-and-paste (with all the issues associated with that).

All of this work wasn’t eloquent, wasn’t clever, was incredibly error prone, caused code bloat and took triple the amount of time it should have taken. The only good to come out of it was a very cool trap for the player and a firm conviction on my part that there had to be a better way of doing things.

The Component Revolution

Components have a number of major features going for them over the traditional game entities.

Self contained – Functionality is isolated into manageable containers

Re-usable – No more cut-and-paste, if you want an entity to have an ability you just need to attach it and depending upon your system can be as simple as a tick-box or an extra line in a configuration file.

Resources Efficent – The entity only uses the resources (CPU & memory) it requires.

Data Driven Components

The purest form of components is the data driven version, it uses configuration data to assemble the entity at runtime, for example:

<EntityType>
    <Name> Toggle Switch </Name>
 
      <ComponentList>
        <Component> Render </Component>
        <Component> Audio </Component>
        <Component> Interactive </Component>
        <Component> TwoStageSwitchLogic </Component>
    </ComponentList>
</EntityType>

What is really interesting about this system is that because an entity is constructed at runtime it also means it’s possible to modify an entity while the game is running.  Not that I have ever seen this done, but there are some intriguing possibilities with the tech.

Under this model the game entity is essentially stripped of its functionality and data, making it for all intents and purposes a blank container, what is left of the game entity is pretty minimal:

    Name (String)
 
      Unique Id
 
      World Transform
 
      List of attached components.

Components written under this model must be bullet proof and because of that you tend to get more stable and robust code being written (always a plus). The only negative really is the slightly higher memory and CPU overhead of handling components.

Plug-in Components

Sometimes the overhead of working with a data driven model is too high especially if you are developing for a platform that has some major limitations (at least when compared to the X360, PS3 or PC) such as Nintendo’s DS, Sony’s PSP, even the PS2 and Wii might not have enough kick. The Plug-in model offers a way to still have components and tap into their benefits while removing some of the overhead of the data driven model.

With plug-ins you no longer create entities at run time, instead they are usually declared in code and built at compile time, for example:

Class CToggleSwitch : public CEntity
 
  {
 
  public:
 
       EntityDeclare( CToggleSwitch, CEntity, eEntityToggleSwitch );
     //- Constructor / Destructor ----------------------------------------------------------
 
                  CToggleSwitch( void );
 
       virtual    ~CToggleSwitch( void );
private:
 
       //- Plugins ---------------------------------------------------------------------------
 
       EntityUsePlugin( CToggleSwitch, CPluginRender, m_pRender );
 
       EntityUsePlugin( CToggleSwitch, CPluginPhysics, m_pPhysics );
 
       EntityUsePlugin( CToggleSwitch, CPluginInteractive, m_pInteractive );
 
       EntityUsePlugin( CToggleSwtich, CPluginTwoStageSwitchLogic, m_pToggleSwitch );
 
  };

Obviously this means that the plug-in model has an entity tree structure, however it is generally flat. There is nothing stopping you from creating a more complex structure but personally I have always steered clear of that choice mainly to make sure I never get into the same scenario I was in years ago.

When Components Go Bad

Granularity is the biggest pitfall when working with components, I’ve seen engineers take the entire contents of their game entity and just dump it into a single component. Often saying that because the new component requires all the functionality it made sense to include it all, one engineer even did it so he wouldn’t have to worry about any inter-component interactions.

Making components that were so large that they couldn’t be re-used by other entities is one extreme of the scale, the opposite end of course is when components encapsulate such small functionality that the overhead of managing and processing the components becomes more than the cost of the features they provide.

A more insidious issue with components to watch out for is circular dependencies as a general rule data should only flow one way, from higher levels to lower levels. For example you do not want your physics component talking directly to your A.I. Brain.

Component to Component Interactions

The simplest method of interaction from one component to another is simply to retrieve a pointer to the required component and make direct calls. The problem with this of course is that you have just made a link between the calling component and the target component.

If you wanted to avoid this there are two methods available, the first is by way of an event (or message), sent to the components to either perform a specific task or return some information. The components usually handle this event immediately allowing access to component functionality without necessarily creating a hard link to the component.

The second method is the Mailbox, where a message is sent to the component and stored for when the component is ready to process the message. This is usually during its next update phase and gives the ability to completely isolate one component from everything else, the negative side is that it’s a pain to debug and you will start to get latency issues as it can take several frames to handle a message.

The Processing Architecture

Under the traditional entity system calling update on an entity meant everything relating to that entity was processed. One of the benefits of isolating functionality into discrete components is that we no longer need to update everything in one go, we could for example have our rendering components updated during the render phase, the physics components updated straight after the simulation step.

I have actually never needed to do more than the basic components like rendering, physics and audio, that however doesn’t mean that it’s not something that can’t be exploited and used if the game would benefit from it.

Next Time…

In part four I’m going to consider the bigger picture of how game entities interact with other game systems.

Coming Up

The Game Entity – Part IV, Game Systems

The Game Entity – Part V, Future Ponderings

Previous parts

The Game Entity – Part I, A retrospect

The Game Entity, Part II, The Life Cycle and Processing Architecture