Cool use of macros. That simulation at the end was very interesting.
One thing I've always wondered about ecs is if you just focused on the array and looping part and instead ignored the component part. Seems a lot simpler over all amd is probably faster too because you're not doing a bunch of branches on components.
This is a good spot, ECS really shines when you have a lot of homogeneous entities. Which is why demos are all about enormous cities, thousands of troops or basic particle systems.
If your entities are more heterogenous or don't need to be running all the time the benefit for gameplay code disappears quite quickly. In particular the acronym conception of ECS architecture isn't the most performant way of organizing things. Which is why you end up with concepts like archetypes to base memory organization around.
Nothing wrong if you're writing a general-purpose engine around ECS as an organizational principle but for game makers you still need to think about memory access patterns and how to organize around that.
If you're just trying to make a game then make the game and organize the game data around it's unique access patterns. If that's just a flat array of tagged unions then who cares.
ECS is a fairly "late" idea in game development history, "just stuff widgets in arrays" works just fine in small games. But when you have
- commercial games getting too big for any one single person to keep track of all those widgets getting developed in parallel
- engines being developed as standalone generic projects to be used in many, many games that need solid abstractions
- enough RAM to justify the overhead (whole megabytes! Scandalous!)
...then ECS starts making a lot of sense. That was in the late 90s/early 00s, and these days the (performance) overhead is negligible even for indie game dev. The only potential downside is the cognitive overhead, but that very much depends on what you're doing.
One thing I've always wondered about ecs is if you just focused on the array and looping part and instead ignored the component part. Seems a lot simpler over all amd is probably faster too because you're not doing a bunch of branches on components.