6 ms·
EnTT: Gaming meets modern C++ 3.9 (ECS library and much more)
- tridentboy 5y agoA great FAQ on ECS is available here: https://github.com/SanderMertens/ecs-faq#what-is-ecs https://github.com/SanderMertens/ecs-faq#what-is-ecs
- chrsig 5y agoSomething I've had trouble wrapping my head around with ECS -- how does it fundamentally differ from an in memory relational database? They describe a "sparse set" designed for sequential identifiers -- how does that compare to something like an in memory b+ tree?
- looki 5y agoI don't think there is a fundamental difference. ECS is the application of relational databases in a dynamic real-time context with relatively modest amounts of data, but lots of sequential processing. Sparse sets work well in this context, but they are ultimately an implementation detail. There are other ECS implementations that don't make use of it but can still deal with large throughput.
- chrsig 5y ago> ECS is the application of relational databases in a dynamic real-time context with relatively modest amounts of data, but lots of sequential processing. This is probably the best explanation that I can imagine -- that they're not fundamentally different, just that ECS tends to make a sufficiently different set of design choices that it warrants some of it's own terminology. I can't help but wonder what a more generalized take on ECS might look like, if it were to continue drawing from relational databases. For example, support for multiple indices to assist with different query patterns. Or triggers to abstract away cascading updates. Or perhaps materialized views to keep query patterns simple. I've never had the opportunity to use an ECS system, especially in a performance sensitive context, so I don't have a good sense of where any pain points are in practice versus what my imagination can conjure up. I also wonder what it might look like to use SQL to generate an optimal C++ representation while keeping the data definition high level. Just idle musings - maybe one day I'll take the time to experiment.
- jayd16 5y ago>Or triggers to abstract away cascading updates. Triggers might be counter productive. Games usually have a fundamental concept of a game loop. Changes can be processed in the loop and side effects can be processed in the following iteration. Triggers would cause this processing to be unpredictable (or at least harder to predict). ECS provides a clean way to define the order in which systems are processed each loop. Triggers might disrupt this ordering. Maybe that's still desired, maybe not. I just thought it would be interesting to mention.
- chrsig 5y agoThat's a great insight. I wonder if it'd be practical to defer them until after the causal operation was complete say translating all positions, then calling all of the triggers for the positions component. that'd keep everything in tight single purpose loops and preserve cache lines. fair enough that it'd probably make execution order harder to predict, but also in theory it would be in the realm of possibility to generate a plan and print out the order that things would happen in. (I'm not positing that this is actually worth doing or that the pros out weigh the cons -- just toying with the idea)
- meheleventyone 5y agoA lot of game engines have the concept of messaging that tends to happen synchronously or with a delayed dispatch step which sounds very similar to triggers. The latter comes with a verification cost because the message might not be valid anymore. The thing with the actual gameplay layer is your often processing mainly heterogeneous elements rather than homogeneous so all the worry and focus on cache is largely academic for most kinds of game.
- k__ 5y agoI had the impression, a goal of ECS was parallel and not sequencial processing.
- jayd16 5y ago
- gravypod 5y agoECS is less about access patterns (relationships and queries) and more about efficient storage. Games care about page faults still so making your tight loop execute quickly on many smaller pieces of data and "do the right thing" is a win. Also, from an architectural perspective it's easier to write abstract code like `Health.value -= 10` instead of PlayerHealth.value -= 10`. By coding against a single components interface you can get consistent behavior across all entities with that component. You could also do this with inheritance but that becomes complex and (the real killer) very slow. jblow has some rants about this in the witness.
- fault1 5y agoSome compilers also use the ECS "pattern" quite heavily. Case in point: rustc: https://www.youtube.com/watch?v=N6b44kMS6OM&t=1263s https://www.youtube.com/watch?v=N6b44kMS6OM&t=1263s
- jayd16 5y agoI don't think the entities/system are really that relational. Data is not denormalized in the same way and joins don't really exist. Indices are an after thought. Full sequential scans are the main access pattern. But, it's easy to think of data for a component system as a table where each row is associated with an entity so I can see why you draw the similarity.
- devortel 5y agoIt's interesting to note that Minecraft uses this library. https://www.minecraft.net/en-us/attribution https://www.minecraft.net/en-us/attribution
- umvi 5y agoWhat are compile times like? I'm always suspicious that "header only" libraries translate to excruciating compile times
- dymk 5y agoI'm not familiar with _this_ exact ECS library, but another header-only ECS library with comparable functionality is flecs [1] and it compiles so fast I thought I misconfigured it. Literally could not even measure the compile time increase. [1] - https://flecs.docsforge.com/ https://flecs.docsforge.com/
- ncake 5y agoUnpopular opinion, but I personally think ECS has no place in C/C++ game dev. Every supposed advantage is either curbed by limitations of the language (e.g. serialization) or can be implemented more logically in a stateless manner.
- BoorishBears 5y agoI can't even imagine game dev without ECS. There's more performant architectures but it's such a useful mental model for the type of rapid iteration games need that so many people are willing to put up with the drawbacks
- verdagon 5y agoWhat are some of the more performant architectures?
- BoorishBears 5y agoData oriented instead of object oriented: https://gamedevelopment.tutsplus.com/articles/what-is-data-oriented-game-engine-design--cms-21052 https://gamedevelopment.tutsplus.com/articles/what-is-data-o... Instead of treating each object as a collection of components, you can operate on bags of components So say in you're modeling space invaders: every frame: for enemy in enemies enemy.transform.y += 10 The CPU is hopping to a random memory address where your "transform" component is located before modifying it, over and over. Data oriented would be something like: each frame: for transform in transforms if transform is enemy transform.y += 10 if transform is player transform += input So you get cache locality as you're running through your transforms. Now imagine if instead of space invaders we're trying to model say blades of grass. Suddenly we go from a very cache unfriendly method to something that's cache friendly, branch prediction friendly, and easy to parallelize. If you want to experiment with it Unity has some great examples under their new DOTS system https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/ECSSamples/Assets/HelloCube/1.%20ForEach https://github.com/Unity-Technologies/EntityComponentSystemS... APIs can make data oriented more ergonomic than my contrived example implies, but it's still not nearly as intuitive as ECS imo. To me data oriented subsystems are fine, but not as a core concept for your game's architecture.