To any budding game developers, my advice would be to not rush into ECS and try to accomplish your goals with structs and loops first and understand the fundamentals of how a video game 'works' under the hood.
Your game will get done if you work on it, not necessarily if you pick ECS!
I've spent a few months working with ECS/DOTS with the Unity Game Engine, their implementation of this style of architecture end up being very complex in comparison to the old fashion GameObject workflow that made Unity popular in the first place.
Everything is MUCH more difficult to implement, I won't go into details but from my experience the time spent to achieve a similar result is about 5x-10x what it should be.
Weird APIs, poor documentation, limited collective experience, tons of restrictions and limits of the C# language are making the global experience quite nightmarish.
And I have had experience with ECS-like system in different engines in the past, and I am mostly experienced with low-level engine stuff, but the induced complexity there is something I did not expect.
> GameObject workflow that made Unity popular in the first place.
It's a bit much of a over-simplication that just the GameObject architecture Unity uses is what made it popular. For example, if there wasn't a UI editor for Unity and only code, you still think it would be as popular? I'm 99% sure it wouldn't be.
I tried getting into DOTS as well, as ECS is an interesting architecture overall, but Unity kind of dropped the ball on it and made it way more complicated than it has to be, from every side of having to use it.
On the other hand, you have Bevy, which is built with ECS as a core part of the engine, and it makes using ECS a breeze. After getting to know Bevy and ECS outside of DOTS better, I'm not sure I could back to how I wrote my games before. ECS just makes it a lot easier to structure bigger projects than the basic introduction game like flappy bird. The modularity is on a different level and it gives you a much better view of the overall architecture than anything else I've tried before.
Simply put, I'm not sure I'd write the same amount of games if it wasn't ECS, because it makes it fun to make games again, for me.
As a game dev that’s been using Unity ECS in production for over 2 years, it’s a very underwhelming implementation. Sure it’s fast if you design a game with Unitys intentions, but Unity has never made a game and what they made isn’t what game devs need.
Whether ECS is complex or not depends a lot on which one you use. I've heard the same thing from a lot of gamedevs that use DOTS, but people in general seem to be pretty happy using Entitas (also a C# ECS that can be used with Unity), Bevy (which is based entirely on ECS) or for that matter Flecs.
Yeah fully agree, ECS is the microservices of gamedev these days.
I've worked on AAA games that used it, and shipped games as a solo dev without it. If you don't know why you need it, then chances are you don't need it. Just keep it in mind as one possible architecture pattern for when your code base starts to experience growing pains is my advice.
I don’t have any intention of writing a game, but my lay understanding of ECS is that it sort of treats your world as an in-memory columnar database for better cache locality: if you’re updating the positions of a collection of entities, you only need to loop over a collection of contiguous `position` structs—you can get a lot more of these in a cache line than you would if the entire entity was a struct containing a position field among many other fields which are irrelevant to the updatePosition operation. How far off am I?
I'm definitely not going to argue that you need ECS to do much of anything, but ECS has come long way in the past 4 years from a tool that lets you have lots of entities in a game, to a more generic system for entity management.
An ECS can also come with a bunch of tools for inspecting entities, monitoring performance or changing components in realtime (https://www.flecs.dev/explorer/). Definitely not something you need to complete a game, but very handy.
The opposite also applies: don't reinvent the wheel if you want to get something done.
Existing game engines like Unity/Unreal already have builtin solutions for entity management, but if you're (for whatever reason) using something that's more custom you can avoid having to reinvent entity management by using an ECS library. Similar to how you'd use libraries like SDL/bgfx/sokol for graphics.
How games work is simple. It's a simulation run at some frequency and the simulation can be affected by player input. Sometimes there is a synchronization step with a server and that is more complicated.
ECS is a pattern that results in better performance and more maintainable code. There is no reason not to use it.
Better performance and more maintainable code are never the only concerns. For example, achieving a running prototype quickly with some ported/adapted non-ECS engine from a previous project might be more effective and efficient that starting from scratch with a better ECS architecture.
component systems are useful when you have no design doc, or a design doc written by new-hire monkeys. Or when management has no idea what the goals are.
As a programmer not part of this world: what's the go-to alternative in this situation?
Does ECS not naturally arise from using OOP? Trying to think if you are creating instances of players/physics objects/items how that wouldn't turn into a kind of entity system.
No actually the ECS approach is more or less the exact opposite of (naive) OOP. In (naive) OOP you design objects for your domain, like an enemy, or a bullet, or an explosion. In ECS, you define abstract entities and compose data (and potentially behavior) on top of them, so there's no single "enemy" object, there's an entity that composes AI, geometry and sound effects to make it behave as an enemy.
In general, for large systems, this is a great way to achieve decoupling, where the naive OOP approach would get you stuck quickly.
One view on the OOP <=> ECS relationship is that ECS is an exploration of/recreation of/divergence from alternative "natural" OOP systems outside of the "dominant OOP strain" of C++ (and family) (re-)implemented on top of C++-style OOP.
There are hints (and needs) in ECS systems of post-hoc/runtime Prototypical inheritance rather than pre-hoc/design time Class based construction.
There are facets of ECS that resemble concepts like mixins and pattern matching and multi-dispatch and message passing rather than "pure" "C++ VTABLE" dispatch.
Some of these things arise more naturally in other branches of the OOP family tree: the Common Lisp Object System can do some of these things out of the box; Smalltalk and its descendants (even Objective-C) were easier to mold to ECS-like configurations; IO had interesting things to say about this style of OOP; even much-maligned JS' "strange" branch of Prototypical OOP has a bunch of low-level tools that make ECS "less of a need" in JS because there are ways to do them more "naturally".
Certainly, though, in C++ and closer-related derivatives (even Java and C#) ECS isn't as naturally a pattern, which is why it often has need for strong "frameworks" and why there are often multiple, competing ones to pick from.
ECS can mean many things. the idea that you put components together (physically, in memory) and try to set up your processing so stuff is processed together may be quite natural.
but actual ECS systems add a lot of stuff on top that's not very natural (in any programming paradigm, not just OOP).
it's about enabling you to add and remove components at runtime, manage complicated relationships between entities and their components in a generic sense. this has all the advantages and disadvantages that those kinds of abstractions bring. bad if you don't need it, good if you do.
In 2D games it is often times some kind of object hierarchy (scene graph, display list, nodes) imposed by the engine/library, which never plays well with ECS IMO. In these instances I think it is better to just inherit from a carefully thought out god object (yeh yeh I know).
If you are using a low level rendering library, or immediate mode library, you can more easily define your state however you want, but still ECS incurs massive overhead compared to basic arrays of structs. If your language allows structural typing then ECS seems to me as having little benefit.
A collection (e.g. an array or a hash map) that stores things. Maybe more than one collection like that, different for each type of entity: monsters, items, etc. (Separate code paths to handle these different types of things.)
Keeping indexes/keys for references, and loops over these collections can do a lot without any upfront complexity of an entity system.
stephc_int13|2 years ago
Everything is MUCH more difficult to implement, I won't go into details but from my experience the time spent to achieve a similar result is about 5x-10x what it should be.
Weird APIs, poor documentation, limited collective experience, tons of restrictions and limits of the C# language are making the global experience quite nightmarish.
And I have had experience with ECS-like system in different engines in the past, and I am mostly experienced with low-level engine stuff, but the induced complexity there is something I did not expect.
capableweb|2 years ago
It's a bit much of a over-simplication that just the GameObject architecture Unity uses is what made it popular. For example, if there wasn't a UI editor for Unity and only code, you still think it would be as popular? I'm 99% sure it wouldn't be.
I tried getting into DOTS as well, as ECS is an interesting architecture overall, but Unity kind of dropped the ball on it and made it way more complicated than it has to be, from every side of having to use it.
On the other hand, you have Bevy, which is built with ECS as a core part of the engine, and it makes using ECS a breeze. After getting to know Bevy and ECS outside of DOTS better, I'm not sure I could back to how I wrote my games before. ECS just makes it a lot easier to structure bigger projects than the basic introduction game like flappy bird. The modularity is on a different level and it gives you a much better view of the overall architecture than anything else I've tried before.
Simply put, I'm not sure I'd write the same amount of games if it wasn't ECS, because it makes it fun to make games again, for me.
jbluepolarbear|2 years ago
ajmmertens|2 years ago
davedx|2 years ago
I've worked on AAA games that used it, and shipped games as a solo dev without it. If you don't know why you need it, then chances are you don't need it. Just keep it in mind as one possible architecture pattern for when your code base starts to experience growing pains is my advice.
throwaway894345|2 years ago
ajmmertens|2 years ago
Things like entity relationships (https://ajmmertens.medium.com/building-games-in-ecs-with-ent...) introduced features that were already common in existing entity management systems, such as entity hierarchies.
An ECS can also come with a bunch of tools for inspecting entities, monitoring performance or changing components in realtime (https://www.flecs.dev/explorer/). Definitely not something you need to complete a game, but very handy.
pjmlp|2 years ago
ajmmertens|2 years ago
Existing game engines like Unity/Unreal already have builtin solutions for entity management, but if you're (for whatever reason) using something that's more custom you can avoid having to reinvent entity management by using an ECS library. Similar to how you'd use libraries like SDL/bgfx/sokol for graphics.
illiarian|2 years ago
I guess it's one of those things that you don't know until you try (and hit the limits of using or not-using one).
I'm also reminded of Robert Nystrom's "Is There More to Game Architecture Than ECS": https://youtu.be/JxI3Eu5DPwE
(Yes, Robert Nystrom of Game Programming Patterns and Crafting Interpreters)
brigadier132|2 years ago
How games work is simple. It's a simulation run at some frequency and the simulation can be affected by player input. Sometimes there is a synchronization step with a server and that is more complicated.
ECS is a pattern that results in better performance and more maintainable code. There is no reason not to use it.
unknown|2 years ago
[deleted]
HelloNurse|2 years ago
oneshtein|2 years ago
tourgen|2 years ago
https://github.com/tmewett/BrogueCE
component systems are useful when you have no design doc, or a design doc written by new-hire monkeys. Or when management has no idea what the goals are.
midland_trucker|2 years ago
Does ECS not naturally arise from using OOP? Trying to think if you are creating instances of players/physics objects/items how that wouldn't turn into a kind of entity system.
vouwfietsman|2 years ago
In general, for large systems, this is a great way to achieve decoupling, where the naive OOP approach would get you stuck quickly.
WorldMaker|2 years ago
There are hints (and needs) in ECS systems of post-hoc/runtime Prototypical inheritance rather than pre-hoc/design time Class based construction.
There are facets of ECS that resemble concepts like mixins and pattern matching and multi-dispatch and message passing rather than "pure" "C++ VTABLE" dispatch.
Some of these things arise more naturally in other branches of the OOP family tree: the Common Lisp Object System can do some of these things out of the box; Smalltalk and its descendants (even Objective-C) were easier to mold to ECS-like configurations; IO had interesting things to say about this style of OOP; even much-maligned JS' "strange" branch of Prototypical OOP has a bunch of low-level tools that make ECS "less of a need" in JS because there are ways to do them more "naturally".
Certainly, though, in C++ and closer-related derivatives (even Java and C#) ECS isn't as naturally a pattern, which is why it often has need for strong "frameworks" and why there are often multiple, competing ones to pick from.
fartsucker69|2 years ago
but actual ECS systems add a lot of stuff on top that's not very natural (in any programming paradigm, not just OOP).
it's about enabling you to add and remove components at runtime, manage complicated relationships between entities and their components in a generic sense. this has all the advantages and disadvantages that those kinds of abstractions bring. bad if you don't need it, good if you do.
pharmakom|2 years ago
I think the future of game dev may end up being immutable and event driven actually... but I’m yet to see anything beyond a prototype.
JoeyJoJoJr|2 years ago
If you are using a low level rendering library, or immediate mode library, you can more easily define your state however you want, but still ECS incurs massive overhead compared to basic arrays of structs. If your language allows structural typing then ECS seems to me as having little benefit.
a-nikolaev|2 years ago
Keeping indexes/keys for references, and loops over these collections can do a lot without any upfront complexity of an entity system.
whateveracct|2 years ago
But I _would_ recommend ECS to Haskell devs interested in making games because apecs is just that good.