Game Entity System learning
Entity systems are simple in concept:
- Every ‘thing’ in system has an id
- The entity system (hopefully a library if you are reading this) stores data components against each id
- Data components can be colour, size, mass or position
Then you write a listener system which ‘acts’ on each of the entities in the system, which decides what to do.
Done, explaination over. Although obviously its more complex to actually use than that, but not by much.
My attempt at learning this was a re-hash of a game I had already made: Asteroids (assuming you have a game engine already, and can use it effectively, using an entity system is rather easy)
I’ll skip over all the details (because im lazy and because its written in like 60 places online already), the general idea is that game objects are really just a guid/id/int. This is really me just typing for fun I swear.
And you write these listener systems which just act on entities with the data components that it works with. Examples:
position
,shape
,colour
andsize
could alow aDisplaySystem
can use these to show them on the screenposition
andvelocity
could allow aMovementSystem
to update theposition
to show motionhealth
andhit
used by aDamageSystem
can reduce the health and record game interactionspostiion
andsize
used by aCollisionSystem
could allow objects to bounce/explode/reducehealth
…well i hope you get the point.
The next concept which is important is to not set the same entity type on the same entity. This is because the last one to set it will win, causing a race condition.
From the great help I recieved on the jMonkeyEngine forums (@ here) preventing these situations is very important and can be done with something called a tagged entity
.
Basic logic is that you create a new entity which has an ‘affects’ data component. So when the systems use it the resulting info is applied to the tagged entity not the one the component is actually against.
This allows many systems to update an entity but not overstep other systems.
For example, say you have a display only particle, but you want it to be affected by gravity and be affected by external collisions.
What would normally happen is there would be like a GravitySystem
which sets the acceleration on the object. And another system like CollisionSystem
which sets the acceleration based on impulses it receives from the environment.
These are now setting the acceleration on the entity at the same time, causing only one of the acclerations to get registered.
In this case using a tagged entity is useful, instead of the systems editing the acceleration data component directly, they create a tagged entity which refers to the base entity. And both accelerations can be applied.