Hacker News new | past | comments | ask | show | jobs | submit login
Why isn't Godot an ECS-based game engine? (godotengine.org)
272 points by nafey on Feb 27, 2021 | hide | past | favorite | 148 comments



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


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.


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.


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".


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


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...


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.


DOTS is not ECS. "Unity Classic" is ECS. DOTS is a more cache-efficient architecture designed to support larger numbers of entities.


Unity's DOTS is definitely an ECS system. You technically can have an ECS without all the data-oriented and cache efficient stuff, if you just want the architectural benefits, but it's pretty hard to build a data oriented game engine that is not fundamentally ECS


Definitely true, having looked at probably 20-30 ECS frameworks in about 5~ different languages between 2019 and 2020. About half of the ones I looked at, probably a bit less, were DOTS.


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.


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?


You’re right, they do. You add a layer on top that is in charge of worrying about those interactions, and it works pretty smoothly in my experience, but even then there can be some challenges from multiple pieces of code trying to use that controller code to do contradictory things. But I think you end up in the same situation with all big apps, and in this setup at least some of your code is still easy to reason about. It’s still several layers of abstractions. Command pattern with a good entry-in-progress-exit lifecycle is another system to add on top that helps things stay flexible and easy to work with later on


Not to sound rude but IMO I find components really hard to organize and structure data. Components are probably really nice for storytelling games and games with simple logic: they really shine when you can just take some effect like a particle system and attach it to some object like a Sci-Fi weapon. But it's really hard to separate model, view, and controller from your game when they're all separate components on the same object.


MVC is good for user interfaces, but there is some inherent coupling between model and view in most games. Eg, animations. I didn’t have much luck using mvc outside of the ui. IMHO, single responsibility is the more fundamental principle and components are helpful for that


You worked on Commandos? Holy crap. I'm mid way in to my game development career and played that to death before I even started. Plus 70 hours on Steam as an adult...


If you wanna make me feel old, just consider that Commandos was released 10 years after my first commercial game, so I'm even older. :D Fun bit: I never ever finished a single mission in a Commandos game.

Yeah I did code architecture work on Commandos 1, then led the tech & tools for the expansion and Commandos 2. A lot of the C1 work was related to this topic, actually: when I arrived at the project, it was hard inheritance-based with a fixed set of subcomponents, and I shifted it to a common base for gameobjects (the class "Bicho", really odd name) which contained a collection of arbitrary components that communicated via messages. It was more extensible that inheritance, but very messy - too many assumptions and typecasts. First steps... The Commandos 1 codebase was thrown away and restarted from scratch for Commandos 2.


It's never too late to start playing!

If you ever get around to writing up a technical post mortem I'm sure it would be super interesting. The simulation seemed quite advanced for the low end hardware the game ran on, with view cones, pseudo height, physical objects, footprints, and pretty good AI.

The Commandos series dying out is a great shame, although of course Kalypso is staffing up to attempt a sequel.

What are you up to these days?


Heh I was officially the last Pyro employee before it was folded, and my last task was to prepare and package up all backups when the IPs (rights, licenses, whatever it actually was) were sold to Kalypso. I not-so-secretly wished there would be a way for the Shadow Tactics team to make the next Commandos, but it wasn't to be (and Desperados 3 is awesome!).

For the past 2.5 years I've been at Lingokids, a mobile service filled with fun and educational content for kids in English. The tech challenge here is balancing constant forward movement with new games, while keeping all the previous ones working. But using my kids as testers beats anything else I've ever done in the fun-at-work department.


There's also this, which seems like a pretty good spiritual successor out of Russia. I've only played for twenty minutes or so but so far so good.

https://store.steampowered.com/app/1227530/Partisans_1941/

I can definitely see that being more fulfilling. There are only so many virtual Nazis you can kill before it wears thin!


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


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.


Cosigned. I did level design on a game in the Unreal 1 era. The cosmic inheritance hierarchy was a regular annoyance.


> [ECS was] Popularized by Scott Bilas' engine for Dungeon Siege.

Make that nothings' and MAHK's http://enwp.org/Dark_Engine for (initially) Thief.


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


> 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.


Godot is node based so you compose an Entity out of nodes. It’s a slightly more flexible version of an Entity Component model.


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.


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.


Composition does not strictly imply inheritance. A DOM tree is a perfect example of composing nodes without inheritance.


Strange to see this worded this way because I often think of composition as the opposite of inheritance.

Instead of “this thing uses this subset of parts from its parent” it is “this thing is composed of this collection of parts.”


Can you give an example of how the composition works, or where it is used?

With everything inheriting from the Node class, I've only seen it as being an OOP/inheritance system.


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


Jai is a programming language and not a game engine.


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.


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


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'être 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.


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


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.


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)


> is trying to downplay the importance of the performance advantages by claiming games with many objects are rare.

Which games in https://en.wikipedia.org/wiki/2020_in_video_games have thousands of live objects?


From that list? The Last of Us Pt. 2, Ghost of Tsushima, Half-Life Alyx, FF7 Remake. I'm not seeing Cyberpunk 2077 on the list, though.

Objects are anything from walls and NPCs to sprites, particle effects, imposters, ... they pile up very quickly in a complex scene.


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.


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.


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.


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


> But I took a look at her(?)

Seems to be a guy, Andrea is a male name in Italian, and female in pretty much any other language.


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.


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)


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


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


Gotta thank @cjhandmer for that rant, but it really stuck with me.


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?


> 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


What I think he's referring to is that you cannot compose new entities that consist of a different mixture of data. I cannot create a ProjectileWeapon that also plays audio, without changing the class to also inherit from an audio node type.


In Godot, you could create a ProjectileWeapon and then add a sub node that plays audio. I don't think that Godot's design limits what you can do at all, there's just a different way of doing the same thing.


Sure you can solve it by basically adding more objects to the world. That's not different from any other engine, but littering your scene graph with nodes because the alternative is inheriting from more things really isn't good.

As much as godot wants to claim their nodes are lightweight, ending up with so many redundant tramsforms, vtables and more (see their Node3D class) just shows how inflexible it is. Again in engines like Unity you can take the exact same approach, they just allow you to author entities without this redundancy.

To add: the blog specifically mentions that using inheritance is used for better re-use, but the need for having this composition through nodes would take that away. I know this might not be your specific point, but it ironically makes it seem they don't see this as an alternative.


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


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.


> 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.


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.


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.


Usually scripting engines in games are there for the exact same reasons, moddability again being a side effect.


A nitpick: "Lua". It is not an acronym.


> 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.


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.


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.


Starcraft does this for it's map animations. Each player in the game has a different color (so you can tell who's units are who's) and on some level that color is implemented as an index into memory, so if you set the player color above what the designers intended you can end up with wonky colors and (if memory serves correctly) some indices can land you in the rotating palette and give you subtile animated colors on your units. Most where just garbage memory though. This leads to a crash too because unlike most units the special 'flag' unit (for capture the flag) has a different portrait for each player color. It's also indexed by player color, so if you click on a flag of an invalid-color player, it crashes the game. This lead to fun maps like 'dont click the flag' but also woe in long running maps where players could click crash flags by mistake. Again, if memory serves, the crash was fixed by some hacks people would use in Roleplay maps (vision hacking allowed you to stack buildings) so RP map makers would include then anyway. Units to use as labels where at a premium in RP maps, you see...


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.


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


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.


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


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?


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)


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.


I feel your pain. I wanted to combine AngularJS and BabylonJS for a GUI heavy RPG but it proved impractical.


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


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.


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


Can you give an example of a message system for game dev? Do you mean something similar to message passing in Erlang?


Based on their previous opinion on Vulkan, in 4 months they will announce moving to ECS.


One of the ideas of data-oriented design (of which ECS is ostensibly associated with) is that data storage and application logic should be decoupled. E.g. your logic may be organized as an object-oriented "scene graph" or whatever which under the hood transparently queries data from (say) a columnar store.

It's not clear from the article how Godot entities are organized in memory or if there is even is an abstraction layer between logic and data.


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?


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?


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.


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.


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.


> 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...


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


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.


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.


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.


In this context, what do you mean by sparse? Simply that similar data is not packed together?


Computer memory access is efficient when linear. That is, when the next thing you need is located directly after the last thing you needed, in memory. In JavaScript, arrays are conceptually sequential, but this is only an abstraction for the programmer. In truth, the array elements are scattered around in random memory locations. This means that when you iterate over an array, the CPU cache misses on every iteration, and the CPU has to wait for the next data to load from memory.

In a language where arrays are not sparse, but rather dense, the whole array is allocated as one contiguous stride of memory. Iterating through it is very fast, because the CPU cache hits every time and the next data you need is always ready, as it immediately follows the previous in memory.

Additionally, ECS wants to pack data even further, so that unneeded data is not interleaved within the memory stride at all. Every byte you "skip" is wasted space in the CPU cache, and eventually accumulates into a full cache miss, which stalls program execution.


I think some JS engines may treat arrays as dense as an optimization in certain cases


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.


I don't really understand what's the advantage of ECS compared to OOP composition. Anyone here can shed some light on the matter?


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


Short story: data is aligned in a way that favors batch processing. Less branching, great setup for SIMD or GPU processing.


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


> 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.


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


If you have beefy objects representing, say, characters, and you only care about their position, you'll use 16 bytes of a 64 byte cache line. So for the "move everything to the right" use case you're wasting 75% of the bandwidth if you go with simple composition or inheritance. If you move from arrays of objects to objects of arrays, your cache utilization improves fourfold. This doesn't matter for your character of, IDK, 20 platforms moving on the screen, but it does matter a lot for entities that are counted in hundreds or thousands. There are only that many cache lines available and memory bandwidth is also limited. If it's your bottleneck, ECS is going to potentially solve some problems. If you're doing something simpler it may not matter at all.


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.


It also translates to a relational model, selection, join and projection.


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


I always preferred doing ECS at a higher level. Above core engine level. Using ECS to handle stuff like rendering never made sense to me. So for me, Godot's approach is the ultimate one. You model core engine compoments with inheritance and use ECS only for high level behavior for entities;

This is the way. I have spoken.


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.


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.


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)`?


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.


My experience with Godot is that it has a very clean design. There is just nothing hacky or unintuitive about it.

Although I don't know much about entity component systems, my impression is that it is basically just multiple inherentence. Personally, I never had any need for such a thing in Godot.


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


The Entity-Component system is not really about composition over inheritance, mostly because "Inheritance vs. composition" is not an either-or choice, but also a little bit because Entity-Component is not really even the best way to perform composition, if greater composability is your only goal.

The choice of inheritance vs. composition is not a dichotomy, it's a spectrum. There are certain properties of your program that are better modeled through inheritance, and others that are better modeled through composition. You end up using both in the vast majority of systems.

Classical object-oriented GUI frameworks have a Button class that inherits through a chain of classes that add greater refinement of behavior. See [0]: System.Object -> Component -> Control -> ButtonBase -> Button.

But you don't create such a hierarchy for something like a login form. A login form will inherit from Form [1] and use composition of subcontrols to create its behavior. You'll have a few textbox controls, a few labels, and a couple of buttons composed with the login form.

And neither is an Entity-Component system really all that great of a composition system. You end up having to query the system for cross dependencies at runtime a lot, as there are no compile-time, static guarantees that any particular component will exist. Something like Inversion of Control with Dependency Injection can give you a better workflow for getting dependent components together in the same place.

Incidentally, building a project in an Entity-Component system (or any composition-based system) does not prevent one from being able to utilize inheritance, either. I'm not even aware of any composition systems that don't use inheritance heavily, actually. For example, Unity's ScrollView [2] component has the chain System.Object -> CallbackEventHandler -> Focusable -> VisualElement -> ScrollView.

An Entity-Component system is really much more about creating ad-hoc objects. Game design is notoriously finnicky. There is no schema or "shape" of fun. You tweak and reorganize and tear apart and recombine things until it just "feels" right. So Entity-Component makes it possible to create and compose objects on the fly, with fairly reasonable performance.

So these statements like "I turned away from inheritance 20 years ago and I'm now all about composition", they just don't make sense. "Inheritance vs. Composition" is not something you think about at the application level. It's something you think about at the functional unit level, and make the choice separately for every functional unit.

[0] https://docs.microsoft.com/en-us/dotnet/api/system.windows.f...

[1] in WinForms that'd be: System.Object -> Component -> Control -> ScrollableControl -> ContainerControl -> Form

[2] https://docs.unity3d.com/ScriptReference/UIElements.ScrollVi...


As a newb, I do find ECS harder to reason about.


Whether or not to make your game have ECS has been debated for years, probably rightfully so to some extent. I ended up writing something like this myself for my own 2D game engine. To name something, it's greatly decoupled, but it also means any algorithm (i.e. system if you will) can literally access any data from any object in your gameworld. It just breaks encapsulation to a huge extent, any data you add is immediately visible to every of these systems and in most cases, you cannot reason what inputs/outputs a system really has. That at least goes for the generic solutions out there.

However, I think this blogpost tries to argue against ECS for all the wrong reasons. I'm not going to go into every detail, but let's start out with this: I don't want to bash on Godot, I think it's amazing they're pushing the game engine scene, but a blogpost like this really makes me question the quality of what they wrote.

> Inheritance is more explicit

I cannot remember a time I ever found it useful to look at an inheritance diagram that presumably will be littered with diamond patterns. Besides, inheritance isn't immediately excluded from other codebases, it just isn't the core principle of their software design for composing objects. Also also, I might have hundreds of (slightly) different objects in my game, so even without diamond patterns, that inheritance hierarchy is not going to be very useful to me.

> Scenes are more explicit

I'm looking at the picture and I'm not sure why I want a scene graph to show my inheritance patterns in the first place! If you ask me, it clutters the scene graph with details about this object. I mean, not unworkable, but I cannot understand this is an advantage. Besides, easily replicated by listing the components that an object is composed of in any game engine, it's not like other editors/game engines can't do it. Most engines do this with a separate view that shows all the data for this object.

> Re-usability improves This one is beyond hilarious if you look at some of their source code. The 2D vs 3D is a prime example, take audio_stream_player_2d/3d for example. A lot of the functionality has been copied between their counterparts (with some inconsistencies, of course). That's kind of logical from the structures, since the algorithms and data they operate on has been completely sealed off, so they couldn't even decently share it if they wanted to. It seems completely due to the fact that at the top of the hierarchy sits a hard distinction between 2D and 3D nodes.

To then point out you don't even need something like prefabs (for those not familiar: think of a template/blue print of a pre-composed entity with data already filled in) is just a weird stab. You could just as easily create such a pre-composed object in code with any component-like design, Unity's prefabs just give you the flexibility to compose these in the editor instead. How is an architecture where I need to explicitly type code to compose new objects ever easier than that?

There are other things I'd find questionable by a quick glance over that codebase that are also a side-effect of these architectural choices. Like, singletons that are used to combine nodes of the same type to form some spatial datastructure, because those nodes cannot be easily made aware of each other. There seems all kind of implicit dependency issues and I've always struggled with nicely engineering dependencies in such architectures as well.

But I'm going to stop here, there's just too much I can go on about in this blog (I would even consider dedicating an entire blogpost myself breaking my disagreements down).

The whole tone of: we use inheritance and we think it's better for the entirety of our software is just strange. As always, inheritance is a tool, you should use it when it's right, yada yada. If you use multiple inheritance and end up with diamond patterns, I don't think I'm the only one that would say that you should reconsider. Shoving all your logic for every aspect of your program into single objects has rarely worked well either.

I already mentioned what I dislike about the generic ECS that everyone keeps talking about like in Unity, but they can improve their architecture and/or apply DOD without doing a 180 into that direction. This weird deflecting of potential architectural flaws certainly didn't sell Godot to me, but hopefully they come back to this post and think it a couple times over.


My experience here is very limited, but at least in the Rust world, some ECSs seem to make component dependencies explicit, partially to support scheduling parallel systems execution. That is, if there are two systems where neither system writes any component that the other accesses, they can run in parallel. Is that not common in general?

Godot usually gets a lot of praise of HN and elsewhere, probably rightly so. But I got the same weirdly defensive vibes from reading the article. Performance is the strawman used throughout: claiming you don't need that many objects anyway, claiming that there design is "higher level" -- without ever really explaining what that means. I know from other contexts that the real problem with deep inheritance hierarchies often is code duplication, you simply can't solve the diamond problem. Good job pointing out examples of that.


It's indeed a common approach that they list their dependencies so you can build runtime DAGs for multithreading, but my main point is that within one system dependencies can be selected at will (I believe Unity allows to just change these at runtime as well). In the end they just get the entire gameworld fed in and then select what they need. If you take something like writing unit tests, you basically have to mock the entire gameworld because these dependencies could change, even if only theoretically. I struggle to find a good way a generic approach of DOD can prevent that.

In general it's also very hard to get dependencies done right. I think Unity does it well, but from what I saw some years ago it's one of few (for implentations that are public). Also not surprising considering Mike Acton seems to play a significant role in that.

Yeah their arguments on performance are an even worse aspect of the article. It's clear that no game or simulation of significant scale has been built with Godot.


ECS or no ECS? it doesn't matter

the problem of that kind of engines is the users are computer-illiterates

they don't understand how memory/cpu works

what happens is 90% of 3D indie games suffer from major performance/optimization issues

and we start to see the same kind of performance issues in AAA games, because, as always, we always want to cut costs, everywhere

worse, clueless people are gaining power and are getting into high positions, and they hire more clueless people so nobody can oust them, or tell them they are wrong, they want people to comfort them, and defend their bad decisions


You could have phrased that better. A lack of optimization could be a real problem but attributing it to "clueless people gaining power" or calling users of game engines "computer-illiterates" just smells of gatekeeping.


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.


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.


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)


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.


As I mentioned in another thread,

"Component Software: Beyond Object-Oriented Programming", 1998

https://www.amazon.com/gp/product/0201178885


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.


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


That's nice, but why all the game engines and libraries introduced it only recently? Defold, Unity ECS, etc.?


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.


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.


> why huge commerical engine like Unreal Engine or idTech don't even lift a finger about that?

https://docs.unrealengine.com/en-US/ProgrammingAndScripting/...


But according to the documentation, that is just a OOP-hierarchy in which they separate the concerns, they miss the S in the ECS.


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.


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.


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"


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.


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.


Overwatch is done with ECS, there are GDC talks from the devs explaining the tech behind it.


That's cool, I didn't know that. I've found the presentation: https://www.youtube.com/watch?v=W3aieHjyNvw


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.


I had the impression this was already state of the art in 2007 when I started my CS degree.


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?


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


Awesome talk. Thanks for linking.


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...


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.


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.


Not a game, but standard software models,

"Component Software: Beyond Object-Oriented Programming", 1998

https://www.amazon.com/gp/product/0201178885




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: