Ah, ECS. The most ill-defined software pattern since IoC/DI. Everyone seems to have their own understanding of it, usually somewhere on the spectrum between "what if we kept the game state in a relational database"[0] and "what if we put any individual type of information into its own big array, so it's CPU-cache-friendly"[1]. I wrote several such systems for my own toy games, at various points of that spectrum[2], and I still have a bunch of open questions I can't seem to get my head around.
The biggest such question is: how the hell do you handle "cross-cutting concerns" in an ECS architecture, especially in the data-oriented programming version, where "cross-cutting concerns" are basically any kind of logic ("system") that needs to access more than one component of an entity at the time, especially if it does so conditionally? Like e.g.:
- Physics, rendering, animation, and game logic all need to access some subset of the same position, orientation, dimensions, velocity, acceleration, mass, tensor of inertia, etc.
- Any kind of logic that goes like "IF something(component 1) THEN doSomethingTo(component 2) ELSE doSomethingTo(component 3)".
How are you supposed to preserve data locality in such cases? Is it even theoretically possible?
I may have some fundamental misunderstanding about the definitions here[3], but I haven't found any clear answer to the questions above, whether theoretical or practical. Back when I last looked, couple years ago, I couldn't find any non-toy game written ECS-first and with source available to study. Maybe this has changed now.
--
[0] - Which, as far I recall, was the original idea behind the pattern. It's also a very interesting one in general - if you squint, a lot of code all of us write for our projects is just half-baked attempts at setting up specific indexes and hand-rolling queries to a bunch of vectors, hashmaps, or (gasp) object graphs.
[1] - AKA "data-oriented programming", in this case mostly preferring "Structs of Arrays" over "Arrays of Structs".
[2] - One of them was literally just "let's store all game state in an in-memory SQLite database, because guess what, it's actually fast enough to be queried at 60 FPS!".
[3] - In my defense, most of the guides, tutorials and articles I read back in the day were themselves confused between "SQL approach" and "SoA approach" (see [0]), or worse, mixed in "whatever abomination Unity passed as ECS back then" and even something semi-related from .NET world. It took me a lot of time to understand that everyone's using their own blend of all those ideas, and this left me unsure about what one's really supposed to do.