In some games there can be too many entity archetypes. As a result the number of chunks explodes and creates a near-1-to-1 mapping between entities and chunks. Right now my test scene of 61 entities has roughly 30 different sparsely populated chunks. Is this unintended and if so, are there any design patterns to mitigate it? For reference my game is a tactical shooter with many different soldier types, each requiring a unique combination of components to create its behavior. Even worse is that there is a large number of components per soldier entity, and each entity is frequently attached “message” components causing it to shift between archetypes.
If you don’t want lots of archetypes, avoid this pattern.
Also note that empty archetypes will never go away. So those “message” components will just slowly increase the number of archetypes you have, slowing down queries and other operations iterating over all archetypes.
I thought that unused archetype chunks are recycled?
The chunks yes, but the archetypes do not.
That is unfortunate. I don’t know then how to mitigate creating a large number of archetypes during the lifespan of my game. The only alternative I know is to have components with a single boolean flag which, when set, triggers a system listening on that flag. This is considered to be an antipattern though… any other alternatives?
Instead of message components (which causes the creation of a new archetype per existing archetype) you could have message entities (creating just 1 new archetype per message type).
But my actual recommendation is to use this wonderful EventSystem made by @tertle : https://gitlab.com/tertle/com.bovinelabs.event
I have been using it in some test projects and so far I couldn’t be happier with the results.
Thank you for your suggestion. I have indeed considered using tertle’s EventSystem, since it eliminates most of the problems associated with message components. However, it requires that you manually handle read/write dependencies, which can be an issue in projects that rely heavily on messaging
Abstracting everything to granular components is fine but that’s just one part of the challenge. You also need to isolate concerns. Otherwise the number of components per entity when using granular components will explode. And good design aside it’s problematic with ECS.
So a component per behavior is one way, but you could just as easily have a single component that contains the union of all behavior types the soldier has. Like a bit flag and then for ease of use map that to an enum. So some of this is just using better data structures here and there.
The rest is mostly the right abstractions. You have data that is behavior specific. Command shared data most likely like say environment data. Maybe other soldier related data that the behavior might need.
The final step your systems should focus on isolating concerns also, not just at the system level but using job chains to isolate also.
There are a lot of ways this can vary in the details naturally. But mostly it’s good abstractions and isolating concerns, with some amount of just looking for better data structures for the problem.