Jump to content

View more

Image of the Day

Trying out some of Pickle Jar compositions in @SketchUp and Unity, for a late #screenshotsaturday #gamedev https://t.co/HU0kZAnQtD
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net's newsletters to receive the latest updates and exclusive content.


Sign up now

Help implementing an Entity Component System

2: Adsense
  • You cannot reply to this topic
17 replies to this topic

#1 dertharino   Members   

112
Like
1Likes
Like

Posted 20 March 2017 - 05:25 PM

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.

 



#2 Alundra   Members   

2163
Like
1Likes
Like

Posted 20 March 2017 - 06:04 PM

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, 20 March 2017 - 06:08 PM.


#3 dertharino   Members   

112
Like
1Likes
Like

Posted 20 March 2017 - 06:28 PM

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.



#4 Alundra   Members   

2163
Like
1Likes
Like

Posted 20 March 2017 - 06:39 PM

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, 20 March 2017 - 06:42 PM.


#5 dertharino   Members   

112
Like
0Likes
Like

Posted 20 March 2017 - 07:03 PM

Ahh I see. So the only methods you would have in entity is the add/remove and getter/setters? 



#6 Alundra   Members   

2163
Like
0Likes
Like

Posted 20 March 2017 - 07:38 PM

Yes.
And some notify which for loop to call one callback in components when you add in scene, remove from scene, ....


Edited by Alundra, 20 March 2017 - 07:39 PM.


#7 dertharino   Members   

112
Like
0Likes
Like

Posted 20 March 2017 - 07:57 PM

I see. I'll try out that method! Thank you



#8 TheChubu   Members   

9307
Like
1Likes
Like

Posted 20 March 2017 - 10:08 PM

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.


"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

 

My journals: dustArtemis ECS framework and Making a Terrain Generator


#9 phil_t   Members   

7921
Like
0Likes
Like

Posted 21 March 2017 - 09:08 AM

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



#10 Alundra   Members   

2163
Like
0Likes
Like

Posted 21 March 2017 - 06:56 PM

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, 21 March 2017 - 06:58 PM.


#11 dertharino   Members   

112
Like
0Likes
Like

Posted 21 March 2017 - 08:29 PM

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.



#12 Alundra   Members   

2163
Like
0Likes
Like

Posted 21 March 2017 - 09:14 PM

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, 21 March 2017 - 09:19 PM.


#13 dertharino   Members   

112
Like
0Likes
Like

Posted 21 March 2017 - 09:18 PM

Ahh I see. Thanks for clearing that up.



#14 Alundra   Members   

2163
Like
0Likes
Like

Posted 21 March 2017 - 09:23 PM

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.



#15 dertharino   Members   

112
Like
0Likes
Like

Posted 21 March 2017 - 09:47 PM

Oh that's a good point. 



#16 Karsten_   Members   

2395
Like
0Likes
Like

Posted 23 March 2017 - 05:05 AM

As I recall, XNA already has it's own ECS implemented if you wanted to use that? Check out a few of these MSDN entries.

https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.gamecomponent.aspx

https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.drawablegamecomponent.aspx

https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.game.components.aspx
http://tinyurl.com/shewonyay - Thanks so much for those who voted on my GF's Competition Cosplay Entry for Cosplayzine. She won! I owe you all beers :)

Mutiny - Open-source C++ Unity re-implementation.
Defile of Eden 2 - FreeBSD and OpenBSD binaries of our latest game.

#17 phil_t   Members   

7921
Like
0Likes
Like

Posted 23 March 2017 - 12:11 PM

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.



#18 Alundra   Members   

2163
Like
0Likes
Like

Posted 24 March 2017 - 08:42 AM

From what I see in MSDN, it's an ECS, you inherit GameComponent with what you need or use the existing, you add this component on one game object.