1
\$\begingroup\$

I'm trying to implement a simple ECS to help understand the concepts, and I am having a bit of trouble wrapping my head around how it would be used in cases where there is not a 1-to-1 mapping between entities and components.

For instance, an example of ECS, as I understand it, is that you might have a "drawable" component defined, which contains a mesh ID and a material ID required for drawing. This is easy to understand in the case you want a game like Super Mario, where each character is represented by exactly one sprite at any time, but what if you need more than one mesh to draw some characters?

Is it common to allow more than one component of the same type on an entity? Or else would you typically have an entity for each drawable component, and implement some kind of "join table" to map sub-components to a parent?

\$\endgroup\$
2
  • \$\begingroup\$ There are different variants of how to implement ECS. Some where this problem is trivial and others where you might have to cheat a lot. How are you doing the mapping between entities, components and systems right now? \$\endgroup\$
    – Philipp
    Feb 25, 2019 at 9:04
  • \$\begingroup\$ @Philipp so currently I'm trying to implement the "one big table" method: i.e. the entity is just an index into the component data. Components are stored in a sparse, regularly aligned array (i.e. each entity row has a slot for each component whether it has one or not). Systems filter the entity list using a bit mask of required components, and operate on each entity which matches the bit mask. \$\endgroup\$
    – sak
    Feb 25, 2019 at 10:36

2 Answers 2

1
\$\begingroup\$

There are a multitude of solutions that each have their associated cost in performance, maintainability and complexity.

This is my favorite solution for entities which consist of multiple sprites, like tanks with their turret. I use this in a 2.5D isometric RTS for the aforementioned use case.


You create an entity per sub-sprite and parent them to your main entity which holds the absolute position from which the sub-entities are offset. The "Parent-System" solves the absolute positions and rotations of the child sprites in a bottom (first child) to top (last child of child of ...) order.


Pros:

  • Rendering-System remains untouched.
  • Sub-Sprites can have individual modifications (shaders, particle-spawner, etc) to their behavior.
  • In line with ECS philosophy and design, which may give you some peace of mind.
  • Simplified/Unified rendering process is easier to optimize.
  • Parenting overhead is small since it only applies to visible entities.

Cons:

  • The overhead because of increased entity count may actually be significant if you abuse this solution, since having more entities always cause more overhead when managing entities.
  • The Parenting-System (position solving) needs to execute before the Rending-System and after any system that changes the parents position. This may create a conflict but is unlikely to actually affect you, since it's the natural order anyway.
  • You need to handle deleting stuff very competently, otherwise some entities might be left dangling around or worse

You might see how you can apply this to other problems as well, but it's not the only solution.


It's equally valid to create a special multi-data component if it saves you lot's of overhead and/or makes the whole thing cleaner overall. For example: You probably shouldn't create an entity per particle unless each particle needs some kind of special behavior and even then it's debatable. Having a component that holds an array of particle-data will have less overhead and fits the concept of particles always being in a group. You also probably want an rendering system that does only particle rendering (or treat particles differently), so it's not that bad to not reuse the sprite component.


A third solution would be to actually have ECS-level support for components being present more than once per entity, this has serious performance and design implications though and shouldn't be taken lightly. What if your sprite component needs an offset or a special shader? How do you associate multiple offset components to the multiple sprite components, with their order of creation? Do you group this data then? Is this better than having a component which stores multiple sprites in the first place?

\$\endgroup\$
0
\$\begingroup\$

There is not one recipe to build an ECS, but several ways to implement it. The gist is that you got Components that are sort of related to Entities and System working on the same time of Components over and over again.

So to get back to your question, if you want to have entities with several meshes for rendering, you either set your ECS to work with several components of the same type to your entities (e.G: Entities have lists for each component type) or have one mesh component with several meshes in it (this would need identifier in this component, when to use what kind of mesh etc.).

The Problem with several components of the same type for one entity might be, that you need to make clear, which component is the active one for the entity. If that is not clear, you might draw several models on top of each other for the same entity. Same would be problematic for different "types" of physics (water physics applied, and then falling physics etc.)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .