\$22

### Image of the Day Submit

IOTD | Top Screenshots

## Entity System question

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

29 replies to this topic

### #1aeroz  Members

Posted 06 April 2008 - 10:51 AM

Hello everybody, I am currently developing my first own "larger" game. It should once become a simple 2D space side-scrolling game. I want it to be extensible and quite reusable for later projects. Till now I have only programmed simple games like Tetris and such things. Now I want to implement a more complex one. I have never before thought much about game design but now I have to because I want to have my code a little bit more organized. I am reading a bit on Component Oriented Programming and Entity Systems (like here or here). I like it very much so far and want to implement my game more or less like this. But there are some things that are not clear to me and it would be nice if you guys could help me a bit! I'm from Switzerland and my first language is not English. I hope you understand me well. ;) So here is how I'm planning to organize my game: All the game objects are single entities that consist of components. The entities can use components to form a certain object in the game. Examples of components are: Position, Render, Physics, Controller, Life. The implementations of the components are not in the component itself, they are in a separate subsystem (e.g. the Render() function of the Render component is in the Rendering Subsystem). In the components I store only specific data needed by the component (e.g. texture name for the Render component). All this sounds quite good, but which class has to know about the existence of which class? My idea was to register a component in its subsystem when it's created and remove it when it's deleted. So no component knows about each other, but each subsystem has a list of pointers to the components that belong to the system. This would look something like this:
/*--------ENTITY---------*/
class Entity
{
public:
Entity( const ObjIdType& rId) {
setID(rId);
}

const ObjIdType& getID() const { return m_OID; }
void setID( const ObjIdType& rId ) { m_OID = rId; }

Component* GetComponent(const CompIdType& rFamilyID ) {
return m_components[rFamilyID];
}
Component* SetComponent(Component *pNewComp);
void ClearComponents();

private:
ObjIdType m_OID; /*unique identifier for this object*/

std::map<const CompIdType, Component*> m_components; /* map of all components */
};

/*--------COMPONENT--------*/
class Component {
public:
Component() : m_pOwner(NULL) { /* register comp in subsystem */ }
virtual ~Component() = 0 {}

virtual const CompIdType& ComponentID() const = 0;
virtual const CompIdType& FamilyID() const = 0;

void SetOwnerObject( Entity* obj ) { m_pOwner = obj; }
Entity* GetOwnerObject() const { return m_pOwner; }
private:
Entity* m_pOwner;
};

/*--------SUBSYSTEM---------*/
class SubSystem {
public:
void RegisterComponent( Component* );
void UnregisterComponent( Component* );
virtual void Update() {}
private:
std::vector<Component*> m_components; /* map of all components in the system */
};

/*-------THIS IS AN EXAMPLE OF A COMPONENT------*/
class CompRenderPolygon : public Component
{
public:
CompRenderPolygon() { RenderSystem::RegisterComponent( this ); }
~CompRenderPolygon() { RenderSystem::UnregisterComponent( this ); }

SetTexture(...);
SetColor(...);
SetTransparency(...);
private:
/* data */
}


What I like in this component system is that I can have nice data-driven programming. What I'm not sure about is how the Entities or Components are interacting with each other (with events?). Here an example: I have 3 entities, a player, a monster and a custom visual effect. When the player kills the monster (ID "monster12") I want the visual effect to be deactivated. How would I do this? The Life component of the monster knows that he's dead, but how would it know it has to pass this information to the visual effect? Does the Life Subsystem send a message to all other components in the world? (like "monster12 has been killed by player") Or does the monster know that when it dies it has to pass the "deactivate" message directly to the visual effect? It would be nice if you could explain me how you would do this event handling. (solving the example) Maybe you could present your own manner to handle this. Comments on my "Entity System" are also very welcome. Thank you for reading this long post. I'm pretty sure I have left something unclear, please just ask when something is like that. :) Thanks in advance, I'm looking forward to your answers! Aeroz [Edited by - aeroz on April 8, 2008 3:53:49 AM]

### #2Shakedown  Members

Posted 06 April 2008 - 01:13 PM

Quote:
 What I'm not sure about is how the Entities or Components are interacting with each other (with events?). Here an example:I have 3 entities, a player, a monster and a custom visual effect. When the player kills the monster (ID "monster12") I want the visual effect to be deactivated. How would I do this? The Life component of the monster knows that he's dead, but how would it know it has to pass this information to the visual effect?

Your SubSystems should be responsible for creating events and receiving events. The individual components do not send the events, but they create them (e.g. Life component sees entity.Life = 0, so it creates an EntityDeadEvent) and then they give them to their parent SubSystem. The SubSystem will receive the events from all of its child components and will then send the events out to the other SubSystems.

When a SubSystem receives an event from another SubSystem (e.g. LifeSubSystem sends event to VisualEffectSubSystem) it could pass the event on to all of its child components who care to receive the event. For example, the VisualEffectSubSystem receives an event from the LifeSubSystem informing it that "entity12" has 0 Life. The VisualEffectSubSystem could either destroy its child component attached to "entity12," without the CustomVisualEffectComponent knowing why, or it could forward the event to the component and the component can then see that its entity has 0 Life and destroy itself. Either way, the CustomVisualEffectComponent attached to "entity12" gets destroyed/removed.

Quote:
 Does the Life Subsystem send a message to all other components in the world?

No. The Life Subsystem sends an event to all other Subsystems. The receiving Subsystem then chooses what to do with the event.

Quote:
 Or does the monster know that when it dies it has to pass the "deactivate" message directly to the visual effect?

Definitely not. This creates unnecessary coupling between each monster and its visual effect component. What if you want more than one visual effect component? The monster would have to tell both of them.

If instead the LifeSubSystem sends an event to the VisualEffectSubSystem informing it that the entity's Life = 0, the visual effects components attached to that entity can just kill themselves, and there is no need to pass information between the entity and its visual effect components. This would allow you to attach any number of visual effect components to an entity without the entity knowing, and when the entity dies the visual effect components destroy themselves.

### #3aeroz  Members

Posted 06 April 2008 - 09:10 PM

Quote:
 The individual components do not send the events, but they create them (e.g. Life component sees entity.Life = 0, so it creates an EntityDeadEvent) and then they give them to their parent SubSystem.
Actually I have no methods in the components (only getter and setters), so the component would not know by itself that it's dead. The LifeSubSystem would check if the child component is dead and then create the event. I don't see how a component can create an event on its own since there is no Update() method in the component.

Quote:
 When a SubSystem receives an event from another SubSystem (e.g. LifeSubSystem sends event to VisualEffectSubSystem) it could pass the event on to all of its child components who care to receive the event.
How does the SubSystem know which child components care about the event?

Since almost every time something is happening, wouldn't it be too much events going around the subsystems? For example: when the player has lost some health points there would be en event EntityLostHealthEvent going to every SubSystem. There would be quite a lot of such events.
What if I would like to know who killed the player? The event needs to be preciser and tell who has killed the entity and maybe also where the entity has been killed.

Aeroz

### #4bzroom  Members

Posted 06 April 2008 - 09:54 PM

I'm personaly a fan of the get-the-job-done entity system. Where there isn't constant RTTI type stuff going on and that the objects type is well known by the object that is accessing it.

I think games should be built with a strict purpose with a strong class heirarchy. The entity object should only be the base, not some manifestor of poo.

In other words, you shouldn't be able to recompose the entity once you have it. You should have been passed it at the proper interface level. And the entity itself only represents the common factors.

Currently in my system this envolves starting, living, and ending. I also, since this is a 3d system, have determined that all entitys posses a 4x4 matrix for it's location. (this greatly fascilitates loading and saving)

My renderer however, is completely independent of entitys (which are parallel to your "components"). It is a unique system of renderables and scenes. There is no common relation to the entity so that pattern is not used at all.

I guess what i'm getting at is don't try to boil it all down into systems and subsystems and this and that. Just build it. And build it efficiently as you go.

"I have 3 entities, a player, a monster and a custom visual effect."

Those are 3 very different things. Don't try to boil them in the same pot.

/me hugs c# re RTTI

### #5aeroz  Members

Posted 06 April 2008 - 10:27 PM

Hi bzroom,
Quote:
 I'm personaly a fan of the get-the-job-done entity system.
What do you exactly mean by "get-the-job-done entity system"? You mean a more Object Oriented way?

What I'm not sure about is whether I should implement all the functions into SubSystems or directly into the components. The last one seems easier to code but then there is a lot of memory duplication since there would be multiple copies of a component. Then I could easily do things like
World.GetEntity("Entity12")->GetComponent("Life")->DoDamage(100);
(of course I would have to check whether the entities and components exist and static_cast them) I have kind of a bad feeling doing this since I'm not sure this is a good way.
You said you don't like RTTI, but how do you know the Object types in your system? You don't have components in your system?

Quote:
 "I have 3 entities, a player, a monster and a custom visual effect."Those are 3 very different things. Don't try to boil them in the same pot.
That's why they are 3 different entities. The player has let's say a Renderable, a Physics, a Life and an InputController component. The monster has the same but instead of an InputController he has an AiController. The visual effect entity has only a Renderable component. What I could have done bether is to put the visual effect component directly into the monster entity. When the monster dies the effect disapear also.

Aeroz

### #6Stani R.  Members

Posted 06 April 2008 - 10:47 PM

The system you describe sounds almost exactly like Sneftel's outboard component-based entity system architecture, so you could possibly get some inspiration from there.

I gave up on component-based entity systems midway when I realized that the complexity just wasn't worth it for the simple system I was evolving, but it sure is nice in theory - especially a system like what's been described for Dungeon Siege, the poster child of component driven architecture. The problem you describe is not unique to component systems however, it seems like a more general entity communication problem. From reading posts on this topic, I understand that one common solution for this is a global message queue. If only subsystems send and receive messages, this then becomes what Shakedown has described already.

If you want to be notified the moment a component has for instance died, you could use the observer pattern. When a component setter is called, if a condition is reached, raise an event on the listener (in this case the subsystem), which would then proceed to enqueue a message for other subsystems. This way you do not need an update function, and this functionality can probably be encapsulated in the base class of all components.

### #7aeroz  Members

Posted 07 April 2008 - 01:13 AM

I have allready read the post you mentioned ("outboard component-based entity system architecture"). The problem is I don't understand exactly how he handles events there. Well, I'm a bit new to this sort of design, so I'm just going to try something out. Although it would be nice if you would show an example of how you solved this problem in your engine/game.
Quote:
 I gave up on component-based entity systems midway when I realized that the complexity just wasn't worth it for the simple system I was evolving
I'm not sure whether I should go for the component system, but it realy sounds good in theory!

Wouldn't it be a good solution to have an EventHandler class that takes care of distributing the events to the correct comopnents?
For example in the LifeSubSystem:
if( component->GetLife() < 0 ){   Event* DeadEvent = CreateDeadEvent();   EventHandler::NewEvent( DeadEvent ); /* send event to EventHandler */   component->GetOwnerObject()->Destroy(); /* because the entity is now dead */}

The EventHandler sends the Event to the components(or other type of objects?) that are waiting for the DeadEvent (they are registered in the EventHandler).

Just still a small question: what are exactly zones? (For example a zone in my level that when the player enters it, a message pops up: "You entered the enemy's base! Try to find the hidden star as fast as possible!") Is a zone an entity with a zone component? Does the zone component then check all other entities that have a position component whether they are in the zone and if yes send an EntityEnteredZoneEvent?

Thank you for the replies!
Aeroz

### #8Stani R.  Members

Posted 07 April 2008 - 02:01 AM

Quote:
 Original post by aerozAlthough it would be nice if you would show an example of how you solved this problem in your engine/game.

You're giving me too much credit, I wouldn't exactly say that I ended up solving anything. Take everything I say with a grain of salt or two :D

If I were to classify my system based on the T=Machine article you linked, it would be number 5 - excessive use of observer pattern. I had an entity class (first red flag right here) which had a list of components and could be queried for a component given a type enum (cheap man's RTTI). Components talked to other components directly by registering listeners, or by querying their parent entity for a specific component type. Subsystems got lists of components to process each turn (for instance, Renderer got a list of Renderables in the current PVS).

So in retrospect, my design was a mess - first time writing a component system. I gave up on it for mostly the same reason that I gave up on excessive scripting - in a one man, single-player project, clarity and ease of development beats flexibility - but I'm not yet sure where I'll go from here yet. This components-owned-by-subsystems seems promising, but also quite a bit more complicated to get a grasp on since entities are broken apart and dispersed in such a manner throughout the engine.

The whole data-driven programming is nice in theory, but ask yourself also what real benefit you get from it if you're the only developer and if there's no level designers to take advantage of this feature.

The Zone issue you mention sounds like something you could work out through collision detection with some custom trigger painted over the area (think Neverwinter Nights triggers). I would think it's an entity with a Collidable and some kind of Scriptable/Triggers component, but that's something that depends on your component granularity. So the collision response could send a message to trigger "onEnter", and onEnter would send a message to the player UI.

### #9aeroz  Members

Posted 07 April 2008 - 02:52 AM

Thx lightbringer, I'll think about it a litte bit.
Quote:
 in a one man, single-player project, clarity and ease of development beats flexibility
agreed
Quote:
 onEnter would send a message to the player UI
What exactly is the player UI? A SubSystem?
Do you have on each frame an update of all SubSystems?
like:
void MainLoop(){   PhysicsSubSystem::Update();   InputSubSystem::Update();   AiSubSystem::Update();   LifeSubSystem::Update();   SoundSubSystem::Update();   ...   RenderSubSystem::Update();}

I'll come back later in a few hours.

Aeroz

### #10Stani R.  Members

Posted 07 April 2008 - 03:39 AM

Just updating subsystems like that may not be what you want to do. Sometimes, things like physics (or maybe logic also) would need to be decoupled from the framerate and called with fixed timesteps. I do implement UI as just another kind of system (in fact, it's another kind of renderer, one that gets called to paint its widget tree to screen in immediate mode OpenGL after the scene renderer is done).

### #11Shakedown  Members

Posted 07 April 2008 - 04:58 AM

In my first post I forgot to mention that although your SubSystems create and receive events, there should still be a universal EventManager. When a SubSystem wants to send an event, it creates the event and gives it to the EventManager. The EventManager can then send the event to all the SubSystems who have registered themselves to receive events of that type. Once the SubSystems receive events from the EventManager they can handle it.

Quote:

Quote:
 The individual components do not send the events, but they create them (e.g. Life component sees entity.Life = 0, so it creates an EntityDeadEvent) and then they give them to their parent SubSystem.

Actually I have no methods in the components (only getter and setters), so the component would not know by itself that it's dead. The LifeSubSystem would check if the child component is dead and then create the event. I don't see how a component can create an event on its own since there is no Update() method in the component.

If the LifeSubSystem checks its child components, that would require it to poll all of its child components every update. Depending on your specific game, that may be a poor way of handling the situation.

Perhaps in a setter method you could create an event if Life = 0. Something like this pseudocode:

class LifeComponent { private:  int Life; public:  void SetLife(int l){   Life = l;   // Check for Life = 0   if(Life == 0){    // Create event    // Note: Here's where you would include this components EntityID# and any other information you want    Event deadEvent(...)    // Give event to parent SubSystem    mySubSystem->sendEvent(deadEvent);  }

Your event system may depend on how you create your components. This may be an ugly way of creating events, or it may work out good for you.

Quote:

Quote:
 When a SubSystem receives an event from another SubSystem (e.g. LifeSubSystem sends event to VisualEffectSubSystem) it could pass the event on to all of its child components who care to receive the event.

How does the SubSystem know which child components care about the event?

The child component will register themselves to receive events of a certain type. Perhaps the type could be of which SubSystem is sending the event. This registering could be done twice; the SubSystem registers with the EventManager, and the components register with the SubSystem. Keep in mind that it's not necessary to register yourself with anything, but you wouldn't receive any events. You could also have your SubSystem register for events while none of its child components are registered with the SubSystem. In this situation, you could have the SubSystem do whatever it wants; it could destroy some components or create some, or instead send a new event, all without the child components knowing of any such event.

Any class that cares about an event must inherit the EventListener interface. Then, registering for events is as easy as:

// VisualEffectSubSystem registering to receive events of type Life (i.e. from the LifeSubSystem)
EventManager->registerListener(this, EventType::Life);

Quote:
 Then a more general question about this approach:Since almost every time something is happening, wouldn't it be too much events going around the subsystems? For example: when the player has lost some health points there would be en event EntityLostHealthEvent going to every SubSystem. There would be quite a lot of such events.

Probably not. The beauty of an event-based system is that all the systems can be very loosely coupled (if not independent). The LifeSubSystem does not know of any other system; all it knows is that when a components Life = 0 it should send an event saying that "EntityID# has 0 Life." Then, anything that is registered to receive those type of events will receive the event and can handle the event appropriately.

In large games there are typically EntityMoved events which fire every time any entity moves. That's a lot of events, but it makes sense. The SoundFXSubSystem would receive this event and play the appropriate sound file (e.g. a Tank moves and the SoundFXSubSystem receives the event and plays the 'TankTracks.wav' file). So, as you can see, there will probably be a ton of events in your game. If you manage memory correctly, you shouldn't have any problem with the number of events being transferred through your game.

### #12Shakedown  Members

Posted 07 April 2008 - 06:41 AM

Quote:
 Just still a small question: what are exactly zones? (For example a zone in my level that when the player enters it, a message pops up: "You entered the enemy's base! Try to find the hidden star as fast as possible!") Is a zone an entity with a zone component? Does the zone component then check all other entities that have a position component whether they are in the zone and if yes send an EntityEnteredZoneEvent?

This would be a Trigger. I'm not sure how Triggers and components work together, but I can tell you that a Trigger has a 3D mesh, usually of a common shape (cube, sphere) that is not rendered to the screen (it could be though) but is taken into account when collisions are calculated and handled. If something collides with the Trigger, the trigger fires an event.

### #13aeroz  Members

Posted 07 April 2008 - 07:07 AM

Very helpful post Shakedown, really! ;)

Which one is better, big but few components or small but many components?
Here in this picture from http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/:

Is Movement not a part of Physics? Here the components really need each other.
Do I have for each single property of an Entity a component? Like Position, Target, Name, Team, ...
Almost every Entity has a Position, do I still need to have all these components?
Then there are a lot of SubSystems. What exactly is the task of the LifeSubSystem for example? Just listening for events and send them to the corresponding child components, isn't it? For the Render component it's clear what's in the SubSystem: the Render() function (OpenGL drawings for instance). But for a component like Position I don't see the point of a subsystem, since there's only data in the component.
Quote:
 This would be a Trigger.
Is a Trigger also an Entity?

Yet another question, Shakedown:
Quote:
 This registering could be done twice; the SubSystem registers with the EventManager, and the components register with the SubSystem.
Why can't I just register the components directly into the EventManager?

A lot of question this time...
I really appreciate our help here!

Aeroz

### #14Stani R.  Members

Posted 07 April 2008 - 08:01 AM

Quote:
 Original post by aerozWhich one is better, big but few components or small but many components?

Depends on your design. Just pick one and try it out? :)

Quote:
 Original post by aerozIs Movement not a part of Physics? Here the components really need each other.Do I have for each single property of an Entity a component? Like Position, Target, Name, Team, ...

The idea here is that you can mix and match. Some things might move about without being influenced by your physics model. There will always be dependencies between components - physics can't work without position and movement, for instance, and render needs position. You could have some kind of "ProfileComponent" for things like name and team however.

Quote:
 Original post by aerozAlmost every Entity has a Position, do I still need to have all these components?

I think there's a strong case for moving position into the entity class, but one of the articles you linked (the MMO one) argues otherwise. You could start out their way and move it later if you need to optimize it, but you can't do that so easily if the entity is just an integer like they suggest (or like in Thief, iirc).

Quote:
 Original post by aerozIs a Trigger also an Entity?

It would be an entity with a collidable/physics, position. The part about it having a script component depends on how and where you are going to fire the events - it could be inside the subsystem also I guess.

### #15aeroz  Members

Posted 07 April 2008 - 08:49 AM

Hi!

Since I really like examples and since I'll be always asking myself such things when developing the game, here is another situation one could want in the game:

When 2 Entities are less than 10 units away from each other, something should happen (like a message or anything). Where in the code do I check whether the two Position components are 10 units away from each other? In the PositionSubSystem? I don't want the PositionSubSystem to check the distances from every Position component in the world so I would again have to make some kind of registering the two components into the distance checking part of the PositionSubSystem. This would then check the distance only of these two every frame.

Maybe you have a more elegant way to solve this?

This would be also possible: a trigger entity receives EntityMoved events from the two Entities (actually from the EventManager) and then calculates the distance and does what it wants when d<10. I think this would need a DistanceComponent or something like this.

### #16Stani R.  Members

Posted 07 April 2008 - 10:25 AM

Presumably you would have some kind of spatial partitioning scheme somewhere in the program. Maybe inside the PositionSubSystem. So instead of having that system store its components in a list, it would store them in something else (octree is an example, though I'm told that for dynamic objects octrees are not so good). In any case, you need to reduce the number of checks to something manageable.

### #17Shakedown  Members

Posted 07 April 2008 - 12:22 PM

Quote:

Quote:
 This registering could be done twice; the SubSystem registers with the EventManager, and the components register with the SubSystem.

Why can't I just register the components directly into the EventManager?

You could, but it would probably be better to have the events go to the SubSystems.

How are you going to create a new LifeComponent? The LifeSubSystem would receive an EntityCreated event and it would create a new LifeComponent attached to this new entity.

If the events have to go through the SubSystem, you can easily control access to the components. You could tell a SubSystem to stop receiving certain events, and thus all child components would stop receiving the events. If the components registered directly with the EventManager, then you would have to iterate through all of the components individually.

Quote:
 This would be also possible: a trigger entity receives EntityMoved events from the two Entities (actually from the EventManager) and then calculates the distance and does what it wants when d<10. I think this would need a DistanceComponent or something like this.

Correct. This is a case for Triggers. You would create a Trigger that will fire whenever EntityID# collides with it. You then set the size of the Trigger appropriately. Most likely this Trigger would be a sphere, so you'd set the radius to 10. Then you attach the Trigger to the entity (actually you'd want to attach the Trigger to the Node that your entity is attached to).

### #18aeroz  Members

Posted 07 April 2008 - 09:53 PM

Quote:
 The LifeSubSystem would receive an EntityCreated event and it would create a new LifeComponent attached to this new entity.
Can't I just create the objects like this anywhere in the game?
obj = ObjTemplateMgr::getInstance()->createObject( "HumanTemplate", ObjIdType("Human"));
Maybe the way you said with events to the SubSystems is better than with this Template Manager. But can you briefly say what exactly an event is? Is there an Event base class and then I derive other events from this class like this:
class Event{   EventType m_eventType; /* e.g EventType::EntityCreated */};class EntityCreated : public Event{   Entity* entityCreated;   std::stack<CompIdType> componentsNeeded;};class EntityDied: public Event{   Entity* deadEntity;   Entity* killerEntity;};

Thank you again. I think I now understand the whole thing quite better!
Aeroz

### #19aeroz  Members

Posted 08 April 2008 - 10:25 AM

Well, I think I have to try it out myseft. Thank you for all the help!
I just realized the Outboard component-based entity system architecture thread has more than one page... :) Let's read a bit more...
At the end of the year we'll see if my game comes out good. ;)
Aeroz

### #20Stani R.  Members

Posted 08 April 2008 - 10:31 AM

Good luck =)

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.