Sign in to follow this  
dertharino

Help implementing an Entity Component System

Recommended Posts

Hello everyone. I've recently started to experiment with trying to implement an Entity Component System for my XNA/Monogame projects. Up until now, I've been using the usual OOP style but as my games have grown bigger, I realized I've been having lots of trouble keeping my base class from being bloated. Some quick google searches later, and I ended up reading articles about Entity Component Systems (in particle this article: http://t-machine.org/index.php/2007/11/11/entity-systems-are-the-future-of-mmog-development-part-2/ ). This system seems to solve a lot of the problems I've had and as such, I  would like to try to implement an Entity Component System (in particular, a one where the components are just data and the systems control the logic).

 

However, I've been having some problems implementing this type of system. I understand the reasoning and the concepts behind the organization, but I can't seem to put a finger down on actually translating this into code. In particular, implementing Systems. Some problems I've been having include:

1. How do I know what system to call and when? I was thinking of just constantly looping a list of entities in my game class and checking to see if each entity satisfied a criteria and then passing that entity to a system, but that seems to be too time consuming--especially the more entities there are. Is there a more efficient way of doing this? I was thinking of potentially just testing the id of the entity but that seems like a naive and hacky way of going about it.

2. How to implement specific systems. For example, for a collision system, I'm having trouble implementing it. Would I just loop through each entity that has a Collidable component, first check to see if it collides with any map tiles and then loop through the other entities and check if they collide with one another? Also, before now, my collision system usually relied on knowing what the next position would be and then fixing the position accordingly. With an ECS, wouldn't I want my collision system to have nothing to do with my physics system? Or am I overthinking this.

 

Any help would be great! Thank you in advance.

 

Share this post


Link to post
Share on other sites

Entity Component System (ECS) is only a data design, you then implements in the way your application needs.

GameObject
  -> Transform
  -> Mesh
  -> Animation
  -> ...

Components have to communicate, the example is the Rigid Body + Colliders, you link the colliders to the rigid body.
Communicate means : You have to know when a component is added and removed to do actions based on that, example, here you link the colliders to rigid body.
It's also needed to know when the component is really added in the scene to create for example the physics only there (and delete when removed from scene).
Another example is the audio component which needs to play/stop based on when it's added in the a scene and when it's removed from scene.
System means manage the registered components, you could simply have an array of registered components and update all.

Edited by Alundra

Share this post


Link to post
Share on other sites

Entity Component System (ECS) is only a data design, you then implements in the way your application needs.

GameObject
  -> Transform
  -> Mesh
  -> Animation
  -> ...

Components have to communicate, the example is the Rigid Body + Colliders, you link the colliders to the rigid body.
Communicate means : You have to know when a component is added and removed to do actions based on that, example, here you link the colliders to rigid body.
It's also needed to know when the component is really added in the scene to create for example the physics only there (and delete when removed from scene).
Another example is the audio component which needs to play/stop based on when it's added in the a scene and when it's removed from scene.
System means manage the registered components, you could simply have an array of registered components and update all.

So would something like this work?

I would create an EntityManager class that would be in charge of attaching and removing components, and creating entities in the game. Then in those attach and remove methods, I would test to see what components the entity already has. If the entity has the necessary components to satisfy a system, I would pass that entity into a list located in that system and that system would just work with the list.

Share this post


Link to post
Share on other sites

Components generally have their data, I don't see why it should be shared using a manager there but maybe to win memory you can reuse the component if you are sure it's shared.
I simply have the Add/Remove to add/remove components in the entity and the constructor/destructor of the component or the Add/Remove of entity can add/remove in the system/manager.

Edited by Alundra

Share this post


Link to post
Share on other sites

Just search around for a lib that already implements it. If its something proven (ie, it has a few games to showcase) then better. You'll spend too much time implementing it from scratch and it wont be a much more enlightening experience than just checking out the implementation of an existing lib.

Share this post


Link to post
Share on other sites

You can implement your Entity Component System but you have to be very carefully to implement all the situations, and test the system correctly.
One example : if you add one component you have to check if the scene is valid to call "AddedInScene callback" same when you remove the component to call "RemovedFromScene".
Unreal Engine calls that Register/Unregister, but it's the same thing, only another names which is maybe less understanding directly.
The best test is of course to have the system for one game, if you write all that for nothing of course you will never know.

Edited by Alundra

Share this post


Link to post
Share on other sites

I did one in XNA several years ago, shouldn't be hard to convert to MonoGame - or at least be helpful to look at the source code:

https://www.gamedev.net/resources/_/technical/game-programming/case-study-bomberman-mechanics-in-an-entity-component-system-r3159

This actually looks really cool. I'll be sure to try this out this weekend! Thanks.


Just search around for a lib that already implements it. If its something proven (ie, it has a few games to showcase) then better. You'll spend too much time implementing it from scratch and it wont be a much more enlightening experience than just checking out the implementation of an existing lib.

Yeah I've looked into frameworks like Nez or the C# implementation of the Artemis framework, but I am interested in trying to implement one myself (tends to help me understand the systems more if I at least give it a shot myself).


You can implement your Entity Component System but you have to be very carefully to implement all the situations, and test the system correctly.
One example : if you add one component you have to check if the scene is valid to call "AddedInScene callback" same when you remove the component to call "RemovedFromScene".
Unreal Engine calls that Register/Unregister, but it's the same thing, only another names which is maybe less understanding directly.
The best test is of course to have the system for one game, if you write all that for nothing of course you will never know.

Can you elaborate on that a little bit? Still a bit confused about what you mean by that.

Share this post


Link to post
Share on other sites

Your Entity has a pointer of the scene where it is registered. If the scene is not valid (nullptr) you don't call the AddedInScene callback on component, same kind for RemoveComponent function.
When you add the entity in the scene, the scene class call NotifyAddedInScene which is a for loop on all components to call AddedInScene.
For the Physics component which is linked to physx, you create the physics here, for the sound you create the sound and play the sound here for example.
Another win of doing like that : if the scene is an editor scene, you don't create the physics and sound, only in game scene.

Another thing : Add a "CanHaveMultipleInstance" virtual in component which return true or false.
For example the rigid body component can only have one instance listed in the entity.

Edited by Alundra

Share this post


Link to post
Share on other sites

Once you have all the system working you can also have an Activated parameter with SetActivated/GetActivated functions and one callback "OnActivated".
For the physics component it enable/disable the simulation for example.

Share this post


Link to post
Share on other sites

The GameComponent stuff in XNA is not an ECS at all. It's classic OOP "call Update() on a black box". It's mainly intended for large systems, where a GameComponent might be the GUI, or networking or something.

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