[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)