11 ms·
I don't really understand what's the advantage of ECS compared to OOP composition. Anyone here can shed some light on the matter?
by samwestdev 6y ago
I don't really understand what's the advantage of ECS compared to OOP composition.
Anyone here can shed some light on the matter?
- EamonnMR 6y agoHere's a real example from a project I worked on in my homebrew ECS framework and later implemented in Godot: a guided missile. In the ECS project the notion of 'thing that can run into other things and do damage' so totally separate from the notion of 'thing that is driven around by AI.' So adding guidance to an existing projectile wasn't too much of a pain. In the Godot project I'm dealing with networking as well, so the division is between fire-and-forget projectiles (derived from Bullet) which know about hitting things and doing damage, and AI driven Ships with AI or player driven movement which needs to be synced over the Network. In that case I had to copypasta the AI driven movement code into a 'guided' class under Bullet. That said, for almost every other task, Godot's composition first model has been way easier to work with, especially because it lets you test elements in isolation. Here are the two projects if you'd like to compare the code: Homebrew ECS framework on top of the babylonjs engine: https://github.com/EamonnMR/Flythrough.Space https://github.com/EamonnMR/Flythrough.Space Godot with networking: https://github.com/EamonnMR/mpevmvp https://github.com/EamonnMR/mpevmvp
- DominikD 6y agoShort story: data is aligned in a way that favors batch processing. Less branching, great setup for SIMD or GPU processing.
- gurkendoktor 6y agoI've heard this so often, and I still don't quite get it. Let's say most of my game objects have a "Position" component, and all the X/Y coordinates are now in one big integer pool. With this setup I can now add 5 to each object's X position really efficiently. But what's the use case for that? Particle systems, and what else? My game objects always look more like Celeste's Twitter-infamous Player class: https://github.com/NoelFB/Celeste/blob/c32f134d210fcf710d7505727df488f1468a6a66/Source/Player/Player.cs#L603 https://github.com/NoelFB/Celeste/blob/c32f134d210fcf710d750... Say about the length of the file what you want, but isn't it actually better for caching that all of the Player's instance variables are in one object, and not stored in components somewhere else? (Now, maintainability is another issue. But I've always found Ruby-style mixins much easier to reason about than the toy ECS systems I've seen.)
- bogwog 6y ago> With this setup I can now add 5 to each object's X position really efficiently. But what's the use case for that? Particle systems, and what else? Physics, AI, animation, etc. A player controller is not a good candidate for that type of optimization because they tend to have very complicated logic that needs to interact with many different game systems. Also, you don't usually need to have more than one or a few. That class you linked to is a mess because it seems like all state is mashed together into a single class. One way to clean this up is to implement an object-oriented state machine, so that state variables and logic are organized into classes instead of being a conditional soup in a giant update function. Here's a good article on that: https://gameprogrammingpatterns.com/state.html https://gameprogrammingpatterns.com/state.html But that game shipped and it worked, and that's really all that matters.
- gurkendoktor 6y ago> Physics, AI, animation, etc. That sounds good, but how would this look like in practice? For the sake of simplicity, let's assume I write a 2D game with classic spritesheets for animation frames. With an ECS, I can pool the animation state of each object into the animation system, and basically execute "anim_frame = (anim_frame + 1) % num_frames" for all objects in one speedy loop. But game object animations are tied to game logic, and as soon as an object depends on its anim_frame in logic that is outside of the animation system, the cache benefits are moot. Maybe I'm not thinking big enough in terms of how many "dumb" objects are in the game in proportion to the ones that have lots of logic (like the player).
- rahkiin 6y agoThe player can be just one component, until you split things to reuse them. But imagine a simple 2d game: whag are you reusing on a lot of entities? - collision size - sprite to render and render properties - position on grid - maybe also a velocity, maybe an acceleration With ECS it becomes trivial to make a system that iterates over all entities with a sprite and a position, and draws them. Another system can adjust the position with the velocity. Notice how we can create non-moving entities by not having the velocity component at all. Also notice how we can easily add a rendered sprite to any entity without changing any code. I know this scales well as it gets more and more popular also for larger games. Bonus: This data is all located together so iterating over Sprite+Position is very cache friendly. And if a system only reads and writes data to the entity jt can also be parallelized.
- sitkack 6y agoIt also translates to a relational model, selection, join and projection.
- deleted 6y ago[deleted]
- hertzrat 6y agoBasically, in game dev, small differences in performance lead to a very noticeable effect on frame rate. In this case, cache misses are a big deal and their impact really adds up. ECS is a way structure your data to minimize cache misses and to theoretically make your multithreading easier too - in both cases by putting the data in one place (ie, removing state elsewhere), and making it easier to control when and how data gets modified