4 ms·
As an ex-game developer and software architecture nerd, I'm very excited about data-oriented design and ECS. It really is a cool pattern, and it's a very common
by munificent 3y ago
As an ex-game developer and software architecture nerd, I'm very excited about data-oriented design and ECS. It really is a cool pattern, and it's a very common one in shipping games today. It's not just architecture astronaut stuff.
At the same time, the level of hype about ECS today reminds me an awful lot of the amount of hype surrounding OOP in the 90s. Can ECS be a better way to structure your game entities and make your game loop faster? Yes. Will it make your teeth whiter and your partner love you more? No.
(There are ECS frameworks in JavaScript, which gives you absolutely no control over memory layout and thus completely defeats one of the primary purposes of the pattern.)
Like any pattern, it exists to solve concrete problems. It shouldn't be the One True Way To Think About All Programming Henceforth and Forever.
When the author says things like:
> For example, how would you model chat messages in your game? I suppose you’d have to represent that as an entity in your game. How would you represent a constraint that would prevent a health component from being added to your chat message erroneously? In ECS it’s straightforward to create a system which operates on chat messages individually, but how would you query your chat messages so that you can display them in order?
To me, that just means "Don't use ECS for those." I have a really nice coffee mug that is just perfect for holding coffee. It does its job very well. That does not mean I feel any need to use that coffee mug for digging holes in my garden.
Databases and the relational model are great. ECS is great. Object-oriented programming is great. Functional programming is great. But treat them all as tools that should be used for the right job.
- jerf 3y ago"At the same time, the level of hype about ECS today reminds me an awful lot of the amount of hype surrounding OOP in the 90s." I appreciate that most of the ECS hype has been around specific use cases, though. OOP was claimed as not a specific useful tool, but the answer to all programming, a billing it has not lived up to. It achieved "useful tool", no question, especially as some of the very rough bits were sanded off the original proposals (particularly the idea that objects should only and exactly match real world objects, an idea which I believe in hindsight was accidentally carried over from a simulation worldview in Simula where maybe it worked into the general programming world where it didn't), but it certainly has failed to be the one true programming methdology. I haven't seen anyone claiming everything should be rewritten in ECS.
- hyperpape 3y ago> I appreciate that most of the ECS hype has been around specific use cases, though. I recently watched the first 30 minutes of Mike Acton's 2014 talk, and while that portion of the talk wasn't about ECS specifically, it very much presented an absolutist perspective.
- c048 3y agoThis is a issue with how most potential solutions or languages are marketed, even to experienced developers. They're all sold as silver bullets and every experienced programmer should know that there is no such thing. A lot of it also stems from what I call 'the hello world problem'. Very simple cases are brought up to sell you on the idea, but it's only in complex scenarios that you really learn the worth of something.
- PH95VuimJjqBqy 3y agoThe biggest issue is that it's a mischaracterization of the talk. He spent quite a bit of time at the start of the talk defining the context w/i which he was talking. He used strong language but it was never absolutist.
- hot_gril 3y agoOOP even got mixed with databases to form nasty hype around ORMs and NoSQL.
- deleted 3y ago[deleted]
- hot_gril 3y agoBut to their credit, there was a feature gap in SQL before jsonb was added.
- munificent 3y ago> I appreciate that most of the ECS hype has been around specific use cases, though. Depends a lot on where you hang out. On amateur gamedev fora, I have seen many many many posts from beginners where they are struggling to cram ECS into their game and feel they need to because it's simply "the way" that one architects a game. Even if their game is written in a language that offers no performance benefits and the their simulation benefits nothing from it, they just think they have to. It's heartbreaking watching someone go, "I know I could just store this piece of data right here in my entity class, but I'm not supposed to because of DoD, so how should I do this?" And then they get back confidence answers that involve pages of code and unnecessary systems. It's exactly like the OOP fad of the 90s, just in the opposite direction. Yes, it turned out you don't need to encapsulate all data in classes. But, also, it is OK to just store data in stuff. You don't have to make every letter of your pop-up dialog a separate component.
- meheleventyone 3y agoThis. To me a well engineered game from a data perspective is a set of seperate datastores optimized for the job they are doing referencing one another through handles. I can see the drive to represent this in a general purpose way but you nearly always lose performance and/or flexibility. Ironically the “where do I put chat messages in my ECS” example illustrates that nicely.
- morganherlocker 3y ago> (There are ECS frameworks in JavaScript, which gives you absolutely no control over memory layout and thus completely defeats one of the primary purposes of the pattern.) While JS does not provide great support for bit packing complex structs, typed arrays give you quite a bit of control over memory layout for simple numeric types, which is what you usually want for optimal data-oriented code anyway. This is a common technique used in fast JS libs for data visualization, ie: https://github.com/mourner/flatbush https://github.com/mourner/flatbush There are also basic operators required for bitarrays, which are useful for ECS and memory-efficient code generally.
- p1necone 3y ago> There are ECS frameworks in JavaScript, which gives you absolutely no control over memory layout and thus completely defeats one of the primary purposes of the pattern. It doesn't give you direct control over the memory layout, but it's still fairly safe to assume that arrays are going to end up in relatively contiguous memory, which the relevant part for the performance difference between structs of arrays and arrays of structs. I don't recall explicitly telling many compiled languages to stick all the items in an array together in memory either - it just happens by default, same as in JS.
- Rusky 3y agoJS arrays don't store their elements directly, they store references to their elements. (Unless the elements are primitives and the engine is using NaN-boxing or pointer tagging to store those inline, or something like that, which doesn't apply to ECS components generally.) Depending on how the GC works, the elements themselves might still wind up next to each other in memory some of the time. But that is definitely not a pattern that you would expect to hold in general- components will be added and removed over the course of the game, with lots of other stuff happening in between. In C++, the layout of the array elements is actually part of the language semantics. In JS, the language semantics don't even have a way to talk about that layout, and engines in practice don't use the layout you want.
- meheleventyone 3y agoTo get this in JS you should do it explicitly with TypedArrays otherwise you’re at risk of what the underlying VM does and in current modern implementations it most assuredly doesn’t make sure most kinds of arrays end up relatively contiguous. Notably for this conversation arrays of objects are unlikely to.
- munificent 3y ago> it's still fairly safe to assume that arrays are going to end up in relatively contiguous memory A contiguous array of pointers to the actual objects doesn't buy you much. You're still doing an indirection and risking blowing your cache each time you do something with each element. It may be the case that the objects the array elements point to are contiguous in memory, but that's entirely a roll of the dice, and those dice get re-rolled on every garbage collection.
- DrDroop 3y agoWhat about TypedArrays though, they could be useful to implement a ECS in JS. I do agree with your point, but ECS could be a useful pattern in JS not just for graphics or games but also OLAP workloads.
- tlarkworthy 3y agoI don't think memory layout is the sole draw, it's also about incrementally building up programs live.
- munificent 3y agoYou don't need ECS for that and it doesn't necessarily buy you much. Composition over inheritance can often accomplish the same goal.
- tlarkworthy 3y agoOf course it buys a lot, you don't blow away program state when you change the program. That's huge for highly stateful programs. Also ecs is a prime example of composition over inheritance
- munificent 3y agoECS is anti-composition. With composition, you say, "This object A has pieces B, C, and D. The way to get to B, C, and D is by going through A." ECS is the exact opposite: "There are components B, C, and D. They may or may not be associated with entity A. In most cases, you shouldn't care because you should be working with B, C, and D directly and not going through A at all."
- tlarkworthy 3y agoI think your latching onto an overly specific definition of composition. The core of composition vs. inheritance is how you add features to a things, and whether that mechanism is decoupled so you can bolt that feature to other things. A feature is a blob of code, as opposed to data, which is a blob of memory. ECS means to add a feature, you write a new system. Its decoupled because you don't have to do anything to anything else in the program. Adding a system (feature/code) affects nothing. To bring it to life on a subset of entities, you add components, which are the data portion. It only affects the joint of those entities that have the component. So again, data can be dynamically added even at runtime without affecting anything else. With inheritance. You need to add a subclass, and restart the program, losing all the data in the process, coz the code is coupled with the data (the definition of a class). This can be annoying for some types of program development.
- zengid 3y agoYour chapter on ECS in _Game_Programming_Patterns_ fueled my own obsession with the power of such a design, so you could be partly responsible ;). I’ve spent a lot of time thinking about how to incorporate Data Oriented Design, SoA and ECS into the normal boring business logic at work, and I think it’s interesting to think about keeping data in the same form as it is in the relational database and skip the impedance mismatch in Object-Relational Mapping. ECS only makes sense if you have real structs like in .NET or C/C++/Rust/Swift/etc, and tight latency requirements, but I think when someone learns a powerful concept like ECS, they want to invent a reason to use it so they can actually use it in action. I know that is what I’ve experienced at least.
- matesz 3y agoI dedicated years to full-time work on unifying the architecture for general software development. ECS, OOP, functional programming, and others serve as methods to organize software — the developer interface. However that role should belong to IDEs — an actual user interface for developers. Everybody has different hierarchy of their software, esentially developing their own software engine which sucks, because doing it right is extremely hard and time consuming. What Steve Jobs told long time ago is still true today, "Paradoxically, we need more sophisticated software to make it more easy for the user" (paraphrasing). This is what we need - trully general software engine with IDE made right, what will unify organization of all sofotware and beyond. For some deeper insights, in the context of the Web, I suggest reading Graydon Hoare's post [1]. [1] https://types.pl/@graydon/110561036237098295 https://types.pl/@graydon/110561036237098295