[HN Gopher] Component Graph System (2017)
___________________________________________________________________
Component Graph System (2017)
Author : Kinrany
Score : 78 points
Date : 2021-07-16 12:52 UTC (10 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| syntaxfree wrote:
| I don't know what ECS is. You should define the acronym...
| anentropic wrote:
| Entity Component System
|
| commonly used in game programming
| mrspeaker wrote:
| "Entity Component Systems" are common in game engine
| architecture, and there are a lot of variations on them - but
| they are a high-level architecture for making modular behavior
| in games. Generally they were thought of as "better than Object
| Oriented, because they very very heavily favor composition over
| inheritance."
|
| The idea is that everything in your game - like Players, NPCs,
| Bullets - are _Entities_. Entities are simply an ID. That 's
| their only property. Nothing else.
|
| But there are _Components_ - they have the data. For example,
| you might have a `PositionComponent` that has an `X Position`
| and `Y position` property. And maybe a `MassComponent` that has
| a property `Mass`. Somewhere in the framework (like a database
| table), a given Component will be related to a given Entity ID.
| The Entity therefore becomes a "bag of Components" through the
| relations.
|
| Finally there are _Systems_. They do stuff with the data. One
| system might be `GravitySystem`. It doesn 't care directly
| about `Entity`s, but can query the relations. It might ask for
| anything that has BOTH a `PositionComponent` and a
| `MassComponent` (it doesn't know which Entity it is for - it
| only gets the Components). It takes any `PositionComponent`s it
| gets and applies gravity: `component.y += gravity`.
|
| The effect is that you can mix and match Components in weird
| and wonderful ways without having to hard-code behavior and
| rules for certain entities. You can obviously achieve this with
| other architectures too - but that's the primary goal of this
| one.
| thom wrote:
| Correct me if I'm wrong, but isn't one of the other
| motivations to store your data in CPU/memory management
| friendly ways? It's not purely about developer ergonomics.
| mrspeaker wrote:
| I think originally it was primarily about developer
| ergonomics - here's the first thing I ever read about them
| in 2007 where they tested it on Tony Hawk Pro Skater
| (http://cowboyprogramming.com/2007/01/05/evolve-your-
| heirachy...). The CPU/memory management has been an on-
| going discussion ever since! Being able to process domains
| as flat arrays helps with cache misses - but there is a lot
| of other overhead, depending on how you designed
| everything.
|
| Making it performant was one of the big problems initially,
| and it seems like the `Component Graph System` this thread
| is about trying to answer "how do systems efficiently
| process components?"... But I don't really get how it
| answers that actually.
| jmiskovic wrote:
| My reading of CGS is that it also means to boost
| ergonomics. Without "entity" concept of ECS triad, it
| should be 33% easier to understand how everything works,
| and what pitfalls exist.
| gmueckl wrote:
| As far as I understand it this is about the ECS
| equivalent of an INNER JOIN, that is, some variation on
| "iterate over all entities that possess instances of
| component A and B". Iterating over single component types
| in a system is trivial if they are separated into pools
| by types. When you have a system requiring more than one
| component, it isn't that easy to do better than iterating
| over all entities and checking whether they possess each
| required component. You can decide to maintain back
| references from components to their entities, but this
| means that you incur that management overhead pretty much
| globally. This essay says that doing away with entities
| altogether and just keeping direct links between your
| components is better. And it probably is when it comes to
| handling related components.
|
| However, I believe (without having actually tried it)
| that this proposal has its own drawbacks. it's harder to
| thoroughly clean up all components that form a single
| entity. My suspicion is that it's easier to produce bugs
| like keeping e.g. a stray collision shape or sound source
| around while the other parts of an entity are removed.
| All you need for that to happen is an incomplete graph
| traversal.
| Kinrany wrote:
| I think CGS boils down to smart links between components,
| which may include SQL-like automatic checks: deleting
| components that refer to deleted components or components
| owned by the deleted component.
| m12k wrote:
| Correct, you basically invert the typical component/object
| oriented approach, so each property relating to some
| Component isn't stored in memory alongside the game object
| it relates to (causing the values relating to e.g. physics
| to be scattered around memory) but is instead stored in an
| array (indexed by an id - the Entity id) with all the other
| values for this component type, making it much more cache
| efficient when a System (e.g. particle system, physics
| system) needs to perform updates on all components of a
| given type (which typically happens once per run loop
| iteration in a game engine). See also
| https://en.wikipedia.org/wiki/AoS_and_SoA
| jcelerier wrote:
| there are two distinct definitions of ECS, the first one given
| in https://news.ycombinator.com/item?id=27856030 is the
| "(entity-component-system) architecture" where there are
| entities, components, and systems, as distinct objects in your
| software. The second is "(entity-component) system" or "entity-
| component architecture" where the behaviour goes inside
| components (for instance, Unity3D gameobjects with their
| components).
| nodejs_rulez_1 wrote:
| It's good old procedural programming. Systems (procedures) are
| mutating state (components) grouped by a common ID (entity).
| leoc wrote:
| I'm no expert on any of this but that doesn't seem right; is
| it? IIUC, most procedural programming is nearly as wedded to
| the "one entity, one master data structure, one address in
| memory" frame of mind as OO is. (And the same is true of most
| functional programming, come to that.)
| bordercases wrote:
| You could do it functionally, i.e. the systems are all
| reducers on partial states of the world.
| m0llusk wrote:
| > CGS is more flexible thus targeting a wider use case than
| generic ECS: it's a hierarchy of components instead of the flat
| entity-component duality ...
|
| Wasn't the flatness of ECS supposed to be a useful feature that
| simplifies things like iteration and searches?
| gameman144 wrote:
| > And we decided that each system processes relevant entity data
| by iterating through entities first. Now we have another problem
| - growing the number of entities slows down every system, even
| the ones that are not related...
|
| Call me out if I'm wrong, but I don't know of any high-
| performance ECS framework that actually does this. Most
| frameworks maintain sorted collections of components with no
| gaps. For instance, if I want all entries with X,Y,Z, then I
| iterate those three arrays starting at their X,Y, Z section, and
| the order of components in that section of the arrays matches
| exactly (meaning we can just iterate through them all).
|
| This library seems like a really neat concept, but I think the
| ECS concepts that it's critiquing aren't actually used in many
| production-quality frameworks. Call me out if I'm just missing
| context here.
|
| Also, I'd love more details on how CGS is able to always iterate
| on flat vectors with no gaps. The only way I've seen to
| accomplish this is to do a decent amount of work curating
| components into multiple orderings, so if CGS is avoiding that, I
| am equal parts skeptical and _very very excited_ (since that
| would be super useful!)
| jayd16 wrote:
| Agree. This presents a bit of a strawman of ECS. No reason
| components can't reference others or Systems can keep look up
| tables in ECS.
| hrh wrote:
| What libraries/frameworks are state of the art?
| xaedes wrote:
| There is EnTT, an ECS as C++ library:
|
| EnTT is a header-only, tiny and easy to use library for game
| programming and much more written in modern C++. Among
| others, it's used in Minecraft by Mojang, ...
|
| https://github.com/skypjack/entt
| gameman144 wrote:
| EnTT is the one I was thinking of -- I'd _highly_ recommend
| looking into its implementation, as it 's both very well-
| documented and readable, and blazing fast.
|
| The fact that even this caliber of implementation has to
| handle multi-component cases by doing _super_ careful
| curation of components is what makes me skeptical that CGS
| would be able to solve this situation more efficiently
| /easily. I would be _very_ happy to be proven wrong here,
| though.
| jayd16 wrote:
| Unity's implementation is well documented and handles this.
| [deleted]
| enbugger wrote:
| >Performance-wise, some overhead may come from reference-counting
| the components
|
| Well, that's what ECS gets rid of and mainly benefits from that.
| Doesn't returning it back mean going back to OOP? What's the
| point then?
| Kinrany wrote:
| I believe the main benefit is a constrained form of dynamic
| typing.
|
| You don't want to lose compile-time type checking and
| intellisense, and you want to keep most of the performance
| benefits. But you want to be able to add data types without
| recompiling.
| Kinrany wrote:
| > There is no ~~spoon~~ entity. What was our entity like? A
| structure with pointers (IDs) to different components. Now, let's
| treat it as just another component! The whole ECS becomes
| simpler.
|
| To me this is the most interesting part. Game logic needs
| components with references to other entities and components
| anyway. And if there's _some_ way of identifying components, you
| no longer need entities to have identities.
|
| And you can still apply all the optimizations as long as you
| treat some components as "entity" components. But only when you
| want to exchange simplicity for performance.
___________________________________________________________________
(page generated 2021-07-16 23:02 UTC)