[HN Gopher] EnTT: Gaming meets modern C++ 3.9 (ECS library and m...
___________________________________________________________________
EnTT: Gaming meets modern C++ 3.9 (ECS library and much more)
Author : tridentboy
Score : 37 points
Date : 2021-12-21 17:21 UTC (5 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| ncake wrote:
| Unpopular 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.
| jayd16 wrote:
| In some ways ECS could be considered stateless, as the entity
| holds the game state as raw data, while the system operates on
| that data without holding a state of its own.
|
| How would you implement ECS, a system for tracking the state of
| game entities, in a stateless manner? Can you expand on that?
| ncake wrote:
| I'll try to explain what I mean. Suppose you want an in game
| character to change the displayed weapon in their inventory.
|
| Stateful way: your Inventory Manager component iterates
| through its private array of item entities to mark their
| model components as shown or hidden, then calls the
| dependency injected character's avatar component to update
| its animation state.
|
| Stateless way: you flip an integer in character's struct, and
| the rendering function does something different.
| BoorishBears wrote:
| I 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
| umvi wrote:
| What are compile times like? I'm always suspicious that "header
| only" libraries translate to excruciating compile times
| tridentboy wrote:
| A great FAQ on ECS is available here:
|
| https://github.com/SanderMertens/ecs-faq#what-is-ecs
| chrsig wrote:
| Something 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 wrote:
| I 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 wrote:
| > 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 wrote:
| >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 wrote:
| That'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)
| rubyskills wrote:
| Completely agree on the different design choices. Curious
| if the analogy of how different gui packages work might
| have some parallels. FLTK uses a "retained mode" paradigm
| where IMGUI uses immediate mode. More idle musings..
| k__ wrote:
| I had the impression, a goal of ECS was parallel and not
| sequencial processing.
| jayd16 wrote:
| Strict ordering and sequential layout allows you to
| efficiently split the work and process these systems in
| parallel (or with SIMD).
| gravypod wrote:
| ECS 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 wrote:
| Some compilers also use the ECS "pattern" quite heavily.
|
| Case in point: rustc:
|
| https://www.youtube.com/watch?v=N6b44kMS6OM&t=1263s
| jayd16 wrote:
| I 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 wrote:
| It's interesting to note that Minecraft uses this library.
|
| https://www.minecraft.net/en-us/attribution
___________________________________________________________________
(page generated 2021-12-21 23:01 UTC)