[HN Gopher] Why isn't Godot an ECS-based game engine?
___________________________________________________________________
Why isn't Godot an ECS-based game engine?
Author : nafey
Score : 212 points
Date : 2021-02-27 11:30 UTC (11 hours ago)
(HTM) web link (godotengine.org)
(TXT) w3m dump (godotengine.org)
| samwestdev wrote:
| I don't really understand what's the advantage of ECS compared to
| OOP composition. Anyone here can shed some light on the matter?
| hertzrat wrote:
| Basically, 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
| EamonnMR wrote:
| Here'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
|
| Godot with networking: https://github.com/EamonnMR/mpevmvp
| DominikD wrote:
| Short story: data is aligned in a way that favors batch
| processing. Less branching, great setup for SIMD or GPU
| processing.
| gurkendoktor wrote:
| I'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
| /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 wrote:
| > 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
|
| But that game shipped and it worked, and that's really all
| that matters.
| gurkendoktor wrote:
| > 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 wrote:
| The 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.
| [deleted]
| [deleted]
| sitkack wrote:
| It also translates to a relational model, selection, join and
| projection.
| willvarfar wrote:
| I first met ECS when modding an RTS called Tiberian Sun. The
| units were all defined in ini files and you specified the
| components for each unit eg the difference between a building and
| a moving piece was whether there was a movement component etc.
| And a small but vibrant modding community grew up around it.
|
| Everything was dynamic, read from data definitions when the game
| loaded.
|
| One downside to godot's inheritance is everything is set up in
| code and decided at compile time instead?
| benjaminjackman wrote:
| > One downside to godot's inheritance is everything is set up
| in code and decided at compile time instead?
|
| That's not really the case because Godot can load scenes at
| runtime. The scene format itself (.tscn files) is text based[1]
| (which is also nice for version control) and could be edited by
| hand, then loaded into the game at runtime. Though since the
| Godot editor is open source and totally free it would probably
| be better just to ship that with the game. It's also really
| easy to extend so custom game centric plugins that modify the
| editor itself are also easy to write.
|
| 1: Here is a sample scene file, just to give a sense of the
| format: $ cat
| enemies/bandit/BanditSpread.tscn [gd_scene
| load_steps=2 format=2] [ext_resource
| path="res://enemies/bandit/BanditBase.tscn" type="PackedScene"
| id=1] [node name="BasicBandit"
| instance=ExtResource( 1 )] fire_period = 0.85
| [node name="VK-001" parent="Sprite" index="6"] visible
| = true [node name="LG-Anger" parent="Sprite"
| index="8"] modulate = Color( 1, 3.1875, 6, 1 )
| [node name="ProjectileWeapon" parent="Hardpoints" index="0"]
| projectile_spread_degrees = 60.0
| projectile_variance_degrees = 0.0 num_projectiles_min =
| 6 num_projectiles_max = 6
| SigmundA wrote:
| Many engines have scripting languages allowing modding using
| full turing complete languages rather config files LUA is a
| common one in games.
|
| Its kinda like the config file vs code as config debate. If I
| where modding something I would rather have a full programming
| language than just a config file, but the config file does make
| it easy to do simpler things without breaking stuff, the more
| complex the config becomes the closer to a full blown DSL it is
| and you might as well just use a mature scripting language
| instead.
| jacques_chester wrote:
| A nitpick: "Lua". It is not an acronym.
| RMPR wrote:
| > Its kinda like the config file vs code as config debate
|
| I had trouble parsing this because I was reading "vs code" as
| visual studio code.
|
| > If I where modding something I would rather have a full
| programming language than just a config file, but the config
| file does make it easy to do simpler things without breaking
| stuff, the more complex the config becomes the closer to a
| full blown DSL it is and you might as well just use a mature
| scripting language instead.
|
| I think using a mature scripting language is just a matter of
| transferable skills. People may be more reluctant to learn
| yet another language just to mod your engine. Especially if
| it's a one-time thing.
| dagmx wrote:
| To note though is that those config files aren't meant for
| modding. They're meant as easy ways for the gameplay
| designers themselves to tweak things without needing to
| rebuild the whole game each time.
|
| They just usually ship as side effects of that process,
| because no body really cares that much for single player
| games.
| SigmundA wrote:
| Usually scripting engines in games are there for the exact
| same reasons, moddability again being a side effect.
| CyberDildonics wrote:
| Are you asking if that is a downside? Yes, it is a significant
| downside since fundamental parts of a game would need
| recompilation which means slow iteration on things that need to
| be iterated on a lot.
| EamonnMR wrote:
| Tiberian Sun's technology is really unique and cool and I wish
| they'd open source it so I can see how they did everything. The
| 2d lighting really have it a distinct atmosphere.
| sitkack wrote:
| Approach it like a mid 90s demo coder. Alphas, light maps,
| shadow casting.
|
| The coolest 80s trick was rotating the palette to get moving
| water.
| Vaskivo wrote:
| While ECS means you're using a "data driven" approach, you can
| have a "data driven" approach without having to use ECS.
|
| It's all about having configuration data separate to the logic.
| And use this data to setup and build the game elements.
|
| Here's a couple of videos I created:
|
| How to start with Data Driven Development in Godot:
| https://www.youtube.com/watch?v=ZG__fXSp74c
|
| What I can do with it in my game, One Way Dungeon:
| https://www.youtube.com/watch?v=PqZwKahZ3cU
| Jasper_ wrote:
| ECS is commonly described as "data-oriented", not "data-
| driven". It's confusing, yes, but the have separate and
| unrelated meanings in the game development space.
|
| The former is a methodology for building engine systems that
| are cache-friendly, the latter talks about workflows that are
| more flexible to artists and developers.
|
| You can use ECS without "being data-driven", and you can use
| data-driven workflows without ECS.
| Vaskivo wrote:
| > You can use ECS without "being data-driven", and you can
| use data-driven workflows without ECS.
|
| True, I've read about ECS being used for one or both of
| those purposes.
|
| My first contact was ECS was as a composability pattern.
| So, in a "high level" purpose, as an alternative to
| inheritance. It was also described as "Game Object - Game
| component" pattern.
|
| See http://gameprogrammingpatterns.com/component.html,
| specially the sidenote in
| http://gameprogrammingpatterns.com/component.html#no-
| bj%C3%B....
|
| There's the "performance" ECS, where it tackles data
| locality.
|
| And the "game element definition and configuration" ECS,
| where it solves a high level problem of building game
| elements. On the "game developer" level, Unity works like
| this.
| WhatIsDukkha wrote:
| If you are making a game, instead of a game engine, you can have
| your cake and eat it too -
|
| https://godot-rust.github.io/
|
| Allows you to pair Rust with Godot comfortably via gdnative.
|
| Then use one of the good ECS systems in Rust like -
|
| https://github.com/amethyst/specs
|
| or (archetype style ECS)
|
| https://github.com/amethyst/legion
|
| To get spun up on ECS in Rust I suggest -
|
| http://bfnightly.bracketproductions.com/rustbook/chapter_0.h...
|
| This won't get you a godot project but will get you a basic
| concepted game you can then port into godot-rust.
| fartcannon wrote:
| Good news, there's an ECS plugin written by a brilliant Swiss (I
| believe) programmer Andrea Cantania. Check it out:
| https://m.youtube.com/watch?v=zxW_xxDuVC0
| TillE wrote:
| ECS at the game engine level has never been particularly
| interesting to me, but it is a good way to structure complex game
| logic. This shouldn't be tightly coupled with the game engine
| anyway, so I don't find the different architectures awkward.
| Godot's node-based structure makes a ton of sense for what it
| does.
| jeremyjh wrote:
| The main reason ECS became popular is because of the
| performance benefits, and the tasks that get the most benefit
| from that are the ones core to the engine such as the rendering
| pipeline and physics engine. Personally I think Godot's system
| is much easier for the end user than an ECS. I am not much of a
| fan of OOP (I use a functional language at work) but I do think
| OOP is a good fit for games and UIs.
| Jare wrote:
| I'm a bit confused between there's a hugely popular place between
| inheritance-based entities and ECS (Entity-Component-System),
| which is what you could call a "Entity-Component system) (notice
| spelling) or perhaps a Component-based entity composition system.
|
| Inheritance based: you derive Vechicle, then derive Tank, Car,
| etc. This was most used from 95 to 2005 as teams moved to C++.
|
| Component based: you create a TreadsMovement component, a Turret
| component, a Wheels component, a Chassis component, etc. Each
| contains the data and behaviour for what they represent. You
| compose them together at runtime inside Entity objects to create
| tanks, cars, etc at runtime. Popularized by Scott Bilas' engine
| for Dungeon Siege. This is classic Unity. Most used from 2005 to
| today.
|
| ECS: data-oriented where components are data-only, and behaviour
| logic lives in systems that act on a set of instances that
| contain certain subset of components. Entities are just ids for
| the set of components that make up the data for a given active
| object in the game. Entities and Components are best understood
| as a database which systems query and select from.
|
| I don't know enough Godot to be sure if it's Inheritance or
| Component, but I know I left "classic" inheritance based behind
| almost 20 years ago and would never want to go back. Even back in
| 1997, the Commandos 1 engine was already half Component-based
| (but it took us a while to refine the Component model and
| intercommunication).
| hertzrat wrote:
| Not about ECS, but speaking of components: I'm developing an
| unreal engine game and component based programming has been a
| dream. You end up with the opportunity to create so many pieces
| of code that are able to be dumb and that don't need to know
| about the rest of the system. Then you add come control code
| that is also as dumb and blind (in a good, decoupled sense) as
| possible and the whole application comes together in 1/10th the
| effort of a more coupled and fragile inheritance heavy
| approach. You can actually change things without breaking
| everything and you can actually understand what something does
| by reading 1-2 source files instead of 40.
| apineda wrote:
| I'm curious about emergent problems that are difficult to
| diagnose with many systems operating seemingly independently.
| Systems interacting in odd ways, and ordering of systems
| (dependency ie one system MUST run before another). Do these
| come up?
| remram wrote:
| I think Godot is both. A lot of built-in nodes are meant to be
| extended (like KinematicBody) and a lot of them provide
| features via adding components (like RayCast or Area or Timer
| or AudioStreamPlayer).
| an_opabinia wrote:
| > I'm a bit confused between there's a hugely popular place
| between...
|
| Godot is a Unity clone. Unity has copied a lot of things,
| including Flash (and therefore Shockwave), where this "attach
| scripts to stuff" architecture actually came from.
| meheleventyone wrote:
| Godot is node based so you compose an Entity out of nodes. It's
| a slightly more flexible version of an Entity Component model.
| bogwog wrote:
| I know what you mean, and that confusion is 100% Unity's fault,
| because they call their data-oriented entity system "ECS".
|
| Back in the day, composition was referred to as "component-
| based entity systems", which makes perfect sense.
|
| But then Unity came in and called their data-oriented one
| "entity component system" for reasons I will never understand.
| Why not just call it "data-oriented entity system" or something
| like that?
|
| So nowadays when you hear "ECS", it's not clear what people are
| talking about anymore.
| CreepGin wrote:
| I'm not sure Unity is at fault here. Most people in the game
| dev business knew about what ECS is (Entities + Components +
| Systems) long before Unite Austin 2017 (when Unity first
| announced their upcoming entities package).
| Jare wrote:
| It would be fair to attribute the ECS naming (specifically,
| making "Systems" an integral concept to the, ahem, system)
| to this from 2007:
| http://t-machine.org/index.php/2007/11/11/entity-systems-
| are...
| Athos_vk wrote:
| I would say it is 100% not Unity's fault. As someone else
| posted, there's a t-machine blog posted and that entire blog
| has been filled with ECS with that specific term for years.
| But aside from that it has been a heavily discussed thing for
| many years in the gamedev scene. There's a wikipedia page on
| it, showing a bit of history from well before 2017, but you
| will find most on it on gamedev.stackexchange and
| gamedev.net. It probably predates the start of Unity in its
| entirety.
|
| Also, to be fair, they really do refer to it as DOTS -> Data
| Oriented Technology Stack (granted, it includes more than
| just that), but I'm not sure if and when they changed that.
| Their community just seems to keep calling it ECS regardless.
| w_t_payne wrote:
| DOTS is not ECS. "Unity Classic" is ECS. DOTS is a more
| cache-efficient architecture designed to support larger
| numbers of entities.
| djur wrote:
| The confusion is worsened by people interpreting it as "[an]
| (entity component) system" or "[an] ((entity) (component))
| system", when it's actually "[an] Entity-component-system
| [architecture]". That is, it's not a system of entities and
| components, it's an architecture comprising entities,
| components, and systems.
| beaconstudios wrote:
| it's not surprising given that "entity component system" is
| synonymous with "thing behaviour environment". It's using
| the most meaningless generic terms possible. It's like when
| companies use a tagline like "using innovative practices to
| deliver results for our clients".
| jasonwatkinspdx wrote:
| Cosigned. I did level design on a game in the Unreal 1 era. The
| cosmic inheritance hierarchy was a regular annoyance.
| vvanders wrote:
| Yup, this is spot on(with a mix for some systems that did a bit
| of data only components for the real perf critical stuff
| together with the more business logic components).
|
| Your dates are right too, at least from my experience during
| '04~'12. Being on the tail end of that inheritance based
| approach was brutal and was so happy to leave it behind.
| georgeecollins wrote:
| I think it is more inheritance than ECS, but not religiously
| OOP.
|
| Having used Unity and Godot, I really like the architecture of
| Godot. But Godot is not nearly as fully functioned (yet).
| Waterluvian wrote:
| As a beginner not thinking too much about performance, ECS is
| beautifully elegant and easy to reason about.
|
| However I found it nearly impossible to integrate into
| libraries/engines that aren't made for it.
|
| I really wanted to use React for my complex RPG UI and PhaserJS
| or Pixi for I/O, but the state management paradigms just didn't
| work together (for me at least).
| mmis1000 wrote:
| If your problem is "you can't mutate state of a react app
| easily because they decides to make their own state management
| system that can't mutate by part out of the app directly".
| Probably you can give vue a try. It is designed to work like a
| plain object. And mutate the data belongs to it from outside of
| a vue app also reflect to the view instantly. (Just alter the
| property of the vue component, that's all you need to change it
| from outside)
| ralusek wrote:
| Do you mind elaborating a bit? My understanding is that ECS
| would be providing data in a way not unlike most web
| applications do, such that building a React UI over that data
| model should be quite easy.
| monocasa wrote:
| One of the nice things about ECS is how easy it is to integrate
| into an existing structure. In the engine case you just make
| your existing object hierarchy one component type, and whatever
| subsystem you're making ECS into its own component. At a
| library level you just wrap that library's per object state in
| its own component.
|
| What issues did you have?
| EamonnMR wrote:
| I feel your pain. I wanted to combine AngularJS and BabylonJS
| for a GUI heavy RPG but it proved impractical.
| cztomsik wrote:
| TLDR the article says that nodes are just a "frontend" and the
| real work is done by backend which is data-oriented anyway.
|
| tensorflow has python frontend and that is "slow" too, yet it
| doesn't matter because most of the work is done in C++ and python
| just compiles that graph to something lower-level
| Kiro wrote:
| I'm a novice JavaScript game developer and I'm currently using
| OOP for my entities. E.g. each NPC is an object with an update
| method inherited from a base class that gets called every tick.
| What benefit would ECS actually give me? Isn't the NPC data still
| just an object but instead of using a shared prototype update
| method on the object it would be a separate component function?
| What is the actual difference?
| Tyr42 wrote:
| Hmm, if you only have one system, then yes, those are the same.
|
| But if you have multiple systems (say collision detection,
| physics, damage/health, control(ai or player)) you can then
| build things up lego brick style.
|
| For example, a basic wall will just participate in the
| collision detection system and nothing else, but now it's easy
| to add in breakable walls by giving them a hp value and defence
| value for the damage system.
|
| Does that help?
| Kiro wrote:
| Yes, thank you! It certainly seems like a good and flexible
| way of structuring your game but I still don't understand
| where the performance benefits the article speaks of come
| from.
| bogdanoff_2 wrote:
| Computers are much faster when they operate on things that
| are laid-out contiguously in memory, instead of jumping
| around following pointers.
|
| You need to use a programming language like C++ to be able
| to this. In JavaScript, all objects are pointers, so
| there's no way to do this.
|
| Google "data-oriented design" to learn more.
| fhools wrote:
| My understanding is the performance benefits come from the
| locality of the data. Usually in an array for each
| component. Whereas in a OOP system, your objects would be
| scattered throughout the heap.
| hypertele-Xii wrote:
| JavaScript gains no performance benefit from ECS because JS
| arrays are dynamic and sparse. The performance benefit
| comes from dense, contiguous data (structures of arrays,
| instead of arrays of structures) in languages that allow
| that.
|
| Consider the difference between: object 1
| property A property B object 2
| property A property B
|
| and: property A of object 1 property
| A of object 2 property B of object 1 property B
| of object 2
|
| If you need the property A for all objects, in the first
| example we have to jump over the property Bs. In the second
| example all property As are next to each other.
| turndown wrote:
| In this context, what do you mean by sparse? Simply that
| similar data is not packed together?
| Jasper_ wrote:
| The performance benefits comes from the "Systems", which is
| very infrequently talked about. Most uses of the term "ECS"
| are actually "Entity-Component" (EC), which has been around
| for a long, long time.
|
| The goal is to have "Systems" which operate on
| "Components", and "Entities" are completely out of the
| picture. The idea behind Systems is that they operate on a
| continuous block of memory: for (auto
| &damagable : damagables) { damagable.hp -=
| damagable.damage_this_frame;
| damagable.damage_this_frame = 0; if
| (damagable.hp <= 0) damagable.dead = true;
| } for (auto &movable : movables) {
| movable.position += movable.velocity_this_frame;
| movable.velocity_this_frame = vec3(0); }
|
| Simple toy example, but by splitting up the data based on
| what acts on them, we have two loops that are very cache-
| friendly. Each of those two loops is called a "System".
|
| The System is the _key_ part of ECS that makes this work.
| Just splitting off components and still using a virtual
| update function isn 't going to get you any performance
| benefits, but it's still most of what I see when I see
| "ECS" talked about online. In fact, making components
| contiguous while leaving your updates to be whole-entity-
| at-a-time is going to make your cache coherency _worse_!
|
| Entities, then, are actually not "container objects", but
| often just uint32's -- _all_ of their data is inside the
| Components. The database analogy: The Entity is just a
| primary key tying together a database of tables
| (Components). The tables can be acted on, sometimes in
| parallel, by Systems (UPDATE queries), regardless of the
| originating Entity.
|
| Actual Systems in practice have dependency chains and other
| things, to make sure that updates are done in the right
| order, scheduling mechanisms, and ways to make cross-
| component talking safe, and performant.
|
| Unity's GameObject is not ECS, despite it being an "Entity-
| Component" model. Their new DOTS stack _is_ , but it has
| tradeoffs for that performance.
|
| Put simply, "EC" is a way of structuring your data classes
| to not rely on inheritance, "ECS" is a way of structuring
| your algorithms that act on those data classes to not
| require virtual methods.
|
| The rest of this thread has similar misconceptions, and
| even the original post makes some errors too. Sadly, this
| misinformation is widespread, and it's not really
| correctable at this point. Oh well.
| HelloNurse wrote:
| Entities aren't out of the picture: those
| "damagable.damage_this_frame" and
| "movable.velocity_this_frame" attributes need to be
| assigned in a previous step, with lookups from component
| to entity and from entity to component. For example, a
| collision detection and handling step could iterate over
| all physical objects and, in case they collide, assign
| damage to the damageable component of the same entity
| and/or alter velocity of the movable component of the
| same entity (if appropriate).
| Pulcinella wrote:
| Yeah there is definitely some mental namespace pollution
| between EC and ECS where, as you described, you have "EC
| systems" (Entity-Component systems) and "ECS systems"
| (uhh "Entity-Component-System systems").
|
| _Actual Systems in practice have dependency chains and
| other things, to make sure that updates are done in the
| right order, scheduling mechanisms, and ways to make
| cross-component talking safe, and performant._
|
| Do you know if there is a formal term for this kind of
| dependency chain and update order scheduling is called?
| I'm interested in ways this kind of checking can be done
| at compile time, or at least a run time guarantee that
| things won't be done in the wrong order and fails to
| compile/generates run time errors when you have a cyclic
| dependency rather than having to map that all out by
| hand.
| Twisol wrote:
| > Do you know if there is a formal term for this kind of
| dependency chain and update order scheduling is called?
|
| ECS might make this an independent-enough concern that
| techniques from build systems would be applicable. See
| "Build systems a la carte" [0], for instance, which
| captures the (an?) essence of build systems as managing a
| graph of dependent dataflow processes. (In ECS, the
| dataflow would be mediated by the database of component
| tables, just as in Make the dataflow is mediated by the
| filesystem.)
|
| [0] https://www.microsoft.com/en-
| us/research/publication/build-s...
| cma wrote:
| To go along with the parallel thing, you can imagine both
| of those loops are much easier to vectorize too compared
| to if each a was acting on objects with the damage stuff
| and position stuff combined in one structure.
| jbluepolarbear wrote:
| I don't like ECS because it always conflates to using components
| as messages for systems that have nothing to do with Entities. I
| much prefer using a message system. A message system can quickly
| abstract the engines view from the core logic of the game and
| allow for the messages to be dispatched across network making
| networked games easier to work with.
| drawkbox wrote:
| I agree and like your style.
|
| Messaging is ideal for decoupling, sending/receiving data and
| it makes networking parts of the game much easier.
|
| Every game engine or system I use I set it up this way. I
| always make my components or entities data backed so when
| people say you can't have data-oriented in GameComponent
| systems it seems they haven't done much game development. I
| usually have most of it in JSON and in previous engines INI was
| popular (Unreal still uses this for some and lots of custom
| engines). I have always separated data from the objects, lots
| of people do not and that is why this is a major debate along
| with all the talk around it due to Unity adding their ECS. Data
| should always be separate from code and hopefully merged at
| runtime.
|
| The benefit of ECS is performance alone and usually only really
| needed for high performance real-time or physics heavy games
| for parallel performance and essentially pre-optimized for
| batched mutations or changes, everything else can be done
| across the same from messaging to data backed
| entities/objects/components and more.
|
| I do wish engines were better as abstracting these elements
| away. Lots of the systems start leaking into the engine which
| is supposed to abstract these elements away in a good
| pluggable/versioned/atomic game engine.
|
| Like what Garry said about Unity [1], too many things are
| leaking up to the game developer creating all these debates and
| issues and incompatibilities. The fact this isn't just a switch
| or setting to switch from GameComponent to ECS is a problem.
| Same with incompatible renderers and more, those should be
| wrapped and pluggable with the same surface level method
| signatures and objects. Underneath is where all the tech needs
| to go. Leaky abstractions are a problem across the software
| world right now.
|
| Atomic systems with facades that wrap complexity and are able
| to be swapped beneath the surface are fading and making things
| more complex than needed. The job of engineering is taking
| complexity and making it simple, not the other way around.
|
| [1] https://garry.tv/unity-2020
| johnnycerberus wrote:
| Can you give an example of a message system for game dev? Do
| you mean something similar to message passing in Erlang?
| MikusR wrote:
| Based on their previous opinion on Vulkan, in 4 months they will
| announce moving to ECS.
| Wesxdz wrote:
| I'm developing a mobile game in Godot that would require
| thousands of nodes. The lowest hanging fruit optimization is
| simply ditching GDScript and nodes altogether for a C++ module or
| GDNative. ECS imo is a requirement for non-trivial games, and I
| don't think any game editor has it together here because of the
| tendency to prioritize accessible fast iteration in early stages
| over performance and scalability. So they stay in the comfort
| zone of scene tree hierarchical representation. I'm planning to
| move to Jai or build a PureRef-like visual ecs editor with
| libclang ast reflection and hot reloading so I can escape.
| zemo wrote:
| > the tendency to prioritize accessible fast iteration in early
| stages over performance and scalability
|
| well, I'm glad you're describing the way you see the tradeoffs,
| I just have a hard time seeing how hanging your hat on the
| ability to eek out every little bit of resource optimization at
| the expense of early iteration is a worthwhile tradeoff for the
| majority of gamedevs. Running the game at a worse framerate or
| render setting so that you can tune the gameplay early, get
| through many different gameplay design iterations, and get the
| artists and sound people working sooner seems like it would be
| of value to more teams than something highly performant that
| makes it harder to experiment and iterate. (on the ECS vs
| inheritance point I'm in agreement.)
| tpxl wrote:
| That counts for nothing if you have to rewrite everything
| from scratch 3/4 of the way in. Don't get me wrong, I like my
| iterations, but if your game runs at 20 fps it's simply not
| going to be good.
| ratww wrote:
| The performance advantages of ECS are a bit of a red herring.
| There's not much of a tradeoff when it comes to speed of
| iteration.
|
| The origins of ECS are in the work of Scott Bilas and Adam
| Martin, who weren't seeking performance improvements, but
| rather a way to allow non-technical teammates to iterate
| faster. This thing was revolutionary in the late 90s/early
| 2000s because suddenly you didn't need an army of
| increasingly expensive programmers just to get simple things
| done.
|
| The performance boost was discovered much later when people
| found out that ECS could naturally benefit from data-oriented
| design. Performance is a nice-to-have but is far from being
| the raison d'etre of ECS. It still makes sense to to have ECS
| or EC (or even just non-inheritance-component-based, like
| Unity) without the performance advantages of data-oriented
| design.
| pjmlp wrote:
| ECS like systems were well known in CS even before that.
|
| "Component Software: Beyond Object-Oriented Programming",
| 1998
|
| https://www.amazon.com/gp/product/0201178885
| jvanderbot wrote:
| Personally, deep object ontologies make my eyes glaze over. Its
| not like these objects evolved in the wild and their ancestry is
| somehow interesting. Give me interface definitions any day. ECS
| is nicer for that.
| gameswithgo wrote:
| there is avoiding object trees, there is ecs, then there is not
| doing either of those things, which is often the best and
| simplest option. no need for a fancy ecs system if you have
| like five entities
| vvanders wrote:
| Yup, "has a" vs "is a". From my experience in gamedev the
| former is a lot more common than the latter.
|
| Had an engine where each entity could only have one mesh object
| since it was a part of the base entity type rather than a
| component. Led to a lot of multi-entity shenanigans that were
| brutal from a sync/off-by-one-frame perspective.
| ephimetheus wrote:
| Might be wrong here, but isn't that also a limitation for
| most component column based ECS implementations? (I mean each
| entity can have only one instance of each component)
| vvanders wrote:
| Depends on the ECS, most systems I've worked in will let
| you do two addComponent calls of the same type and then
| they'd just get added to the array of components to batch
| process. This is really common for mesh components
| (although there's usually mechanisms to specify
| dependency/ordering to avoid off by one frame issues).
| jvanderbot wrote:
| Gotta thank @cjhandmer for that rant, but it really stuck with
| me.
| Shorel wrote:
| From the article:
|
| Using ECS
|
| Nothing prevents you to use an ECS solution in Godot. In fact,
| I strongly suggest to check Andrea Catania's fantastic work on
| Godex, which aims to bring a high performance ECS pluggable
| implementation.
| yellowapple wrote:
| That paragraph really should've been the focus of the
| article, front and center - and from there an explanation on
| why it ain't built-in.
| UnpossibleJim wrote:
| I'm a fan of Godot, so I'll state that in the beginning, so
| I'm biased. But I took a look at her(?) GitHub page and
| wondered why there isn't more effort being put into this
| branch. Even from his own words, ECs is a more efficient
| style when a large number of objects/nodes are involved, or
| when optimization becomes important.
|
| At the moment Godot is really only viable as a 2D engine,
| as it tends to bog down when used as a 3D game engine even
| though it has all but replaced the default Blender engine
| (their recommendation). So in order to get a viable 3D
| project, a user would have to use an experimental ECS
| version (no offense to the creators, they are working hard
| and I do have high hopes for this project. I'll most
| certainly be experimenting with it) using the C# version,
| which is still fairly new.
|
| Now, the fact that a small group of devs can make an indy
| project/proof of concept with Blender and Godot, or
| students can make a group portfolio that is viable - these
| things are AWESOME. Granted. But it still comes out of a
| quasi Frankenseinian lab as they have chosen to go with OOP
| instead of ECS, it seems, even though a path does seem laid
| out before them.
|
| P.S.
|
| here's the link to the ECS project:
|
| https://github.com/GodotECS/godex
| bogwog wrote:
| I'm going to have to give a hard disagree. I've been making my
| own engines for a long time, and have used many different engines
| for a longer time. Inheritance-based entity systems are often a
| pain in the ass to work with, a massive pain in the ass to debug,
| and tend to invite shitty hacks to get around the shortcomings of
| the inheritance model.
|
| The article says that "Godot does composition at a higher level
| than in a traditional ECS", but I don't get what he means by
| that? Combining nodes with incompatible hierarchies is hardly
| composition, and is just what you typically have to do when using
| inheritance.
|
| Inheritance-based entity systems are not always terrible, and
| even though I tend to hate them, I use them quite a lot in my
| projects where an ECS would be overkill. If designed for a
| particular project, you can usually be more productive, and write
| cleaner and less code with inheritance.
|
| However, for a general purpose engine like Godot, that's a bad
| choice IMO. The flexibility offered by an ECS far outweighs all
| benefits of an inheritance-based system.
| dexwiz wrote:
| Composition does not strictly imply inheritance. A DOM tree is
| a perfect example of composing nodes without inheritance.
| lxdesk wrote:
| Godot doesn't expose inheritance to scripting AFAIK; it's
| strictly a convenience used internally to describe the core
| nodes. When you script Godot to make complex entities, it's
| through composition of arbitrary nodes in arbitrary
| hierarchies, often encapsulated as scenes. References are
| mostly done by relative path, and the scripting language has
| sugar to make this a convenient process.
|
| So, yeah, try it. It's the best system I've encountered for the
| general-purpose use-case, and I've designed a fair few myself.
| mhh__ wrote:
| So what does Jai do that is different?
|
| For performance at least my focus is usually on eliminating
| information-lossy interfaces i.e. try to keep the hot loops
| where the compiler can see them
| JesseMeyer wrote:
| Jai is a programming language and not a game engine.
| Agentlien wrote:
| The article makes more than a few baffling statements beyond the
| core argument regarding ECS.
|
| The claim of Godot having similar tools as other engines
| certainly caused me to raise an eyebrow.
|
| The strangest in my mind, however, is trying to downplay the
| importance of the performance advantages by claiming games with
| many objects are rare. I currently work on optimising a game
| which falls somewhere between indie and AAA. We have thousands of
| objects active at any given time.
|
| I also dislike the statements regarding compute. I love compute
| shaders and use them whenever I can, but they're basically
| unusable from a performance perspective on both mobile platforms
| and Nintendo Switch.
|
| (Edited from a Reddit comment I made regarding this article)
| gugagore wrote:
| I might have an easier time following if there were some small
| code examples.
|
| For example, the article mentions that for simplicity some
| components require other components to exist. That sounds like
| something that cannot be encoded in the type system of most
| languages, whereas the fields present in classes within a class
| hierarchy are encoded in the type definition.
|
| A code example would help me figure out if I'm following or not.
| linkdd wrote:
| In C# and Unity, you have the class attribute
| "RequireComponent" which will automatically add the dependent
| "MonoBehaviour" when this one is added:
| [RequireComponent(typeof(RigidBody))] public class
| MyObject : MonoBehavior { /* ... */ }
|
| This is not really _in_ the type system, but still, if your
| language provide some meta-programing features, it can help the
| developer makes sense of your code.
|
| This kind of dependency is not a "type dependency" IMHO, since
| the data are independent of each other. It's more like a "logic
| dependency", where the logic of one System requires the logic
| of another System.
|
| It is the systems you want to apply to an entity that will
| dictate what components it needs.
|
| Since it can change during runtime, this cannot be statically
| typed.
| gugagore wrote:
| I think I know the answer, but I'll ask explicitly.
|
| Suppose we have two components: A and B. A is defined to
| `RequireComponent` B. If I do `has(object, A) && has(object,
| B)` then can the C# compiler compile away the check for B
| given the check for A, turning it into just `has(object, A)`?
| linkdd wrote:
| Unfortunately no.
|
| IIRC, all "RequireComponent" does is allow you to omit the
| "add(object, B)" when you "add(object, A)".
|
| A simple example of this is when you add A to the object,
| then edit A to require B. The Unity Editor won't add B
| automatically (which is in fact a pain).
|
| NB: removing A will not remove B, and B won't be replaced
| if it existed before.
|
| I usually use "RequireComponent" whenever I have a
| "GetComponent<...>()" in my behaviour just to make sure I
| have an initialized value.
| hn8788 wrote:
| At the last godotcon, someone gave a presentation on an ECS[1]
| they're making for godot. It's not an official project, but it's
| cool to see that it is possible if people want to develop that
| way.
|
| [1] https://www.youtube.com/watch?v=bjuUtddnUok&t=12370s
| johnnycerberus wrote:
| All this hype around ECS started when Minecraft, Factorio and
| They Are Billions proved that the paradigm works, though that is
| just a small percentage of games that can benefit from ECS. The
| rest should use the classic OOP model. I really don't see how a
| game like Dota, CSGO or your average Battle Royale will be better
| with ECS. I agree with the article.
|
| There are libraries enabling ECS for you if you are not looking
| for an engine like Unity:
|
| C++: https://github.com/skypjack/entt (Non-Java Minecraft uses
| this)
|
| Java: https://github.com/libgdx/ashley
|
| Rust: https://github.com/bevyengine/bevy (it's still work in
| progress, not battle-tested and a moving target)
| pcstl wrote:
| I believe ECS is in fact quite a bit older than that. As far as
| I can tell, ECS first started being talked about by AAA
| developers who were trying to find efficient ways to deal with
| the memory hierarchy in modern computing platforms (it got
| quite big specifically with the PS3, which had a very hard to
| deal with memory layout that could totally kill game
| performance). ECS allows data to be processed in a very cache-
| effective manner.
| bogwog wrote:
| Entity component systems are nothing new, I remember reading an
| article about it from Valve back in like 2007.
|
| The recent hype comes from Unity, because they very
| unimaginatively misappropriated the term.
| diegoperini wrote:
| Overwatch is done with ECS, there are GDC talks from the devs
| explaining the tech behind it.
| johnnycerberus wrote:
| That's cool, I didn't know that. I've found the presentation:
| https://www.youtube.com/watch?v=W3aieHjyNvw
| k__ wrote:
| I had the impression this was already state of the art in 2007
| when I started my CS degree.
| johnnycerberus wrote:
| Kind of providing an ECS-based game pre-2016, before
| Factorio, Minecraft Non-Java, They Are Billions and Overwatch
| (as I was told in a comment) got released?
| pjmlp wrote:
| Not a game, but standard software models,
|
| "Component Software: Beyond Object-Oriented Programming",
| 1998
|
| https://www.amazon.com/gp/product/0201178885
| dkersten wrote:
| Dungeon Siege, although the slides where this was revealed
| seem to no longer be online. Additionally, here is the blog
| post from 2007 that largely introduced the concept in the
| form we know now, based on the Dungeon Siege talk and
| others: http://t-machine.org/index.php/2007/09/03/entity-
| systems-are...
|
| Although, arguably, Dungeon Siege's component architecture
| is different from what we call ECS today.
|
| EDIT: I found the slides:
| https://www.gamedevs.org/uploads/data-driven-game-object-
| sys...
| johnnycerberus wrote:
| Thanks, I will check them out. I'm out of the loop when
| it comes to older games since for me game development is
| only a recent hobby. I'm developing Big Data stuff mostly
| with Java and Scala, but I have been playing with data-
| oriented stuff in Clojure, hence my interest.
| dkersten wrote:
| Funnily enough, I came to it in reverse: I learned about
| ECS years ago (from the tmachine series of posts, posts
| about Dungeon Siege, and others I can't remember) and
| became interested in Clojure's data-oriented stuff
| because of my interest in ECS. Although, I became
| interested in and used Clojure already, due to its focus
| on immutability and functional programming, before people
| really started pushing the data-oriented aspects, so it
| was an easy evolution for me.
| jonhermansen wrote:
| For anyone curious to know more about usage of ECS in
| Overwatch, check out this GDC talk from one of the
| developers: https://youtu.be/W3aieHjyNvw
| dividuum wrote:
| Awesome talk. Thanks for linking.
| vvanders wrote:
| Sorry but we were doing ECS long time before that in the
| industry. I remember doing it back on the PSP with Lua(meta-
| table -> component mapping) and a backing in house C++ runtime.
|
| It was pretty widely known in industry as a way to have cache
| locality and made it out to the broader dev community a good
| while after.
| jmiskovic wrote:
| Could you elaborate the way your system worked in Lua? Was
| the table itself an Entity, and which meta-methods would link
| with component? What kind of querying capabilities did a
| System have?
|
| I've seen metatables used often to implement inheritance, but
| not the ECS yet.
| vvanders wrote:
| It's been over a decade now but if I remember right yeah
| the entity was a table, meta-table would do a lookup for
| the related component(ex: table.mesh would give you the
| mesh component) and each entity also had an optionally
| available coroutine for AI logic. Components were batch
| processed by type for the performance sensitive areas.
|
| The coroutines there was incredibly useful, our designers
| could write AI that was almost literate programming(yield
| value was number of frames to wait to re-eval coroutine).
| Something like: Walk to point A, yield until at A, turn,
| walk to point B, yield, check for nearby entity of type,
| yield, etc.
|
| Oh and it also ran the whole game state in a 400kb
| preallocated block in a system than only had 8mb of
| accessible ram(rest went to vram).
| pjmlp wrote:
| As I mentioned in another thread,
|
| "Component Software: Beyond Object-Oriented Programming",
| 1998
|
| https://www.amazon.com/gp/product/0201178885
| johnnycerberus wrote:
| That's nice, but why all the game engines and libraries
| introduced it only recently? Defold, Unity ECS, etc.?
| vvanders wrote:
| Because not every engine slaps a fancy ECS tag front and
| center, the pattern evolved concurrently in industry (and
| we all had games to ship).
|
| If you look really carefully you'll find structured column
| databases have similar properties since when you optimize
| for speed cache misses are your number one enemy.
| johnnycerberus wrote:
| Yes, I understand that ECS is probably good for more low-
| level stuff like particle-like systems. But what about
| gameplay-code? Unity ECS is mostly about that, to think
| in a data-oriented way about your gameplay programming.
| The thing that bothers me is why huge commerical engine
| like Unreal Engine or idTech don't even lift a finger
| about that?
|
| About structured column databases, the same thing could
| be said about Lisps like Clojure which match the RMDB
| data model. But people still find it hard to grok it,
| hence the low adoption rate.
| teamonkey wrote:
| > why huge commerical engine like Unreal Engine or idTech
| don't even lift a finger about that?
|
| https://docs.unrealengine.com/en-
| US/ProgrammingAndScripting/...
| johnnycerberus wrote:
| But according to the documentation, that is just a OOP-
| hierarchy in which they separate the concerns, they miss
| the S in the ECS.
| teamonkey wrote:
| Not so. The physics system works on all physics
| components. The renderer system works on all rendering
| components. The networking system work on all components
| that are enabled for network replication.
| vvanders wrote:
| https://docs.unrealengine.com/en-
| US/ProgrammingAndScripting/...
|
| The "S" in unreal is a tick. It's been about a decade
| since I last worked with Unreal but there was very much
| the concept of systems that processed batches of things
| in areas where performance was a concern.
|
| Keep in mind that ECS is a design pattern and just like
| any design pattern applied blindly you can end up in a
| worse place than you started. A
| FactoryDispatcherQueuePatternImpl helps no one despite
| using many design patterns. When it comes to ECS it's
| much more about the spirit than the letter of the law.
| dralley wrote:
| You mean the big commercial game engines? They took a while
| time to adjust because, by definition, they're big. Harder
| to move the entire ecosystem at once.
|
| But that's hardly "all the game engines"
| DominikD wrote:
| Total Annihilation (1997), Thief (1998), Dungeon Siege (2002),
| and many others used ECS and their developers wrote about it
| long, long before Minecraft and others.
___________________________________________________________________
(page generated 2021-02-27 23:00 UTC)