I'm planning to develop a game in C# (but I don't think that language matters) and I'll be using Entity Component System since I know by design that my game will have a lot of different game items with different twisted behaviours and logics. I have some experience using Unity ECS which I find very easy and intuitive. I've also programmed games in the past using the old "inheritance approach" and I found that pattern very not scalable.
As far as I know, a pure ECS (which is not what Unity implements) works like this:
A GameObject is just a collection on Components, it may be seen as a wrapper class or as a shared index in some parallel arrays of Components.
A Component is a collection of data (basically a record) which holds the data needed by its relative System to handle it. It does not implements game logic itself.
A System is a world object which loop through each GameObject which has a component it can process and update game logic of that component.
My point is: if the Systems are the ones responsible for the actual game logic update (practically speaking, the game logic code is written inside the system), is there a 1:1 relation between every component and every system ? Let me explain with an example: let's say I have 2 components:
- RenderSpriteComponent
- RenderLightSourceComponent
The first one does a simple 2D sprite rendering (using OpenGL or whatsoever); the second one send a light source to the rendering shaders. They do similar operations but with some actual differences. My question is: since they behaviour is different, should I implement two different Systems which will handle them separatly? If not, should I add a bunch of IF
statements or overloads to handle those two components inside the same System?
From my point of view both ways seem unnecessary, especially if the ECS should improve code scalability. Using one of those approach would force me either to implement a different system for each component I have (implying a lot of GameObjects loops) or either to fill my Systems with if and overloads making them impossibile to understand after a certain point.
Furthermore, from what I can see and understand, Unity implements a different version of this pattern in which every component implements its own logic (in the Update method) and the GameObject is a wrapper class which has an internal list of components to update. Systems don't exist at all (or if they do they do, they do so for other reasons). This implementation looks easier and more "elegant" from my point of view, but I can't understand why it's not so spread and everyone sticks to the "classic" ECS implementation which has those "problems" I've described above. At the same time, I do not have control over the priority of the components updates, which can be useful in some cases.
I understand there isn't an "absolute" better way to design your game structure, but I'd like to know how is generaly implemented. Or which factors would make a way better than the other.