I’m looking into Entity Component Systems and trying to understand them. So far I know that : Components are created that hold data but no logic, These components are added to an Entity therefore referencing the entity, and then the logic for the component is handled in a System. So… Let’s say that I have a System that renders. This system takes a Component that has a position and a Component with an image. If that system were to have hundreds of components, how would I go about finding those two components that are meant to be of the same Entity? To clarify more, how would the system know not to use another Entity’s image with a totally different Entity’s position? ???
There are a few ways ECS systems are implemented:
-
The components exist on the entity. This is the simplest but least efficient when it comes to processing (doesn’t take advantage of cache coherency) and great when it comes to memory usage. You ALWAYS know you’re operating on the correct components.
-
The components exist in a large array. The component at index K belongs to entity K. Ideally components are all initialized sequentially and placed in the array to take advantage of cache coherency. Entities only need to be an ID (K) and with that you look in each component array for their components. A challenge here is to keep track of which entity has which components. You could do this by using a Bitset sort of class, where component with ID X is 1 in the bitset in the Xth position if the entity has the component. This is a very fast solution but allocates more memory than needed. This is also very light on memory though - you grow your component arrays as you need more entities and you leave it be at that. You don’t need to allocate more components on each entity create. You just find a new entity ID. If you’re looking at component X at index K you know if you look at any other component at index K you will have the proper components
-
The components exist in a compressed array. Only entities with component K have an entry in the array. This is tracked by keeping an ID at K which is the entity ID. You end up having mappings between the entity and the indexes of their components in the component lists. This is like a decoupled #1 where the data is still stored in component lists for efficient iteration. This is a more complicated structure, if you want a code example I can provide. You know the indices of the components here by keeping a mapping. As long as you keep the mapping accurate you can be confident you are operating on the proper components.
So how are you implementing it exactly? That might shed some light on why you have worries about looking at the wrong component.
Thank you for the broad explanation on the different methods of creating an Entity Component System. However, I have focused my thoughts down to the particular issue that I’m not understanding.
Assuming I am using the most basic form of the ECS and trying to render a Sprite Component at the position of the Position Component:
Sprite Component + Position Component —> Entity —> ? —> Render System
I can’t wrap my head around how the Entity would go into the Render System. I was thinking of giving each system a list that holds all of the entities and iterates over them to see if they have the required components and accomplish the logic, but wouldn’t Iterating over the entire list of Entities slow down my game to a halt with the more Systems I have? So then I thought about treating the System as a component too:
Sprite Component + Position Component —> Render System(Sprite, Position) —> System List —> Entity
With this I would put the entities in an ‘Entity Manager’ and then run the logic of each system in the entity’s system list.
Am I completely lost on how this is actually supposed to work?
Jesus Christ, I just realized with the second way I am thinking there is no way for me to contact the components of other entities.
If you only want to iterate over the entities which have component X & Y then there are a few ways to achieve this. Based on personal experience you can create these concepts called “entity types”. An entity type in practice is like a “Ball” which has a Position, Velocity, and Image component. An entity type simply groups entities together based on the components they have. Not all entity types need to be named like “Ball”, the whole concept of entity types can be hidden behind the scene.
Anyway, on an entity type you have an ID (integer starting at 0), you have a bitset which represents which components an entity of that type has. I use bitsets because comparing them is very simple. If you want to know if a type has component X & Y you can use bitwise operations lickity split. Since you are only going to have a handful of entity types (maybe 10?) its pretty efficient to store the components directly in the entity type - then you iterate over the 10 entity types and say “DO YOU HAVE THESE COMPONENTS?” - if yes, iterate over each entity in the type.
I’ve created APIs like int typeId = entityManager.createType( POSITION, VELOCITY, IMAGE ) on the EntityManager - you can store that generated ID (index) as a static variable public static final int TYPE_BALL = … and later user it like so: entityManager.createEntityType( TYPE_BALL ). You can also have entityManager.createEntity( POSITION, VELOCITY, IMAGE ) which finds an entity type with those components and uses it, otherwise creates a new one. A little slower. You can dynamically add components to an entity by using the previous logic of finding the appropriate type and adding a new entity instance while removing the entity from it’s old type.
I hope this helps.
Absolutely wonderful, I understand how to go about this now. Might I ask where you got your education? You are very skilled. I’ve been on this site for years trying to self-study Java but I suppose I’ll forever remain a newbie if I don’t get a higher education. Honestly though, I appreciate the help.
I went to Shippensburg University which is a public college in Pennsylvania with a great CS department. Most of what I know was acquired by lots of practice, books, and article reading.
When it comes to high performance in Java I just read C++ articles on game programming (from AAA companies is best). Those articles really concentrate on memory and execution speed - and even though Java has its own memory management a game in Java is an entirely different beast. If you avoid allocation during game play your games can perform amazing things very efficiently. You essentially want to give the JVM heap memory manager nothing to do and you can achieve speeds comparable to C++