Sign in to follow this  
aeroz

Entity System question

Recommended Posts

aeroz    171
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]

Share this post


Link to post
Share on other sites
Shakedown    230
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.

Share this post


Link to post
Share on other sites
aeroz    171
Shakedown: Very helpfull reply, thank you!

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?


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.
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

Share this post


Link to post
Share on other sites
bzroom    647
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

Share this post


Link to post
Share on other sites
aeroz    171
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);
istead of sending events.
(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

Share this post


Link to post
Share on other sites
lightbringer    1070
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.

Share this post


Link to post
Share on other sites
aeroz    171
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

Share this post


Link to post
Share on other sites
lightbringer    1070
Quote:
Original post by aeroz
Although 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.

Share this post


Link to post
Share on other sites
aeroz    171
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

Share this post


Link to post
Share on other sites
lightbringer    1070
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).

Share this post


Link to post
Share on other sites
Shakedown    230
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.

Share this post


Link to post
Share on other sites
Shakedown    230
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.

Share this post


Link to post
Share on other sites
aeroz    171
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/:
components
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

Share this post


Link to post
Share on other sites
lightbringer    1070
Quote:
Original post by aeroz
Which 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 aeroz
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, ...

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 aeroz
Almost 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 aeroz
Is 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.

Share this post


Link to post
Share on other sites
aeroz    171
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.

Share this post


Link to post
Share on other sites
lightbringer    1070
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.

Share this post


Link to post
Share on other sites
Shakedown    230
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).

Share this post


Link to post
Share on other sites
aeroz    171
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

Share this post


Link to post
Share on other sites
Mike2343    1202
I know its a bit late and this likely won't be read by the OP... But still... Helpful I hope info/ideas/thoughts.

First thing:
Quote:
obj = ObjTemplateMgr::getInstance()->createObject( "HumanTemplate", ObjIdType("Human"));


Please let the singleton die the death it deserves! Read up on the forums of why its bad. Its so rarely a valid pattern you should forget it exists, you will KNOW when its actually valid. Also, a high level event system (not huge on the word manager) would solve this for you. As a side note, I call mine a Messaging System, but that's merely a name.

Example:

//EventSystem is a namespace, SendEvent is a "global" function.
EventSystem::SendEvent("CreateObject", "HumanTemplate", "Human");



In my case my "EventSystem" is actually a class that is templated internally so you can have all kinds of messages inside a single class. So your not as limited as say inheriting from an Event class and being stuck with just a few options (send functions).

Also, not sure which article linked in your first post you liked the most but your Entity class pretty much flies in the face of the T=Machine blog posts. Which is actually the system I like the most as it is also the most generic, but yet can be nicely optimized at the same time.

Then again going overly complex in a single person project is just time your spending not making a game...

Now to answer some of your other questions:

Quote:
Is a Trigger also an Entity?


I actually think no. I think something like TriggerEvent1234 should be an entity that is made up of a Trigger component, Position component and Script component. This allows a lot more complex game events to take place. Like below...

Quote:
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?


One solution I came up with as I was reading the question (not done it but think I will try it soon...) is to have the object your concerned about being close to another use the Trigger component and set its cube to be 10 units in size. I can be flat for just hits on its same level, etc. This trigger then could call its own script component and run a custom script upon being triggered.

Quote:
Do I have for each single property of an Entity a component? Like Position, Target, Name, Team, ...


Yes, kinda the point. Entity should really be completely empty though you can come up with decent arguments for position but mines still separate and not a pain to access. Target and Team can be kept in AI honestly. I have a CommonInfoComponent that holds things like name and other generic info.

Quote:
But for a component like Position I don't see the point of a subsystem, since there's only data in the component.


Its data, but whats wrong with that? You can have things that set/check/get (I hate putting GetX, SetX as methods instead I like readable code like int X() or void Y(int).. etc. Cleaner when you type it out. But this can verify things and allow a lot of other components to get access to it. It can also be packaged into a message (event, though think even message sounds better) and fired off.

Quote:
Is Movement not a part of Physics?


Though commonly tied closely together, one doesn't exactly NEED the other and situations can be thought of when movement might not need physics.

Ok, 4 phone calls cause this 10 minute reply to turn into 2 hours. Kinda lost focus. Anyways this just my take on things. My system runs similar to what I described above. Maybe another bit of insight might help who knows.

Share this post


Link to post
Share on other sites
aeroz    171
I was just checking my old links and noticed your post. Thanks for the reply.
I have already brought quite some structure to my code. I don't really know if it's good because I have never seen a professional way of doing this. Well, I hope that I can learn from my project.

I see that I have a lot of possibilities for the design; I just have to choose one. For me it seems that with a component system you can easily add new things to the game once you have the system. The game I'm developing is for a school project, so I have to stay alone with it. Do you really think a single person project is not worth it? I don't know if it's easy to find other people that are willing to work with you till the end, especially in a voluntary project.

So now, if somebody is still reading this post, it would be nice if one could answer some of my questions regarding what I have achieved till now.
Quote:
Please let the singleton die the death it deserves! Read up on the forums of why its bad.
I don't want to ask basic questions about Singletons, maybe you can give me a link: what can you do instead of them? I have made my EventManager, my RenderSystem, my InputSystem global Singletons, is that a bad thing? I don't know if passing around pointers to the systems would be better.
Quote:
//EventSystem is a namespace, SendEvent is a "global" function.
EventSystem::SendEvent("CreateObject", "HumanTemplate", "Human");
Has this not the same drawbacks as a global Singleton?
------------------------------------------------------------
Now my design:
Comments are welcome!

The game is separated into SubSystems: RenderSubSystem, InputSubSystem, PhysicsSubSystem, Camera, etc...
The SubSystems are updated every frame in the main loop:
void GameApp::UpdateGame( double deltaTimeSecs )
{
InputSubSystem::GetInstance()->Update();
PhysicsSubSystem::GetInstance()->Update( deltaTimeSecs);
RenderSubSystem::GetInstance()->RenderScene();
/* ... */
}


Then there are game objects that are Entities and consist of pure Components. To make a new Entity I use this code:
#include "Entity.h"
#include "components/CompVisualTexture.h"
#include "components/CompPhysics.h"
#include "components/CompPosition.h"
#include "components/CompPlayerController.h"
/* ... */
#include "World.h"

void Init( World* pWorld )
{
Entity* pEntity = new Entity("Entity0");

CompPosition* compPos = new CompPosition;
compPos->Position()->x = -10.0;
compPos->Position()->y = 10.0;
pEntity->SetComponent( compPos );

CompVisualTexture* compPolyTex = new CompVisualTexture;
pEntity->SetComponent( compPolyTex );

CompPhysics* compPhysics = new CompPhysics;
compPhysics->SetInvMass( 0.0 );
pEntity->SetComponent( compPhysics );

/* more components ... */

pWorld->AddEntity( pEntity );
}


In case of Events, you just call the EventManager. Example in the AddEntity() method:
void GameWorld::AddEntity( Entity* pEntity )
{
/* ... */
EventManager::GetInstance()->InvokeEvent( Event( NewEntity, pEntity ) );
/* Event( EventType type, void* data ) */
/* Each event type has a different type of data. Here it is a pointer to an Entity */
}


Or to listen for an Event you do this:
/* RenderSubSystem initialisation */
void RenderSubSystem::Init ( ... )
{
/* ... */
EventManager::GetInstance()->RegisterListener( NewEntity, RegisterVisualComp );
/* In the case of a NewEntity event, the EventManager calls RegisterVisualComp.
(RegisterVisualComp(Event* pEvent) is a callback function that checks whether the
new Entity has a renderable component and saves a pointer to it if yes.) */

}



I think that these are the most important thing to say. How can I implement the EventManager when it isn't good to have it a global Singleton?
Another thing I came across and don't know how to solve elegantly is whether input events are also normal Events that objects can listen to or whether the InputComponents can check the InputSubsystem for key states. (key states vs key events?)

Thank you for your help.
aeroz

[Edited by - aeroz on April 23, 2008 1:31:09 PM]

Share this post


Link to post
Share on other sites
newera    157
A possible solution:


class IListener
{
public:
IListener(EventMng* evnt) : mEventMng(evnt)
{};

void Register()
{ mEventMng->Register( this ); };

void UnRegister()
{ mEventMng->UnRegister( this ); };

virtual void HandleEvent( Event &evnt )=0;

private:
EventMng* mEventMng;
};

// each subsystem inherits from this,
// and register itself to the EventMng.
class ISystem : public IListener
{
public:
ISystem(EventMng* evntMng) : IListener(evntMng)
{};
virtual void Init(..)
{ Register(); }
virtual void Shutdown()
{ UnRegister(); };
virtual void Update(float deltaTime)=0;

};


...
EventMng eventMng;
ISystem* render = new RenderSystem( &eventMng );
render->Init(...);
ISystem* etc...

Share this post


Link to post
Share on other sites
lightbringer    1070
Quote:
Original post by aeroz
what can you do instead of them?

Passing around pointers, mostly.

Quote:

I have made my EventManager, my RenderSystem, my InputSystem global Singletons, is that a bad thing?

The prevalent opinion, and one I also subscribe to, is: yes, it is a bad thing.

Quote:

I don't know if passing around pointers to the systems would be better.

It would. Explicit dependencies are better than implicit ones, and you might avoid more dependencies by thinking of just where you need to pass those pointers. Also, making non-trivial stuff like Renderer a singleton has the potential for really chaotic execution paths since the Renderer.render() method could easily be called from anywhere in your program. Debugging things like that when you do not have certainty about what happens in what order is not a lot of fun.

Quote:

How can I implement the EventManager when it isn't good to have it a global Singleton?

My own, perhaps naive due to lack of experience, approach would be to create the EventManager object in a top-level object such as a Game object, and pass it down to any object that needs to send events. I say naive because I have not worked in a team on a large project, but I believe this is the standard approach taken by everyone who does not use singletons.

Share this post


Link to post
Share on other sites
Shakedown    230
Quote:

Another thing I came across and don't know how to solve elegantly is whether input events are also normal Events that objects can listen to or whether the InputComponents can check the InputSubsystem for key states. (key states vs key events?)


Have you already implemented input as events? I've seen inputs handled by a single class, and the class interprets the input and creates other Events accordingly. In that implementation, there are no input Events. It makes sense, too. This single class, usually called a controller, is provided to a game view. In that way, you can have 2 different controllers: one for the player (PlayerController), and one for the AI (AIController). Only the PlayerController would be a KeyListener and a MouseListener, so it can receive player input and create Events accordingly. The AIController would only create Events based on your artificial intelligence system (however that works).

Doing it this way, rather than creating a InputSubysytem, removes the necessity of input in your game completely. I can't quite remember what you're doing with your game, but you wouldn't need to worry about input if you wanted to simulate a game with only "bots."

Also, this may not apply too much to your game, but if you had an InputSubsystem, how would you handle other players over a network? If every entity in your game was controlled by a controller (PlayerController, AIController), you would give the networked players their own PlayerController, and then those controllers would read input local to the player, but send the events over the network to the server.

Quote:

I don't want to ask basic questions about Singletons, maybe you can give me a link: what can you do instead of them? I have made my EventManager, my RenderSystem, my InputSystem global Singletons, is that a bad thing? I don't know if passing around pointers to the systems would be better.


Quick and Dirty Answer:

Structure your game differently. If you structure your game to include a game-wide (application-wide) layer, then anything that needs to be accessed from anywhere in the game can be put in that layer. One broad way to structure your game may look like this:


Photobucket
Taken from Game Coding Complete, Second Edition by Mike McShaffry


More on this if you're interested.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this