I recently watched a talk by Bobby Anguelov on Entity/Object Models, which goes over past approaches to game object management (OOP, object-component model) and discusses their benefits and drawbacks. He also discusses ECS and praises how it fixes certain problems, but he also brings up several concerns, which he feels are not adequately addressed by this new paradigm. I listed what I think are the most important points below:
- “Iterating on components” sounds nice, but in a real game project, how many processes will fit neatly into this pattern? It makes perfect sense in a trivial example ("Boid simulators" as Bobby puts it), but most games are not a simple “update position using velocity and delta time” loop, and will have a lot of complex logic, edge cases, one-to-many connections, etc.
- Is “performance” really the most important issue? ECS libraries tend to place a lot of emphasis on making their component access insanely fast, often via complex storage logic. But again, realistically, is this going to be the bottleneck? More often than not, game code in particular will be messy by necessity, and a good system ensures that developers still have an easy time with it. ECS makes a lot of things nicer, but a lot of other things seem to become needlessly convoluted.
- How to “componentize” complex logic? Bobby shows a few examples where you want certain entities to have special behavior despite having the same components as others. Most ECS libraries will solve this using “tags”, which then leads to complexities with branching the logic in the systems (if/else blocks, filtering, etc.) which goes against the purported “efficiency” of ECS
- How to handle hierarchies, one-to-many relationships, etc? Most ECS libraries will enforce 1:1 ownership between an Entity and any component type, allowing for 1:N is rare, especially when trying to enforce the “performant arrays” mentioned above.
- Component inheritance? Is it really a good idea to just throw out OOP altogether?
To be clear, I'm not here to bash ECS, nor do I agree with everything Bobby says. I think ECS is a wonderful paradigm, and composition seems like the most sensible choice for game development. The main problem, in my opinon, is that there is a serious shortage of documentation, case studies, and best practices for ECS. Most of what you can find are extremely basic introductory pieces (usually involving the simple “transform + velocity” example mentioned above), or they are focused purely on the low-level engineering aspects, which in my opinion places way too much emphasis on “performance” and not on the “Big Picture”.
Generally speaking, I have yet to find material on ECS that actually dives deeper into how you can use it in a more complex scenario, with multiple larger modules interacting with each other, and entities/components being used to run multiple processes across a frame. In isolation, one can of course think of a way to make any particular process work via “iterating on components”, but it gets a lot less intuitive when one has to think of the entire game simulation.
Just to name a few things:
- How to design components so that they can be reused across multiple systems? Can they even be reused? Should “Transform” be the same one used for rendering and physics?
- Should a single ECS be responsible for the entire game? Or could it even be multiple different “ECS worlds” dedicated to a specific part of the game (gameplay, rendering, etc.), with entities from different worlds linking to each other?
- How to manage “key” entities (e.g the player, the AI Director), i.e those who are few in number but may have by far the most components per-entity. Is it even worth adding them to the ECS?
- How to run processes that require random access, e.g collision detection? Should these even be part of the ECS? Or should it be delegated to another system, with a cached result that the entities can iterate on afterward?
- How should rendering interact with ECS? What kind of data should be stored in the components, as opposed to what might be better to store in dedicated structures in the render module?
While these may seem like banal questions, there is actually precious little information on any of this when it comes to ECS usage. And yes, the trivial answer to this is “well it depends on the game”, but that doesn't mean we can't learn from past experiences.