Outboard component-based entity system architecture

Started by
105 comments, last by qingrui 16 years, 4 months ago
Quote:Original post by Emmanuel Deloget
Question: how do you manage
1) data duplication (the bounding box can be of interest to various components; should all components have an embedded bounding box)?

Well, if some data is potentially used by multiple subsystems I'd create a corresponding component.

Quote:Original post by Emmanuel Deloget
Question: how do you manage
2) components requirements (because I have this component, I shall also have this other one)?

I'm not sure if I fully understand that question but if multiple components are needed the subsystem would check for those components individually and either reject the entity or create a default component (a bounding box, for example, could be calculated from other spatial data).

Other components could be optional. As an example the visual subsystem could expect the mesh but could also make use of some shader component.


Edit: I'd not use the Observer mechanism to change the order of processing but to build lists of entities that have changed. Then when it's the subsystem's turn within the processing order it will remember what entities/components have changed and only process those.

[Edited by - Lord_Evil on October 30, 2007 2:14:08 PM]
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
Advertisement
I've been thinking of moving to "outboard" component storage and find myself with a pretty much 1:1 ratio of subsystems to component types. I can see myself having many, many component types. How do you manage all these? Also, this seems to make it a lot more difficult to create new components, especially from a script.

On the otherhand I see problems with "inspecting" each entity for various components that require attention each frame. Are there any other solutions? I was thinking of adding a "onTick" global type event that components can hook into which would let them get updated/drawn/whatever each frame without requiring iteration through a list of entities. Any thoughts?
[size=2]
Quote:Original post by wild_pointer
I've been thinking of moving to "outboard" component storage and find myself with a pretty much 1:1 ratio of subsystems to component types. I can see myself having many, many component types. How do you manage all these? Also, this seems to make it a lot more difficult to create new components, especially from a script.


I see this too in a way. I'm currently sketching out an engine design based on what's been said in this thread and other places, and there does seem to become a 1:1 (or near) relation between components and subsystems. Of course you could allow a subsystem to add more components to an Entity (or just associate them with the Entity and store them in the system itself), depending on which behavior it should have.

I guess this depends on how exactly you define your components. On the Engine-level (no game specific components here) I see few occasions where I would need more than one component at a time from each subsystem. It might be a different component depending on type of animation needed from the Animation subsystem and such, but I don't think one would need more than one component from that specific system.

On this level subsystems seem to become very strongly associated with their own components. So if you want to add a new behavior to your Entity, you might need to write a new subsystem to take care of that specific task. (Especially since components here seem more like data containers as I've understood it.) #1

I'm going for a subsystem interface, so I can add new subsystems at any time and know that the engine knows how to pass it an Entity if told to (from script perhaps).

This could also mean some game specific (above engine level to be clear) subsystems are implemented in script, utilizing script implemented components. The subsystem could of course also be dynamically linked if one so wishes.


In "Dungeon Siege" they had a Component Database to manage the components. Each component had a unique id (Siege Component ID) and each Component "template" also had one if I'm not mistaken. When they needed a new component they just asked the DB for it using the template id. Since they had a continous world, they also had to load and unload a whole bunch of components all the time. They solved the problem with maintaining unloded components state using "SCIDBits", 32 bits stored together with the SCID even after the component was unloaded. That way a Chest Component could remember if it had been opened before etc even right at the moment it was loaded back into the world.

EDIT:
#1) Hmm, what if one would stretch the component "pattern" further and include "plug-and-play behavioral components" in say the animation system? If I want a different type of animation behaviour (skeleton instead of frame based), but would like to keep the framework of the animations subsystem, I could make a new behavior component for the subsystem, and a data component for the Entity. I'm not sure if this would be practical at all, it just hit me it might be worth a thought or two... it's probably more work than replacing the whole animations subsystem with one that does all you want to tho.

[Edited by - TwoD on November 1, 2007 10:30:30 AM]
i've been using a data-driven design for a while now which im not happy with heres the gist of it:

class Message{}class Entity{  bool HandleMessage(Message* msg);  array<Entity*> children;  Entity* parent;}


think of the top most level as an entity, then all of its children and thier children are components.

the problem i had with this is that communication is a problem between entitys.

many times i would just assume my parent is the entity i needed communication with.

All communication must be done using HandleMessage. This is also another problem. Its ugly having hundreds of messages, but it does make for some cool scripting opportunities!

i've been thinking about this stuff alot, and my new system im about to prototype after reading other peoples thoughts and scouring the web for what others have done is this:

class Entity{  InsertComponent(component)  RemoveComponent(component)  GetComponent(type)  array<Component*> components}class Component{  InsertObserver(component)  RemoveObserver(component)  NotifySubjectChanged(component)  NofityObservers()  Entity* owner}


the observer pattern looks like it can solve my communication problem, but this means components need to know about other components, which i think is fine so far here's an example i came up with:

class HealthComponent{  void TakeDamage(damage)  {    health -= damage    NotifyObservers()  }  void Regenerate(amount)  {    health += amount    NotifyObservers()  }  float health}class ScoreComponent{  void Init()  {    HealthComponent* hc = owner->GetComponent(HealthComponent::Type)    hc->InsertObserver()  }    void NotifySubjectChanged(subject)  {    switch (subject->GetType())    {    case HealthComponent::Type:      HealthComponent* hc = subject;      if (hc->health <= 0)        deaths++;      break    }  }  int deaths;  int kills;  int score;}


creating entitys is easy to do:
Entity e;e.InsertComponent(new HealthComponent);e.InsertComponent(new ScoreComponent);e.Init();


Components also act as interfaces, so i dont need the ugly messages, i can do this:

HealthComponent* hc = e.GetComponent(HealthComponent::Type);if (hc)  hc->TakeDamage(10.f);


im just wondering how to do state machine type code with this system now, and how im going to do scripting. Might need a special function
HandleScriptCommand as part of a component
If anyone could post some guidelines about how to divide components and how to use this paradigm using a script system I would be really grateful.

And by the way I will make a really newbie question regarding this system.

Think of an entity that has a Component containing its position, orientation, etc... And a Physics component. The Physics component needs to know the position of the entity, how do you retrieve it? I have been read through the thread about sending messages, etc... wouldn´t be enough doing something like $this->Owner->Get Component("PositionOrientationComponent")->GetPosition()?. And isn´t this a lot of trouble to just get the position every time it is needed?.

Sorry for the newbie question...


Thanks in advance,
HexDump.

[Edited by - HexDump on November 20, 2007 10:30:31 AM]
Quote:Original post by HexDump
And by the way I will make a really newbie question regarding this system.

Think of an entity that has a Component containing its position, orientation, etc... And a Physics component. The Physics component needs to know the position of the entity, how do you retrieve it? I have been read through the thread about sending messages, etc... wouldn´t be enough doing something like $this->Owner->Get Component("PositionOrientationComponent")->GetPosition()?. And isn´t this a lot of trouble to just get the position every time it is needed?.


I believe Sneftel mentioned that the entity actually has spatial information, because many subsystems needs it. The outboard components knows the entity and can therefore get the positioning info directly from it. He could have made a SpatialComponent, but that will only make almost all of the subsystems depend on that instead.

dingojohn, this was just an example, what I wanted to know if this is the way components get things from another components.

As I said in my last post if anyone could explain some guidelines about how to divide components and how to use this paradigm using a script system I would be really gratefull.

By the way, what are this subsystems you´re talking about? render system? input system? IA system? etc...?

Thanks in advance,
HexDUmp.
Quote:Original post by notbad
dingojohn, this was just an example, what I wanted to know if this is the way components get things from another components.

If a subsystem knows about another subsystem, then it can find out about the other subsystem's components. That lookup information is necessary anyway (for when entities are removed). So when a component is created which will depend on another component, the creation process can resolve that linkage. From there on out, the component can just ask the other component.

I can't really give you great guidelines on how to divide components, other than to say that this sort of an architecture leads to slightly fewer components than the standard onboard component system tends to. As for scripting, that really depends on where scripting fits into your game architecture.

Quote:By the way, what are this subsystems you´re talking about? render system? input system? IA system? etc...?

The first and third are good matches. For the input system, since only one entity is controlled, the setup can be a lot more simple.
I´m using LUA, if this is of some information.

HexDump.
Quote:Original post by HexDump
I´m using LUA, if this is of some information.

A little bit, but not much. In terms of control flow, information flow, etc., how does scripting fit into your game architecture?

This topic is closed to new replies.

Advertisement