I have been reading about ECS architecture. I write business software at the day job, so trying to work through some small projects in order to really grasp the very different way of thinking that ECS espouses.
I have been watching Unite 2017 videos, in particular the one regarding the new job system and compiler changes, and it sounds like we might have something to at least preview sometime in 2018.
In the meantime, can anyone recommend an existing ECS library to play with, just so I can continue to train my brain to think about code organization in a different way? I have read a bit about Entitas, but the developer seems to be MIA (no updates since May, etc).
I’m on my I think 6th or so iteration on implementing entity systems spanning the last 8 years. My conclusion at this point is the value you get from anything resembling a strict ECS system is marginal. And the chances that it will just end up getting in the way are fairly high.
There are some good lessons to pull from ECS however.
The main issue I ran into is that the architecture is half baked. It doesn’t answer important things like how to handle dependencies. Plus you have to look at the problems it was originally designed to solve. Performance was a key one, which is a moot issue with Unity because all the performance critical stuff is handled for you, you don’t control that.
The other selling point was having a data driven architecture. But there are multiple ways to have that, you don’t need ECS to get there.
Generally I have found that creating feature specific data and logic works out better then trying to make a generic system work for everything. The trick is to define a system that shares the most without getting in the way of specific features.
For example my messaging and data models are all protocol buffers, and very often one and the same. I will usually have some that are data models and some that are separate request/response wrappers that usually contain the data models. Message dispatching and event handling are generic. Stuff that specific features don’t and shouldn’t care about.
But how a feature wants to model it’s data should largely be left up to it, without having to force it into some paradigm that doesn’t fit well. My rules for data models are fairly simple, it needs a specific type of id if it will go into the database, it should use integers/enums where possible in the design for space efficiency, etc…
The problem I’m fairly certain will exist with anything Unity does here, is that most of the above you can only figure out by actually making games with ECS. Making platforms/engines doesn’t give you the context to really know what works well and what doesn’t. Which is why even when I was using ECS I was writing my own, because most implementations didn’t evolve from real world usage in real games.
Another issue is that to use an ECS system efficiently requires a good amount of tooling. A bare bones editor works functionally but it’s really hard to reason about the data without a higher level structure to organize it.
Plus it starts getting really difficult to reason about what does what and what can be used together when you have say 100 different components that can possibly be used on any entity. I mean that’s the whole idea behind an ECS, the entity is just a sum of it’s parts. But real games kick you in the ass and say hey this component needs to be just a bit different in this context. So now you can either give additional context specific data to the component, or you can create another component that’s almost the same but not quite. And then you have to sort that out in the editor somehow so designers know what is what.
Now combine that with components that depend on other components, that has to be sorted out also.
ECS is a case of some good ideas that were never baked fully. I tried several times to make it all work but couldn’t. I have yet to see anyone else solve the issues I ran into either. So maybe it’s possible, but at this point I tend to agree with Martin Fowler that it’s more of an anti pattern.
Oh ya almost forgot a big drawback. Mapping entities to a database. It can be done. In Game Machine I wrote a whole layer with code generation that generated a simple Orm layer over entities, which were protocol buffer messages. So you could take a message/data model all the way from the client to the database (with proper validation), much like you can do with most MVC frameworks.
But what will invariably happen with those less skilled in data/database design, is they will end up with something horrible that should not ever be, like one huge document in a document database, or god forbid one huge table with 100 columns. That is exactly where ECS systems lead to in the hands of someone without a lot of experience if the data needs to be persisted.
In your experience, is there a threshold where the lack of organization of the components becomes untenable? I wonder if there is some sort of validation you could apply to dictate which components can be used where. That might be counter purpose, but might go a way towards “documenting” the expected usage in some cases.
Will keep reading, but thank you for sharing your real world experiences!
It’s not terribly difficult to have an organization structure. The approach I liked best was an editor screen where you define which components go on an entity. Because normally that doesn’t change much. You can always change it yet when working with it you don’t have this huge selection of components.
But you still have the issue of dependencies and similar components. And often you face the dilemma of you really want components within components, but ECS likes everything to be rather flat.
Thanks Elzean, I mispoke. I was looking at the releases section of the wiki, which had last been updated in May. I only noticed afterwards that there had been recent commits.