Game Engines 101: The Entity/Component Model

There are many approaches to game engine design, and this is far from the best in all cases, but it is certainly the most common overall. Welcome to the wide world of component-based entities.

First, let’s address the way most people fresh out of Data Structures, CS 101, etc think of game objects:


class Engine
{
int numberOfCylinders;
....
}

class Car : Public Engine
{
bool hasComfySeats;
bool numSeats;
...
}

… which is, in a word – bad.  In two words, really bad.  In two different words, painfully inflexible.  You can make a game this way, and many have, and it was even “the” way to do it way back in the day, but those days have passed, game engines have blossomed in size, and now we’re willing to spent a bit of processing power on making our tech flexible and resuable.

Let’s take a peak at why.  Imagine you need 10 different enemies.  Ok, great, now we have 10 different enemy classes.  So far so good, right?  So now we realize that each of those entities is 90% the same, and only 10% different.  We don’t want to copy-paste identical code that many times, it would be entirely unmaintainable as it grew and we wanted to tweak the base functionality of entities, so we think – “ah hah!  we’ll make a shared function for the equivalent bits!”.  Ok, great.  But now one of those entities has a slightly different AI routine too, but the same everything else.  So now we break the AI out of the shared code, and give him a unique AI section.  Now there’s another entity, that wants that AI, but has different physics, so now we have to break the physics out of that shared code, make a 2 versions of physics, and then the new entity has a unique physics but shares the other different AI and then AAARRRRRGGGGH.

So we stop just short of hanging ourselves, back out, and realize that that route is unsupportable.  So we go back to thinking about keeping each entity separate, and just copy-pasting code around, and even if it’s identical – whatever, if we change one, we just remember to change them all.  Now a year later, you have 100 entity types… and you realize you made a typo in their physics stepping.  All of their physics routines have to be changed.  AAAAARRRRRRGGGHHH.

Thus – enter components. Which, and excuse the extremely rough pseudo code, might go something like this…

class Entity
{
void AttachComponent(ComponentType, argumentList, name)
void DetachComponent(name)
void UpdateComponents()
void UpdateComponentType(ComponentType typeOfComponentToUpdate)
void HandleMessage(MessageType message) // echoes to all attached components
...
BaseComponentList attachedComponentList
....
}

class BaseComponent
{
virtual void Startup()
virtual void Update()
virtual void Shutdown()
virtual void HandleMessage(MessageType message)
....
}

class RenderComponent: Public BaseComponent
{
virtual void Startup() // (registers the renderable mesh with the rendering system)
virtual void Shutdown() // (removes the renderable mesh from the rendering system)
...
}

Abolish the idea of an object.  There is no such thing as a “chair”, or an “orc” – there is only data, and components, that together may resemble such.  A chair has “physics”, “rendering”, and “the ability to be sat upon” (which we’ll call “interaction”).  An orc has “moving physics” since it can walk, “rendering”, and “AI”.  Each of these components, and this is a very stripped-down example, stands alone, and has no actual knowledge of whatever else may be attached to a given entity.  The entity itself, such as it is, only has a list of components attached to it, and a generic data “bucket” that all components can write to or read from.  It may also have a messaging system, which lets it broadcast one of a list of messages out to every attached component, and the components may be able to themselves send messages to the entity they’re attached to (which then broadcasts the message out to all components attached to the entity… including the component that sent the message, but it’s smart enough to ignore it).  This messaging system is also likely exposed to the world, allowing other actors in the world to send messages to the entity, and thus all components attached to that entity, but more on that in a sec.

Now the beauty of this is reusability.  Two rendering components are basically the same thing – they take a mesh and make it render – meaning that every renderable object in your game can, mostly, share that one component.  All that changes, really, is the argument you pass the component on creation, which’ll probably be the filename of a mesh to render amongst other things.  Even if you have a few different classes of renderables, particles vs skinned objects vs rigid vs whatever, that’s still just a handful of renderable components that are easily tracked, which can all be transparently assigned to whatever entity you choose.  Physics are likely even more generalizable.

Things will likely break down if you assign a ton of physics components to a single object, which is to say that not EVERY component can be put on one object with the expectation of them all just working things out, but the point is flexibility, not being completely idiot-proof.  You still have to consider component interactions, and in general the idea is that some components expect that only one of its class of component will be attached at a time – if a given component wants to “own” a particular chunk of data that lives on the entity, like the name of an attached mesh resource or the entity’s physical position, ideally you will have attached nothing else that also tries to own that data. There’s also a balancing act with how aware a component is allowed to be of other attached components, with one extreme being no communication allowed aside from messaging and data putting/reading, the other extreme not looking much different from never having used components in the first place. Generally, you want to start with isolated components, and only skew the other way as you note performance problems (THROUGH PROFILING! DO NOT PRE-OPTIMIZE!) and rework your component interactions.

Your update cycle thus becomes something like this: your world manager says “update the world”, and that update the world function likely has some specific order in which it updates components – physics needs to come before rendering, and so on – and for each class of component, it gathers a list of all entities with that component, and says “update your physics.”  So the entities run Update() on their list of components of that type.  Not everything will necessarily update that way – rendering probably keeps track of meshes directly and renders them directly, with rendering components just updating their mesh’s information during their Update() step, and the actual physics-sim portion of physics would do likewise – but much will.

If you’re still not getting it, let’s give a practical example of how this might work:

You have a mobile animated creature.  It has a skinned mesh component, and a mobile physics component, and a movement AI component.  The AI component calculates a movement vector and puts it into the entity’s data store, the mobile physics component takes the movement vector data from the entity and physically moves the entity along (and adds current velocity data to the entity), and the skinned mesh component determines if the object is moving based on velocity and either does a walking animation or a standing animation depending.

You have a second entity, which is a trigger physics component and an explosion AI component.  The trigger physics component defines a bound you can walk through, it just waits for a collision, which sends a message to the attached-to entity when anything collides with it.  The explosion AI component waits until it gets a collision message, waits 5 seconds, and then does a collection (by asking the entity manager) for any nearby entities – and to each, sends a physical impulse message.

The player, walking in the circle, eventually enters the explosion region, and then 5 seconds later gets the physical impulse message.  Its render and AI components ignore it, but the physics component recognizes that message, and applies the requested physical impulse – launching the player up and away.  The player lands, and then continues walking in a circle as defined by the other two components.

Done.  A complex interaction broken down by components, that can be varied in a hundred different ways while writing barely any new code.  You could change the way the entity responds (maybe the player’s AI ignores the explosion message, whereas an enemy’s AI responds by running away – but all you do to do that is change the enemy’s AI component), the arguments to any of those messages, etc, and nobody has to go editing 20 different entities by hand to do it.

Now there is another important aspect to components – namely that they easily allow for your engine to be data-driven.  However, that is a topic for another posting, so… for the moment, just stick with what we’ve got here.

28 Comments

  1. Posted on December 20, 2010 at 4:45 am by Mark

    Hi there. I just got introduced to component-based game objects, and this is the second article I read which proposes a messaging system to decouple components. The first one used plain ints for their message type, which won’t allow you to send any information with the message other than the message type itself. Here you talk about MessageType; is MessageType some sort of base class for all concrete messages? If so, won’t you have to resort to type checking / downcasting to parse the concrete message when it reaches a component?

    For instance, when you say your physics component recognises the physical impulse message, how is it recognising it exactly? What the HandleMessage method receives as a parameter is a MessageType, not a concrete message.

    Now, using integers or any hard-coded enumeration as a message type does seem quite like a limitation; for instance, say you want your AI component to make your character flee when it takes a certain amount of damage. Your Health component or whatever would broadcast a message when damage is taken, but it would need to ship the damage taken and/or current health with the message, otherwise the AI component wouldn’t know when to act. Firing a message saying damage has been taken would not be enough; you would need to know how much damage has actually been taken.

    We could think we could leave the damage taken / current health data in the game object itself, but that would defeat the entire purpose of using components, since our game object would quickly grow as bloat as in the monolithic approach. Querying the Health component for the current health doesn’t seem to be an alternative either, since that would couple the Health and AI components together and defeat the purpose of a messaging system.

    Is there any way to solve this problem without resorting to downcasting, shared data, or coupling components together?

    Sorry if I’m totally lost here, I’ve got zero experience with this.

  2. Posted on December 20, 2010 at 8:21 am by Mark

    I still can’t come up with a solution; I guess the coupling between components is inevitable unless you push data into the game object itself.

    I was thinking the messaging system would still be useful, however, since each component would only query the other component’s state when a certain event takes place, as opposed to doing the queries on every single frame update, which could bring a performance hit.

  3. Posted on December 20, 2010 at 9:30 am by Megan

    Heh, you’re doing fine, you’re not lost ;) It just takes a bit to wrap your head around. Let’s take your specific example: an AI component that flees when a certain amount of damage is taken.

    Now in this case, yes, I would absolutely recommend your “entity” store a standard Health value, and that your AI component simply grab Health in its Update() and, when it drops below a certain number, initiate the Flee state or whatever. A lot of components care about that chunk of data, so, it’s handy to centralize. The data on the entity is not bloat – there WILL be a lot of it, but that’s fine, the goal here isn’t to avoid data. Going this route probably results in MORE individual data members than would otherwise be required. The goal here is only to break out functional components and avoid monolithic code bases, and that goes fine with a data store that happens to have a lot of distinct bits of data, since those bits of data are still individually managed by some specific component or some set of components – not everything knows or cares about them.

    As to how this entity data store looks, I mean it could be something as simple as a hashmap, where each data element has a string name. Or you could do a more fixed-style array, with an enum of pre-defined data elements. Or you could even define an actual DataStore class with specifically-named variables, all in code, and just add a new data element every time you need one. That last is the fastest, most likely, but also the least flexible, and having flexibility here can count – especially if, for instance, you eventually define a component that operates entirely within script – so… well, look around, and consider your options. There’s a lot of ways of handling this.

    Also remember that your “entity” is really kind of a figment of your imagination. There is no entity, there is only a collection of components, so you could even ditch the entity concept entirely and have each component track whatever data it cares about, and have a message that you send to the entity to get a data element (called “Health” or whatever, with message GetFloatData), into which you pass a pointer to a float, that sends back the “Health” data if there exists an attached component that defines that data. This is by far the most flexible, but also not terribly fast, so… yeah, consider your options, figure out which ones serves you best. The key consideration is how often you expect to need to read or write these numbers, since they can of course be cached locally within a component to avoid constantly reading or writing to them (and if you expect to barely ever read or write to them, then flexibility is far, far more useful than speed). As is typically the argument, I would advise not optimizing this too heavily until you’re further in – start at least somewhat flexible.

    Now let’s modify your example somewhat, and say that you want your AI component to flee if your health is below a certain number AND you just got hit. We’re probably going to emit some kind of GhostImpact message from the physics component – it’ll probably have ghost colliders that look for other ghost colliders, usually weapons, and it’ll emit a GhostImpact message which has 2 arguments, the flat of the ghost object that’s hitting us (call it “Sword”), and, say, the force of impact. This of course implies messages need arguments… which they do.

    There’s a couple of ways you can do this. At my current job, we made a fancy precompiler system that takes an XML and converts it into code, and we use the XML to easily define a message and the arguments it has… but ignoring the fanciness, all we’re really doing is defining a BaseMessage class, and then all specific messages inherit from that class. We then have a giant enum into which we add an entry for each message, in this case it’d be GHOST_IMPACT, and BaseMessage has a “MessageType” member that takes a value from that enum. That’s basically “it” for the message, and yes, it implies you’ll need to up-caste to use it within your AI components or Physics component or whatever.

    As to how that message gets sent, I recommend that you have a central ComponentRegistry system of some kind that tracks all of the components that exist, and to which entities they are attached. This system also tracks, per component, a list of all messages that instance of that component is registered to listen for, and that registration contains a pointer to a specific handler function (which takes a BaseMessage pointer as an argument) that handles that message. So inside your component, you’ll have something that looks a bit like:

    RegisterMessage(GHOST_IMPACT, ::GhostImactHandlerFunc)

    … and then when you send a message to an entity, it goes by way of ComponentRegistry, which finds your entity, collects all components attached to that entity, determines which of those components are registered for that message, and then calls those message handler functions directly with your input message. The other way of doing this is to build a big hierarchy of SendMessage -> HandleMsg on the entity -> (each component) -> HandleMsg and blah blah blah, but that way is slooooooow. I highly recommend direct functional coupling, to avoid all the passing around you otherwise have to do.

    Note that you’re also going to have cases where you want to emit more of a to-whom-it-may-concern message, probably to within a specific sphere of an entity. Like, for instance, emitting an “Explosion” message to all entities within a 20 unit radius of a bomb. For that, your ComponentRegistry will want to have some collection scheme, maybe octree-based, to collect all entities within that space quickly and efficiently.

    Does that help to answer your question?

  4. Posted on December 20, 2010 at 10:35 am by Mark

    Thanks for the response. I’m a bit overwhelmed by the amount of information, but I think I’m getting somewhere.

    A question that arises to me now is what does your BaseMessage class look like exactly? I suppose your giant enum is application-specific, and not hard-coded into the game engine; the game engine should only provide the means to get messages passed around; it shouldn’t know anything about the messages themselves, right? I guess in C/C++ the MessageType member variable of BaseMessage could just be an int, since enum values are represented as integers anyway, but other languages like Java / C# won’t allow you to cast integers into enum values and vice versa afaik.

    About the ComponentRegistry, I can see the advantages it provides, especially for scenarios like the bomb one. What left me wondering, though, is how ‘ComponentRegistry -> find entity -> collect components attached to it -> select those registered to receive the specific message at hand -> call the handler’ is faster than ‘ComponentRegistry -> find entity -> collect components attached to it -> broadcast message’.

    In the worst case you’d just call a method which does nothing else than checking the message type against the types it’s interested in and then discarding it, seeing that that particular message does not match any of those types. You’d save yourself from having to initialise data structures with those message type -> handler function associations, and from having to look up which components are registered to receive a certain message. Is broadcasting really that bad ?

  5. Posted on December 20, 2010 at 10:43 am by Megan

    The direct function approach avoids virtual functions, and is thus necessary if you expect your engine to run on PS3 or 360 (for instance) or generally want a high performing engine. Otherwise, every message handle involves some degree of virtual HandleMsg function call.

    It also avoids the massive switch statement that would probably otherwise live inside HandleMsg, and exchanges it for what is most likely an array or hash table lookup (which would return your list of registered message handler functions).

    To your other question – I, personally, don’t particularly care to keep game-specific code and engine-specific code separate. I don’t believe it’s ever totally practical, and that any illusion you have of your engine being pick-up-and-plug-in ready for future projects (with it just magically shedding your game-specific code) should be avoided.

    I mean keep them separate where you can – specifically, keeping your general-use components barricaded off might make some sense – but there is always, always, going to be some mixing of the two halves, and part of the cost of migrating your engine into your next project will be the time spent deciding which parts make sense in the new project and which parts should be discarded. Build it into your scheduling, rather than pretending it won’t happen… because it will, every time.

  6. Posted on December 20, 2010 at 11:42 am by Mark

    Ok, thaks for the clarifications :)

  7. Posted on December 24, 2010 at 4:19 pm by Mark

    Hi again. I was wondering if you could help me out with an issue I’m having.

    Say our game objects have two components, Render and Collision, amongst others. Then we’d have two subsystems, RenderSystem and CollisionSystem, which would deal with rendering the scene and colliding game objects, respectively. The reason we’d have these two subsystems is that the nature of components kind of suggests that to us; now that we have decoupled components, each dealing with a specific domain, it would be nice to take this decoupled nature further, and have each component play a different part of the game. The RenderSystem would have no clue about the existence of the CollisionSystem and vice versa.

    At a first shot we might give the RenderSystem the responsibility to render both game objects and static geometry. To do this, we feed the RenderSystem with such geometry during initialisation, so that it can build an octree or a BSP based on that data. Later, we just add the Render components we want to be rendered; the RenderSystem places these in the correct place so that it can then render the scene efficiently, and updates the graph’s state as objects move around. So far, so good.

    The CollisionSystem, on the other hand, should collide Collision components not only with other Collision components, but with the world as well. Well, we have a problem now; to collide objects with the world, we need the actual static geometry, and we don’t really want to build yet another octree/BSP holding duplicate data.

    An obvious solution to the duplicate data problem would be having a single system, which would deal with both rendering and collision, but I don’t quite like that because I really want to exploit the power of components and have rendering and collision be two separate subsystems; the rendering one should only know about Render components, really, and the collision one only about Collision components. Two domains, two types of components, two subsystems.

    Because the source of evil is the static geometry vs moving geometry issue, I thought about pulling these apart. In this situation I’d have three subsystems instead of two: some sort of subsystem dealing with both world rendering and the collision between Collision components and the world, a subsystem dealing with rendering game objects, and a third dealing with colliding game objects only. This way, the former would use a static geometry induced space partition, while the last two would be free to build their own, since they no longer deal with world geometry. Though we still have the same problem as above, a subsystem speaking two languages, we are now free to keep the other two apart; we get half from each approach.

    I’m not sure if I’m liking this last idea, and I’d like to have your opinion on all of this. Perhaps you could suggest a totally different approach?

    Thanks in advance, and merry christmas :)

  8. Posted on December 26, 2010 at 11:33 am by Megan

    You’re over-thinking it ;) You just make a separate physics system that, yes, has a separate octree. If you were licensing Havok for instance, do you honestly think it would use the same spatial collection mechanism as your rendering subsystem?

    The kind of approach you suggest ends up with a monolithic, impossible-to-work-with structure. It’s what you get if you optimize too early, and it’s one of the things component-based architecture tries specifically to avoid.

  9. Posted on December 30, 2010 at 4:58 am by Michael

    I can’t help but think these component systems are really just trying to overcome the limitations of the language, which lets face it is always C++ in the games industry. The problem is the inflexibility of C++ both with its statically typed nature coupled with a lack of first class functions, the main issue in my opinion; though some form of meta programming would also go a long way. I think there is many other tools (read languages) that would solve this issue a lot more elegantly.

  10. Posted on December 30, 2010 at 8:48 am by Megan

    Maybe so, but it’s not a terribly useful line of thought if you’re production-oriented. If you’re in the business of writing languages and pushing standards, by all means, it’d be nice to see a standard that had more of this built in… “but” – if you’re in the business of just making games, you just have to work with what’s available that’ll get the job done the fastest. In games, that more or less means C++, maaaaaybe XNA, and maaaaybe C# – and Flash or Unity, depending, and then your various other big engines (UE3 most notably). Of those, Unity and UE3 probably have the best handling of components et al, though Unity has other issues that make it unsuitable for larger productions. Then there’s the just-languages, and none among them is really better suited than the others, so C++ wins by default to existing adoption.

    Granted, it will take a studio willing to make a big success via some alternative language approach to get any kind of adoption of a new scheme – like Doom did with C – but that carries cost and risk that you really don’t need to include in your schedule unless you want to. Personally, I’d rather spend my risk elsewhere, in driving things end users care about (features, depth of gameplay, etc) – and C++ (or UE3) isn’t a limiting factor to that.

  11. Posted on December 30, 2010 at 9:17 am by Michael

    Certainly, if you are tied to C++ technology then that is different, but the original post seemed to be more about generic engine implementation as opposed to using a specific technology.

    Alternatives have been used; Naughty Dog used their own implementation of Lisp (GOAL) very successfully on the PS2.

    I can understand that quite a few who have spent the time (and its a lot of time considering the ‘gotchas’) to become proficient at C++ would be reluctant to consider alternative tools. But there is a quite a few alternatives and they don’t necessarily live solely in the realms of academic fantasy. Lisp is a good example and provides a lot tools necessarily to both provide flexibility and adequate abstract to facilitate complex application development; one of the main reasons it was so popular in the AI field.

    One direction might be to have the underlying ‘bare metal’ systems in C, and then embed a more flexible dynamic language to define and manipulate game objects; I suppose the likes of Lua and unreal script might be in this space, I have limited experience of either. GOAL took the opposite approach, I believe, of allowing the developer to embed assembly language blocks for performance critical portions of the game engine.

    As for risk; it does indeed depend on the situation but from my reading of the blog post that did not appear in scope. I think most people would agree that C++ is very complex language that puts a lot of burden on the programmer and hence finding people who have invested the necessary time to understand its various nuances is not easy.

  12. Posted on December 30, 2010 at 9:43 am by Megan

    All very true, and you’re right, the entry was fairly generic. I responded with my “production programmer” hat on – apologies for that.

    Regardless, yeah, Lua isn’t a bad choice. Arguably, it’s a really neat choice, given how it can treat collections of functionality as little more than tables… though from experience, it’s a real bear to implement it to do that efficiently / without an expert developer doing the Lua (it loses the ease-of-use angle), so I’d personally look elsewhere if you want more than a light scripting language. Doing Lua to that level ends up just as complicated as C++, it just wasn’t built terribly well for it.

    The scripting language in UE3 serves a similar purpose, but was more built with components/entities in mind… but as far as general, more open-source scripting languages that are good choices? Honestly, I don’t know of any. If anyone does, holler.

  13. Posted on January 18, 2011 at 12:29 pm by Raghu

    I find it hard to let go of polymorphic behaviour entirely. Would it not be possible to have the components themselves have their own inheritance lines? a separate inheritance for physics object such that if the render system needs to grab an origin, it know the base physics component always offers this? Likewise an inheritance line for Render components. Or do you think taking the component system further is better where within your physics component you may have sub components for behaviours?

  14. Posted on January 18, 2011 at 12:34 pm by Megan

    Your first line – “I find it hard to let go of polymorphic behaviour entirely.” – would be the problem with that approach. Why are you trying to retain polymorphic entities? What do they do or not do for you? Why is a stack of inheritance ever a good thing? Don’t do things because you’re used to them, do them because they have a positive impact on your overall design.

    Personally, I’m not married to my discussed component scheme. It’s just the one that I chose to write on, because it’s by far the most common. I honestly think that the way forward is more functional programming, in a LISP’y or JavaScript’y way with that stacked over top a thin wrapping of functional hard-coded low level elements. The approach that Unity takes, for instance, or what Unreal Engine 3 does. And that will eventually give way to some other “best” approach I’m sure.

    Try not to get married to any paradigm, period. Just look at the ways you know of doing something, and pick the one that makes the most sense for the problem at hand.

    In your specific example, I can’t imagine what a rendering component and a physics component ever have in common, functionally-speaking, and components are all about separating the functional elements. They DO share data, but so do all other components, which is why data (like position) needs to be stored separate from the components in a central hub per entity or similar that is easy and fast for all attached components to access.

  15. Posted on February 20, 2011 at 6:59 pm by Dezzles

    While I agree that component systems are an efficient way to go, I can understand why somebody may still use inheritance for systems that are similar, for instance two physics components that have the same functions during an update cycle, but have different functions for how to react on collisions (not the best example I know). Is there any real issue with doing this, or is it a bad idea to mix and match OO design and a component entity systems?

  16. Posted on February 20, 2011 at 7:39 pm by Megan

    Nothing wrong with it at all – and that’s a case where it makes perfect sense. You just need to balance that with avoiding stacks of components 10 deep, or you still end up back where you started.

  17. Posted on April 27, 2011 at 11:24 am by Zach

    I had a question. I’m writing a 2D game engine with a similar architecture to this. Basically, instead of using a component system tied into the Entity, there are separate Scene, Physics, and Logic subsystems that handle the rendering, collision, game logic aspects of each entity, respectively.

    I understand the concept of each entity having its own “Renderable” object; say, a mesh, sprite, particle system, or anything else. However, I’m having a hard time grasping when something should be its own entity. For instance, lets say my game needs a space ship that takes damage. Based on the level of damage, there will be sparks flying from the ship, scrape decals, fire, etc. The way I see it, I could use a couple approaches:

    1) Define a separate scene node for the ship that can have child nodes for each decal, particle system, etc. The problem now is that I have an entity with multiple scene nodes. I have to handle ownership of those nodes without breaching the “keep render data outside the entity” model. My engine currently assigns the entity ID to a single scene node. The scene subsystem has a virtual HandleEvent(…) function that can receive messages about an entity and can query for its scene node based on that ID. Having more than one scene node per entity without those nodes being children presents a problem.

    Also, since I’m using a scene graph, if I did treat a particle system as a child node, the transformation would be bound to its parent. This wouldn’t look right since the particles would rotate with the ship. I guess I could allow child nodes to only inherit position.

    2) Have one scene node that handles the particle systems, decals, and ship rendering based on the entity state. I hate the sound of that because of the whole C++ reusability training I’ve had.

    What has been your experience with this?
    Thanks,
    Zach.

  18. Posted on April 27, 2011 at 12:02 pm by Megan

    For everything that is placed in an editor, I would suggest an entity for each decal, each spark effect, etc. There should be a bunch of distinct entities, though a bunch would of course be using the same decal or spark effect or whatever asset. If your entities need a concept of parent/child, that should be based in THE ENTITY, not the scene graph – the structure of the scene graph should arise naturally as a result of your entity relationships.

    Now that said, if these sparks arise from gameplay conditions, I wouldn’t generally have each spark be its own entity. I would have an “effect manager” and a “decal manager” and such into which I register decals and effects attached to a given entity at a given offset relative to the entity’s position and orientation. You COULD make them each their own entity, but that’s going to get expensive fast.

    The other trick to keep in mind here is the concept of entities that freeze / basically turn off as soon as the game starts. They can change their position, be rotated, interact, etc when being edited, but once the game starts? They stop their internal processing, and just become “part of the scene” until destruction of the entity which properly removes all their associated meshes and such. If you have every shrub, every rock, every sparkle as its own entity, the cost of even the all but empty Run() methods of all those components will start to add up – so you’ll eventually want to build them such that they can set themselves up, then disable the Run(), since they’re effectively static from that point on anyways.

  19. Posted on April 27, 2011 at 12:21 pm by Zach

    Thanks a lot. I have been grappling with the concept of a Scene Graph (i.e. on one side wanting to say they are evil and ditch them, but on the other liking the concept of heirarchy). I think my problem is in considering the scene graph a render data structure, a thus keeping it on the SceneNode side of things rather than the game entity side. I feel like a better approach might be to ditch the scene graph altogether on the rendering side and go with a flat rendering hierarchy (well, like you said, the hierarchy should arise naturally).

    What is the best way in your opinion of handling those entity relationships? Is it through a scene graph (i.e. inheriting position, orientation, scale from a parent) data structure? Or something more simplistic?

    As far as your last paragraph, my engine is event based, so objects don’t have a Run function that gets called every frame. Rather, events occur like that trigger callbacks for those objects. It seems like that would solve the problem you described.

    One last thing. Going back to the entity hierarchy thing. If I did consider every single object in the game an entity, I would need some way of grouping them. Using the example I described earlier, if I wanted to update the ships damage, I would need to get a hold of those decal/fire/turret entities quickly and easily. Maybe the ship could just simply store those ids in an array specific to that entity. Or somehow define a group of entities where you can query for all their ids. Unfortunately, none of these sound particularly intuitive to me.

    I’m hoping to find a solution that works for more general cases. How would you handle hierarchies and grouping?

    I appreciate your insight. I know I could think up many ways to solve this, but I’m particularly interested in your opinion because you have experience with professional game development. I want get it right.

    Thanks,
    Zach.

  20. Posted on April 27, 2011 at 1:14 pm by Megan

    If I were doing the ship thing, I would personally really just have the ship entity as “the entity” and not have individual entities for the FX it spawned. Those would instead be under a manager. I only break things out as individual entities if I need to position them individually by hand (like in an editor, so trees and such – though they often cease to need to be entities in-game), or if there is some reason to make that piece of the game individually intelligent (like the ship being able to be hit). Everything else (the FX), I will tend to classify as purely visual stuff, and group it under a Manager of some kind – in this case, an FX manager – that is intelligent enough to update the FX positions to match whatever entities they happen to be attached to. Or the reverse, and make the entity’s render component smart enough to move any attached FX, but you get the idea.

    As for scene graphs, I really don’t believe in them. I believe in individual node hierarchies within a given asset – for instance, a mesh made up of multiple parts where each part needs to use a different shader, so each gets its own node – but as far as between-entity parent child relationships, etc, that should really be handled at the entity level. Scene graphs tend to be too rigid for that in my tastes. So here, I would make the FX manager smart enough to handle the relative positioning of sparks onto the ship, or similarly build the coupling in a way other than a fixed scene graph. It makes it much easier to manage if, for instance, you want a piece of fire to eventually detach and spin off on a ballistic trajectory – if everything lives in a scene graph, that kind of thing becomes a nightmare.

  21. Posted on April 27, 2011 at 1:31 pm by Zach

    I hadn’t thought of using a separate Effects Manager. I agree that objects accessible in an editor should be entities, but things like decals and sparks are almost too small and numerous for that to be wise. I think that a separate manager with links to the entity makes the most sense. Thanks! :)

    I’ve been getting those exact vibes from my scene graph. It feels way too rigid and I have no support for detaching scene nodes into a separate entity. I think I’ll just say no.

    Thanks for your help, Megan. I think I have some direction now.

    Cheers,
    Zach.

  22. Posted on November 7, 2011 at 8:32 pm by Chris

    I have several questions varying to different parts of game design.

    First, what are some typical ways that games handle input in a component-based paradigm? As an example, we spawn two entities in our game world. One of the entities is controlled by the keyboard operator so they can use ‘WSAD’ for example to navigate around the area. The other has a hard coded AI component that we want to instruct the entity to move to several positions, waiting in between each move. The AI seems simple in that a simple AI component and subsystem would work in tandem. The subsystem invokes the update(delta) each fixed time step to progress the finite state machine logic dictated by the AI component. For the player controlled entity, how would we get key ‘W’ to make the character move? Same can be said for the AI logic component, how does it dictate ‘MOVE TO HERE’ to the locomotion system? How would physics be involved to enforce gravity or inability to move through a solid wall that obstructs the destination?

    Second has to deal with self-containing the rendering subsystem. I have typically thought about creating this deep scene graph hierarchy which has lead me to the stage where components (such as transformation) held a reference to their scene graph but this seems really bad. So it seems typical that a single entity usually confines itself to one scene graph node in the render engine? If it requires more than one, how is this achieved?? (for example a camera that follows a player entity or wheels rotating on a vehicle).

    Thanks for your time.
    Chris

  23. Posted on November 11, 2011 at 10:24 am by Megan Fox

    For the input, I’d typically have a PlayerInput component that I attach to the thing I think of as the player, which feeds input events it sniffs from the input manager into the entity’s messaging system. I’d then have a general movement component that takes those inputs and works with them. This would let you swap to any entity in the game and control it transparently, and is the way I suspect they did it in Gothic 2 for instance. You can also merge the input system and movement system down to a PlayerMovement component vs an AIMovement component. Easier than trying to make AI talk to its movement via keypresses, less flexible, which you pick depends on your needs.

    For the rendering system, that’s… tricky. You can have the wheels as independent entities that are parented to the vehicle body, but that is painful beyond belief. I’d usually recommend making a custom vehicle rendering component that can contain more than one render node, and have the vehicle body and all attached wheels internal to it. Ditto for similarly complicated situations, skinned vs unskinned actors, etc – just make a specific rendering component for that setup.

  24. Posted on November 13, 2011 at 9:20 am by Chris

    How do you cope with the ever growing number of components versus subsystems that manage them? If we take your example of the specialized render component for the vehicle, do you just create a new vehicular system that manages those components? If a new system is created, do you simply take that new system and add it at the appropriate position in the game loop?
    It feels as though I am having a hard time grasping how the methodology as a whole comes together in a game to work effectively. You load a scene file that outlines your world’s geometry, NPCs, and other static assets. Then you need to determine of those entities, which are within ‘potential viewing distance’ of the player and add those to the entity system. As entities leave ‘viewing distance’, they’re removed and others added. To me, there is some system above your entity system that is controlling what to load and unload, yes? When when it comes to loading these things, is it as simple as having an entity definition in XML or some binary structure loaded from a file and passing that to the entity manager to construct the appropriate components? And when these components have dependencies, do you simply have your render component post a message to the entity and request it’s position and wait for it to be broadcast by the transform?

  25. Posted on November 13, 2011 at 11:50 am by Megan Fox

    To the first bit – yep, pretty much.

    To the second – that has nothing to do with component systems. In a zoned world, you just load everything up in the zone, and bam, done. The problem you’re describing is the general problem of streamed worlds, and… yeah, it’s tricky. That’s an entirely differently discussion ;)

  26. Posted on February 7, 2012 at 6:43 pm by The Floating Brain

    My engine is component based but in your first argument against old – style game engines when you put down a shared function and said you would have to copy/paste all over the place you could have done:
    class Entity : public Engine
    {
    protected:
    //…
    public:
    //…
    virtual void Physics()
    {
    //Default physics.//
    }
    virtual void Other(){}//Could be used for AI.
    };
    struct DefaultAI
    {
    void AIDefault()
    {
    //Default AI behavior.//
    }
    };
    class FirstAI: public Entity, public DefaultAI
    {
    //…
    public:
    //…
    void Other()
    {
    //The AI most of the AI’s would have.
    Default();
    }
    };
    class SecondAI: public Entity
    {
    //…
    public:
    //…
    void Other()
    {
    //New AI behavior.//
    }
    void Physics()
    {
    //New physics.//
    }
    };
    //Could be in the singleton.//
    static void Shared( Entity *ent )
    {
    ent->Physics();
    ent->Other();
    }
    class Single
    {
    std::vector objects;
    void Instantiate( std::string what )
    {
    //…
    }
    void Update()
    {
    //Somewhere in the engines cycle.//
    Shared( objects[i] );
    }
    };

  27. Posted on February 7, 2012 at 6:47 pm by The Floating Brain

    My engine is component based but in your first argument against old – style game engines when you put down a shared function and said you would have to copy/paste all over the place you could have done: http://pastebin.com/Vuzsu1Ug

  28. Posted on February 7, 2012 at 8:08 pm by Megan Fox

    The Floating Brain: Yep, very true, that’s certainly a way of avoiding the problem. Though it does tend to create a fractured code base that can quickly spin out of control. You have to remember that SubAI1() is used in items 5, 23, and 8, whereas SubAI2() is used in (etc), so if I want to tweak 23′s AI I should… etc.

LEAVE A COMMENT