Jump to content
  • Advertisement
Sign in to follow this  
virus-

Entity system pondering (yup, yet another)

This topic is 3779 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

I've read pretty much everything I can find about entity/component system and while I earlier had a bit different implementation in mind Adam's posts about entity systems made me think of a bit different solution. Earlier I was planning to have components do part of the processing so I could allocate X threads to handle those parts, the subsystems would still be running in their own threads. The downside is that eg. the renderable component would have to know if the entity has animation component so it can update the visual representation when the animation state has changed. You can probably draw rest of the system out and it'd fall perfectly to number 5. on Adam's list, excessive use of observer pattern [headshake]. So on to wrap my head around to components being pure data and subsystems doing all the calculations. Seems better all around. Making parts of the subsystems use thread pool isn't probably going to be much harder than doing those calculations in components. Components are completely isolated from each other, no need to know anything else about the entity which is a damn big bonus and since they'll only be used by one system they don't need any kind of locking, well in theory anyways. The part I can't decide is how to eg. get animation information from animation subsystem to rendering subsystem.
  • I could just blindly send message to every other subsystem that the animation has changed with copy of the animation information (read only so no need for locking here either). However this would result in useless strain on the messaging system (input doesn't really need to know about animation) and of course data duplication which turns me off.
  • Instead of duplicating the data only send pointer to the component data, ok no duplication but components would require locking in most cases and still useless messages passed around.
  • Have subsystems register with other subsystem for messages, that way we can send messages to those subsystems that care about them but this requires knowledge of those subsystems so adding a new system might require changes to others.
  • Send the message to every subsystem that has component in the entity. Still more messages than would be needed but better than blindly sending it to everyone. Bigger problem is that some subsystem might be interested in messages that are not directly related to an entity that has that subsystems component eg. an in-game gui might want to know about players input but since player doesn't have gui component the messages need to be relayed some other way.
The last one seems like the best choice so far. Any thoughts or ideas?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by virus-
Have subsystems register with other subsystem for messages, that way we can send messages to those subsystems that care about them but this requires knowledge of those subsystems so adding a new system might require changes to others.


An alternative to this is that you have a messaging module, and the other modules register themselves only with it, telling what kind of messages they want to send and receive. This way a module need knowledge of only one other module, and I think that in a messaging based system a dependency to messaging system is acceptable.

Though now that I think about it, messaging could be arranged so that the messaging system is the one that asks the modules what kind of messages they want to send and receive, this way only the messaging system needs to know anything about other modules. And if the modules have generic enough messaging interface, even the messaging module could be pretty ignorant about whose messages it is delivering.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ubik
Quote:
Original post by virus-
Have subsystems register with other subsystem for messages, that way we can send messages to those subsystems that care about them but this requires knowledge of those subsystems so adding a new system might require changes to others.
An alternative to this is that you have a messaging module, and the other modules register themselves only with it, telling what kind of messages they want to send and receive. This way a module need knowledge of only one other module, and I think that in a messaging based system a dependency to messaging system is acceptable.

Though now that I think about it, messaging could be arranged so that the messaging system is the one that asks the modules what kind of messages they want to send and receive, this way only the messaging system needs to know anything about other modules. And if the modules have generic enough messaging interface, even the messaging module could be pretty ignorant about whose messages it is delivering.
Apparently I had a brainfart somewhere along the way [totally]. The messaging is done via lock free event system that also allows the subsystems to communicate with other systems outside of the entity system eg. file system (too many systems [lol]) and the subsystems register themselves to it. All messaging is done via the event system so yea they actually would register to the event system and not to each other.

Still eg. the rendering system would need to know about the animation system to register for its events/how to handle them or the animation events would need to be defined outside of the animation system which seems like a very bad choice. Then again I can't even imagine how a subsystem would be able to use the data received from other subsystems without knowing anything about the data [rolleyes] (hard to use something you have no idea of).

BTW. The event system doesn't really need to know anything about the receiver except that it can receive events.

Share this post


Link to post
Share on other sites
Quote:
Original post by virus-
I've read pretty much everything I can find about entity/component system and while I earlier had a bit different implementation in mind Adam's posts about entity systems made me think of a bit different solution.


I cringe every time I see someone cite that URL. I find issue with so much of what is in that blog, sadly. Then again, I also cringe whenever anybody calls it an 'entity system' since that description doesn't really say anything, given that 'entity' could mean just about anything. The word 'component' should at least figure in there.

It's interesting to see that some of the early docs on this subject, eg. the Scott Bilas one, don't really talk about communication between the components, yet that's the issue that comes up time and time again here on the forums. I think perhaps life is a lot easier if you integrate a scripting language, and treat a component as just another property of the entity which you can read from and use like any other variable.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
It's interesting to see that some of the early docs on this subject, eg. the Scott Bilas one, don't really talk about communication between the components, yet that's the issue that comes up time and time again here on the forums. I think perhaps life is a lot easier if you integrate a scripting language, and treat a component as just another property of the entity which you can read from and use like any other variable.
Well yea they don't talk much about communication between components/subsystems which causes a lot of confusion and headache. If components are just pure data they could be treated as just another property. Using them directly as properties and accessing whichever one you need indeed sounds great on paper but requires a lot of synchronization. As for scripting I was planning similar system that dungeon siege has where script can define new components and their functionality thou I haven't had time to think about it much yet.

Share this post


Link to post
Share on other sites
What do you mean by synchronisation in this context? Are you talking about the threading aspect? I think this adds a whole new set of problems to an already complex system. Still, if you already have an event system, then I'd assume you can just send data as needed from producer components to any subscribing consumer components. It's all well and good saying that the observer pattern is easy to overuse, but you still need to get these change notifications somehow. If observers save you from polling too often or broadcasting too often, that might be preferable. In parallel systems like this, if you can send lightweight state changes in the notification rather than waiting for a callback to query it, that will help. Consider it an augmented observer if you will.

Share this post


Link to post
Share on other sites
I just let entities query for other entities. Yes, entities know about the existence of other entities. At first I felt that was dirty and that I was just hacking until I got around to worrying about a more robust system, but I honestly dont see a problem anymore. Now entities just verify all their dependancies were in place during a post creation phase and that's the end of it. It works well and keeps the components lightweight. If I run into issues, it'd probably be one of the easier things in life to refactor.

I'm not saying my system is better or that your pursuits aren't worthwhile, I'm probably just missing something obvious that will bite me later, so feel free to educate me. Another problem I have, while I'm at it, is that most message passing systems I've seen just seem to hide the dependencies anyways - you still need to know what messages to listen for.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
What do you mean by synchronisation in this context? Are you talking about the threading aspect? I think this adds a whole new set of problems to an already complex system. Still, if you already have an event system, then I'd assume you can just send data as needed from producer components to any subscribing consumer components. It's all well and good saying that the observer pattern is easy to overuse, but you still need to get these change notifications somehow. If observers save you from polling too often or broadcasting too often, that might be preferable. In parallel systems like this, if you can send lightweight state changes in the notification rather than waiting for a callback to query it, that will help. Consider it an augmented observer if you will.
Yes the system is multi-threaded so that brings its own headaches with it, still worth the trouble imo seeing the trend in CPU development. As mentioned above if the subsystems send change notifications to other systems with copy of the data that has changed it doesn't need any synchronization since that data is read-only, leads to data duplication but I think that's a smaller issue than having to use locking in most of the components. The state of an entity/component can be queried if needed but usually all interested parties will be notified on change.

Quote:
Original post by wild_pointer
I just let entities query for other entities. Yes, entities know about the existence of other entities. At first I felt that was dirty and that I was just hacking until I got around to worrying about a more robust system, but I honestly dont see a problem anymore. Now entities just verify all their dependancies were in place during a post creation phase and that's the end of it. It works well and keeps the components lightweight. If I run into issues, it'd probably be one of the easier things in life to refactor.

I'm not saying my system is better or that your pursuits aren't worthwhile, I'm probably just missing something obvious that will bite me later, so feel free to educate me. Another problem I have, while I'm at it, is that most message passing systems I've seen just seem to hide the dependencies anyways - you still need to know what messages to listen for.
The original idea I had was to have components define their dependencies and check that they exists after creation. The dependencies themselves don't put too much constraints on the system, just need to know about other components in advance, but I'd rather not have that constraint if possible.

The event system isn't really used to hide dependencies but decouple sender and receiver. As I mentioned above the ideal situation where subsystems know nothing about other subsystems and can still use their data is absurd, how can you use data you have no knowledge of? There will be dependencies on data but there shouldn't be dependencies on specific subsystems eg. rendering doesn't really need animation but static objects are boring.

Hmm... keeping to the renderer <-> animation line. Assuming a skeletal animated character entity, it hash renderable component and animation component. The rendering system needs to know about an skeleton structure so it can render the model correctly and the animation system needs to know about an skeleton structure to animate stuff correctly. Might as well use same structure for both so updating the animation and just sending a copy of the skeleton data should be enough. Since both know about it there's no dependency between the subsystems and since the structure isn't specific to a certain subsystem it should be defined somewhere else and doesn't break encapsulation. Wonder why I didn't think of that before.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
Quote:
Original post by virus-
I've read pretty much everything I can find about entity/component system and while I earlier had a bit different implementation in mind Adam's posts about entity systems made me think of a bit different solution.


I cringe every time I see someone cite that URL. I find issue with so much of what is in that blog, sadly.


Have you raised your specific objections on the blog? Lots of other people have. If you keep quiet, no-one can help you.

Quote:

Then again, I also cringe whenever anybody calls it an 'entity system' since that description doesn't really say anything, given that 'entity' could mean just about anything. The word 'component' should at least figure in there.


Terminology is a shared game that none of us get much say in. Entity System is a phrase that's stuck, at least for the differnet programmers I've met within the game development companies I've worked at. I agree that you could invent better names. For instance, my favourite is "Component-based Entity-centric GameObject System", which pretty much fully and clearly defines it in less than one sentence.

Unfortunately, that's too many words, and no-one uses it other than me.

OTOH, when I say "entity system" in the office, so far *everyone knows what I mean*, which is a compromise I'm willing to accept.

Share this post


Link to post
Share on other sites
Couldn't an entity system just as well be a deep hierarchy though? I've had some presentations at a university here in norway, and there I used the term Component-based Entity System to describe how entities are only a container of the components they hold on to.

The Game Programming Gems books have had some alright articles on the topic of component-based entities. Especially one article in GPG 5 helped me quite a bit in defining how my system would work, where the author talks about factories and event systems that is tied into the mix.

I've learned that there's a lot of debating on what exactly a component should be though, and what exactly a system should be. In adam's approach, referred to in the OP, I get the impression that a component is just a container of data, but that each type of component also comes with a complimentary system that can process that data in some logical form.

In my approach I have the logic handled in the components themselves, but since it's the components that get instanced, and not the component systems, I'm sure there's quite a lot to save doing the logic system side if one can generalize enough to do it that way.

As for messaging, I use a publish/subscribe approach that can also take the id of the entity. That way I can publish a message that only the subscribed functors will get and can define exactly which entities should receive it as well.

I'm not going multithreaded though, as seems to be the source of the OP's problems in the first case. If I were though, I'd probably have one thread per component system, and use the "component holds only data, while the component system performs logic on that data" approach, so the components of the system would run in the system's thread, so the system would handle all the locking/unlocking as needed when messages are received from the entity or from other component systems.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!