Sign in to follow this  

Entity System ( Component System )

This topic is 2648 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ok im having trouble understanding how this works, in one article i read it stated that you were to stay away from all oop and use arrays and ids to find entities and components. others say that i should have a base abstract component class and an entity class and take an oop approach. im just confused on how this all works, i would love to learn more about component systems and different practices in using them, right now i do use oop when i program.

i would like to know how entities have access / store components and how you use the components on the entitiy. i would also like to see how you guys have done this ... i know i sound like a noob but i would appreciate any help given. Thanks in advance :)

Share this post


Link to post
Share on other sites
Hey!
I suggest you to start with this very useful thread that helped me a much, with my component system (that is still in development).
Also check out this thread that was posted by me.
And check out the T=Machine blog posts.

I hope it will give you some initial information to start with, and if you will have any more question, feel free to ask them!

One last suggestion, try not to think OOP, its hard, and most of the suggestions will look dumb to you (like comparing ES to RDBMS) but believe me the moment you will stop to think OOP, the system will look so simple and so modular to you!

Good luck! =)

Share this post


Link to post
Share on other sites
Quote:
Original post by skwee
Hey!
I suggest you to start with this very useful thread that helped me a much, with my component system (that is still in development).
Also check out this thread that was posted by me.
And check out the T=Machine blog posts.

I hope it will give you some initial information to start with, and if you will have any more question, feel free to ask them!

One last suggestion, try not to think OOP, its hard, and most of the suggestions will look dumb to you (like comparing ES to RDBMS) but believe me the moment you will stop to think OOP, the system will look so simple and so modular to you!

Good luck! =)


Thank your for your responce, the links, and the tip about oop because it is super hard to think in another way but ill try :)

Share this post


Link to post
Share on other sites
Hi,

Quote:

...because it is super hard to think in another way but ill try :)


http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html

Here's my slightly modified version; I found it funny, but then again, I have a strange sense of humour. Perhaps it won't make you giggle, but it'll make you see a subtle, important lesson:

Quote:

The venerable master Qc Na was walking with his student, Anton. Hoping to
prompt the master into a discussion, Anton said "Master, I have heard that
oop is a very good thing - is this true?" Qc Na looked pityingly at
his student and replied, "Foolish pupil - oop is merely a poor man's
component-based system."

Chastised, Anton took his leave from his master and returned to his cell,
intent on studying entity systems. He carefully read the entire "Gamedev.net" series of threads and its cousins, and implemented a small
component-based system with no oop. He learned much, and
looked forward to informing his master of his progress.

On his next walk with Qc Na, Anton attempted to impress his master by
saying "Master, I have diligently studied the matter, and now understand
that oop is truly a poor man's component-based system." Qc Na responded by hitting
Anton with his stick, saying "When will you learn? Component-based systems are poor man's
oop." At that moment, Anton became enlightened.

:)



Once you have to deal with (de)serialization, efficient message passing, object pooling to go easy with allocations etc, you'll realize that even T4 (boring code generation!) is an awesome tool.

Bottom line is: research component systems, but don't let them blind you with their shininess!



ooo shiny

Share this post


Link to post
Share on other sites
Quote:
Original post by skwee
Hey!
I suggest you to start with this very useful thread that helped me a much, with my component system (that is still in development).
Also check out this thread that was posted by me.
And check out the T=Machine blog posts.

I hope it will give you some initial information to start with, and if you will have any more question, feel free to ask them!

One last suggestion, try not to think OOP, its hard, and most of the suggestions will look dumb to you (like comparing ES to RDBMS) but believe me the moment you will stop to think OOP, the system will look so simple and so modular to you!

Good luck! =)


ok just a quick question how do you store components with out OOP i have been trying to read about it but most people use a base abstract component class but i read that T=Machine post and it said not to use he some how stored all the data in arrays and accessed them with an id that the entity held.. could you explain how you are implementing this

Share this post


Link to post
Share on other sites
Quote:
Original post by Rainweaver
Hi,

Quote:

...because it is super hard to think in another way but ill try :)


http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html

Here's my slightly modified version; I found it funny, but then again, I have a strange sense of humour. Perhaps it won't make you giggle, but it'll make you see a subtle, important lesson:

Quote:

The venerable master Qc Na was walking with his student, Anton. Hoping to
prompt the master into a discussion, Anton said "Master, I have heard that
oop is a very good thing - is this true?" Qc Na looked pityingly at
his student and replied, "Foolish pupil - oop is merely a poor man's
component-based system."

Chastised, Anton took his leave from his master and returned to his cell,
intent on studying entity systems. He carefully read the entire "Gamedev.net" series of threads and its cousins, and implemented a small
component-based system with no oop. He learned much, and
looked forward to informing his master of his progress.

On his next walk with Qc Na, Anton attempted to impress his master by
saying "Master, I have diligently studied the matter, and now understand
that oop is truly a poor man's component-based system." Qc Na responded by hitting
Anton with his stick, saying "When will you learn? Component-based systems are poor man's
oop." At that moment, Anton became enlightened.

:)



Once you have to deal with (de)serialization, efficient message passing, object pooling to go easy with allocations etc, you'll realize that even T4 (boring code generation!) is an awesome tool.

Bottom line is: research component systems, but don't let them blind you with their shininess!



ooo shiny


thanks for that... i guess the grass is always greener on the other side :P and they are shiny lol

Share this post


Link to post
Share on other sites
This is a somewhat broad and popular topic. There is not the "One Way" to make a component system work. But generally they are quite "OOP" because composition and single responsibility principle are among the basics of OOP design. You have a whole bunch of choices ahead of you:

In some systems components are owned by entity objects and updated on a per-entity basis, in other systems the entity is simply an ID and components are updated by component "managers" which hold an array of all instances of a given component type.

In some systems components own their own data, in other systems entities own all data, and in yet other systems it's a mix of both. The data itself can be a static blackboard (bunch of member variables optionally packed into their own structure) or a dynamic blackboard (stores any number of different variables with a key association).

In some systems components store pointers to other components they collaborate with, in other systems components communicate over a message bus without knowing anything about what other components exist.

In some systems components have an elaborate interface, in other systems they only export an "onUpdate" and an "onMessage" method.

I think a good way to think about components is as "users" of other systems. For instance, a rendering component typically does not render anything, it simply passes along some data to be rendered later by the rendering system. A collision component does not check for collisions, it simply updates the collision info used by the physics system.

Share this post


Link to post
Share on other sites
Quote:
Original post by lightbringer

I think a good way to think about components is as "users" of other systems. For instance, a rendering component typically does not render anything, it simply passes along some data to be rendered later by the rendering system. A collision component does not check for collisions, it simply updates the collision info used by the physics system.



wow that may have been the most usefull thing i have heard yet.. thanks and thanks to all others who helped and will help in the future :)

Share this post


Link to post
Share on other sites
Some people say Entity systems are so much better than OOP, but for the life of me I can't see the difference between them and the OOP Compositor Design pattern. Maybe I'm just missing something...

Share this post


Link to post
Share on other sites
Quote:
Original post by Echkard
Some people say Entity systems are so much better than OOP, but for the life of me I can't see the difference between them and the OOP Compositor Design pattern. Maybe I'm just missing something...


My understanding is that it basically IS OOP, and that what everyone's comparing it to is not OOP per se, but traditional inheritance-based OO design.

Share this post


Link to post
Share on other sites
Quote:
Original post by Oberon_Command
Quote:
Original post by Echkard
Some people say Entity systems are so much better than OOP, but for the life of me I can't see the difference between them and the OOP Compositor Design pattern. Maybe I'm just missing something...


My understanding is that it basically IS OOP, and that what everyone's comparing it to is not OOP per se, but traditional inheritance-based OO design.


Entity systems are very OOP. Composition is preferred to inheritance in most cases.

OOP is *all about* encapsulation, which composition represents more readily than inheritance.

The difference between inheritance and composition is the same as the difference between an is-a relationship and a has-a relationship.


Contrived example:
We have a class Arm. We want the class Human to have the functionality of Arm (Since the average human has the use of arms).

If we inherit from arm that is an is-a relationship, so we're saying Human is-a Arm.

Instead we want to compose Arm, so we're saying Human has-a Arm (as many times as we compose it for as many Arms as the Human has, this also adds the benefit of each arm being independent from one another).

More concrete example:
We have a class Entity which we want to encapsulate Controller (Whether it be AI_Controller or Player_Controller).

As above, the Entity does not have a logical is-a relationship with Controller, so we compose controller rather than inheriting from it to form the has-a (composition) relationship.


Hope that clears up the "entity system"'s link to OOP.



Note: This does not mean that inheritance is always bad. For instance the Controller object mentioned above would logically be a pure-virtual interface class which AI_Controller and Player_Controller would inherit from since they ARE controllers.

Share this post


Link to post
Share on other sites
Is it possible to reconcile entity/component systems with scenegraphs (i.e., use both in the same project)? For example, scripted entities but animation and rendering subsystems that use (possibly non-isomorphic) scenegraphs? Has anyone here done/planned something of this sort, and how did you map entities/components to scengraph nodes?

Share this post


Link to post
Share on other sites
Quote:
Original post by Dox
Instead we want to compose Arm, so we're saying Human has-a Arm (as many times as we compose it for as many Arms as the Human has, this also adds the benefit of each arm being independent from one another).

Composition is just one way of implementing it. Consider SQL database with Arms table that contains key to entity to which it belongs. This could be 1:many relation.


Quote:
As above, the Entity does not have a logical is-a relationship with Controller, so we compose controller rather than inheriting from it to form the has-a (composition) relationship.

Alternate way: controller doesn't know about entity at all, but controls the position and orientation.

SQL example, have command table (FK controller_id, command). Have Controllers table (controller_id, position_id, orientation_id). Commands are filled in from input, AI, or somewhere by inserting which command to send to which controller.

On each update, SELECT all Controllers, join on position, orientation and command, and end up with the following table: (position, orientation, command). Now just run over every rows in this table updating position and orientation depending on command.

The added bonus here is that with proper normalization, all these tables can be processed in parallel. This area of relational algebra is quite well understood - SQL servers do this kind of optimizations for each query, some even use GPU. It's hard to do generically, but for specialized use, one can roll a NIH version.


PS: Arm could be attached to position,orientation as well. It doesn't really care about entity, only how to transform itself, if even that is needed. And arm could also be related to position/orientation as well.

After all - that is what rendering systems do, just chain transforms. The logical relation between arm and entity can obviously still be expressed.

Quote:
For example, scripted entities but animation and rendering subsystems that use (possibly non-isomorphic) scenegraphs? Has anyone here done/planned something of this sort, and how did you map entities/components to scengraph nodes?

Scenegraphs don't work all that well. Turns out they aren't needed. The topological relation of parent/child is needed mostly for matrix transforms. With SQL approach above, one would iterate over the graph and apply the transforms, appending the result into single list/table - then perform the rest on that result. It's one way of doing the rendering.

For most other things, graph isn't really needed. Even if it is, it can always be flattened as with transformations.

Share this post


Link to post
Share on other sites
Antheus, you're right Arm doesn't care about Entity. That is why Arm is composed into Entity and not the other way round.

The container object knows about what is contained and not the other way around.

As you said, Arm may only only really care about its position (etc). However, Arm doesn't pull the position from the Entity, the Entity would pass information down to the Arm. That is Arm doesn't care where the information comes from, just what the information is (x,y,z coordinates for instance).

The SQL is definitely a valid implementation of this, and I was happy to see it as I am not overly familiar with SQL.

Share this post


Link to post
Share on other sites
ok so i now know that im going to make a base component class and inherit from it to make new components but the entity, is it a label/index in which to reference the components or is it an object that holds the components... from what i have heard the second case is not preferred. I was just wondering how to implement this, should there be an entity manager that keeps track of which entities own what components or should the entity its self contain the components and how should they be sent to the systems to be executed.

one other thing i was wondering is how do you keep track ( if the entity dose not contain the components ) stuff like when the entity dies and you want to stop updating it and when the entity owns other entities such as an enemy entity owning a weapon or somthing.

Share this post


Link to post
Share on other sites
OK, I need to step in and clear up one thing: the term OOP is being horribly misused and misunderstood. OOP is a method of programming, not of design. Using a component system is smart, but it is often implemented using OOP, not instead of it. Using a strictly vertical hierarchy is not what OOP entails. The T=Machine blog posts are particularly offensive in describing OOP incorrectly.

Share this post


Link to post
Share on other sites
could you explain how you would implement it :), i mean how T=Machine explained OOP wrong and how to implement a component based system correctly. would you have the entity contain the components or would it just index it... i still am trying to figure this out. Thank you for your responce.

Share this post


Link to post
Share on other sites
OOP at its simplest just means grouping data with the code that controls it. Again at its simplest, inheritance is just an efficient way to reuse code. A vertical class structure is one way to implement inheritance. Though most people think of things like decoration, composition, etc, as alternatives to inheritance, they're really just another way to implement inheritance in a more flexible manner -- dynamically at runtime, rather than through formally defined classes.

Share this post


Link to post
Share on other sites
sweet, i was reading a post where they had properties for the component and you could add the property through a templated function and get it that way as well but i was wondering how you would update the systems with the properties being undefined to them.


component.addProperty("vector", Vec(1.f, 1.f));
component.getProperty<Vec>("vector").x = 5;


i can see how this would work if you had the properties in the component class already but when dynamically adding then how would your system know how to update them. here is an example ... the only way i can think of is to have the property for that class like only add images to the rendering component..

the way i would implement it would be to make a class inherit from the component class and have the properties defined already. i would love to make it dynamic but idk how it would work

Share this post


Link to post
Share on other sites
Just be advised that any system where you're dynamically adding all an object's properties is going to be s--l--o--w. Most of the reason C++ has been so massively successful is that its implementation of inheritance (whether statically bound or through a v-table) comes at very little performance cost.

Share this post


Link to post
Share on other sites
ok, i just figured out how this is going to work, im going to inherit from the component class and call the addProperty in the constructor... if there is a better way i would love to know.. i was just thinking because if you inherit from the component... unless you feel like it ( which i think i may ) you would have to create lists of each type of component you had or you wouldent have access to the information... well then i wouldent need a base class :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Echkard
Just be advised that any system where you're dynamically adding all an object's properties is going to be s--l--o--w.
Not necessarily? If implemented as above, using a std::vector and per-value instances, then it will incur access penalty. But there are other ways to implement it. That is why I mentioned SQL above - that design side steps queries altogether and works just on large batches of values, no polymorphism needed.

Quote:
Most of the reason C++ has been so massively successful is that its implementation of inheritance (whether statically bound or through a v-table) comes at very little performance cost.

v-table is far from optimal, in many cases it's a very inferior method. What used to be known as type-feedback compilation in '94 is now more commonly referred to as polymorphic inline caching. In combination with JIT, code at call site can then be dynamically rewritten based on statistics of values used. v-table exists primarily because of certain memory and class layout requirements laid down by the C++ standard. In practice, v-table fails to meet the real world use, where actual polymorphic calls are used rarely while most of virtual calls always resolve to same function. This observation holds for dynamically typed languages as well, and is the basis for many of recent optimizations in various VMs and compilers.

Share this post


Link to post
Share on other sites
Quote:
...There are other ways to implement it. That is why I mentioned SQL above - that design side steps queries altogether and works just on large batches of values, no polymorphism needed.
Store the data in SQL Server all you want; at some point you have to read it into memory in some sort of data structure, else you need to query the DB for every single bit of logic, which will be a performance penalty at least several orders of magnitude slower than even the worst possible in-memory solution.

Quote:
v-table is far from optimal, in many cases it's a very inferior method....v-table exists primarily because of certain memory and class layout requirements laid down by the C++ standard. In practice, v-table fails to meet the real world use.
V tables are not used just by C++, but also by C#, VB, Object Pascal/Delphi, and (most) Java implementations. There's a few hundred billion dollars worth of commercial software written with this approach, so saying it doesn't work in the real world is a bit illogical.

In any case, you miss the point. Whether you're talking about V-tables, static bindings, method invocation tables, or decorator wrapping -- these are all means to implement code inheritance/reuse with little performance penalty. I can think of a dozen other alternatives that, from a sheer elegance and flexibility perspective, are better than what real world languages use. The problem is they're all simply far too slow. It's also interesting that most languages that implement these alternatives generally wind up with alternative "compiled" versions that either convert the code into C++, or implement a vtable or something similar to improve performance.

To return to the OP's point, if you throw a property value and its name into a string hash table to dynamically build your objects, then you've essentially just reinvented the dynamic dispatch method that languages like Eiffel and Python use.

Share this post


Link to post
Share on other sites
Hi Antheus, thanks for the explanation.
Quote:
Original post by Antheus
Scenegraphs don't work all that well. Turns out they aren't needed. The topological relation of parent/child is needed mostly for matrix transforms.

Yes, but I see this as a side effect of the hierarchical nature of animation of aggregate graphics objects. In a typical game situation I would imagine that applying a scenegraph design would result in a hierarchy that is fairly flattened with few levels and mostly leaf nodes and so it certainly woudln't work well; but I'm interested in cases where at least in terms of conceptualization scenegraphs make sense. Then how to best map this to an entity/component approach that doesn't have any scenegraph? If an object is structurally parented to another one, how can links be avoided? One could use a (concurrent) heap organized by dependencies, so there's no explicit scenegraph tree, but in practice that would still be an implicit scenegraph.
Quote:
With SQL approach above, one would iterate over the graph and apply the transforms, appending the result into single list/table - then perform the rest on that result. It's one way of doing the rendering.

Could you elaborate on some other ways?
Quote:
For most other things, graph isn't really needed. Even if it is, it can always be flattened as with transformations.

I was under the impression that only static transformations really benefit from flattening...

Share this post


Link to post
Share on other sites
Quote:
Original post by TheBuzzSaw
OOP is a method of programming, not of design.

This is overly pedantic about terminology, not unlike the grammar Nazi approach.
The abbreviation OOP is often used interchangeably with OOD, and everyone knows the difference and that each can be used without the other. Just as with 'then' vs 'than', no one will get confused about the semantics even if they read OOP instead of OOD.

Share this post


Link to post
Share on other sites

This topic is 2648 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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