3 ms·
> Hardly any game needs "thousands of interacting entities" though (outside of special subsystems like particle systems). This is an example of survivorship bi
by pphysch 5y ago
> Hardly any game needs "thousands of interacting entities" though (outside of special subsystems like particle systems).
This is an example of survivorship bias. How many ambitious game concepts have collapsed under performance/architecture issues that lead to productivity-killing refactoring? Impossible to say, but no doubt many.
> Arguably, ECS makes it harder to incrementally build a game by adding features, because you need to put more effort into designing the data layout upfront.
OOP bakes these decisions into the inheritance hierarchy, which ends up being more thorny than adding a component, or migrating an existing component's schema. ECS will make it straightforward to determine which Systems will be affected when a particular Component's schema is altered.
- Twisol 5y ago> This is an example of survivorship bias. How many ambitious game concepts have collapsed under performance/architecture issues that lead to productivity-killing refactoring? Impossible to say, but no doubt many. I'm reminded a bit of Minecraft, whose infinite and completely mutable voxel world was really novel at the time -- and which was (and maybe still is) the source of a lot of performance woes.
- meheleventyone 5y ago> This is an example of survivorship bias. How many ambitious game concepts have collapsed under performance/architecture issues that lead to productivity-killing refactoring? Impossible to say, but no doubt many. Probably less than you think. The games industry knows how to wring performance out of hardware. Data oriented design is common in most game engines where it matters. It’s just it’s not usually the gameplay code that is particularly a bottleneck. There are also plenty of examples of games where the gameplay layer is a perf concern that not only have been released but were big sellers. For example Factorio and City Skylines. It’s just I’m those examples it makes more sense to worry about data model and access patterns for the actual problem at hand rather than try to generalise it with all the attendant problems that causes. Not least slowing down workflows when you don’t actually need it. Most game engines are also composition based rather than using much inheritance these days.
- SeanBoocock 5y agoSpeaking from experience, the hardest part about game development isn’t figuring out how to (efficiently) build something, it’s deciding what to build in the first place. The second hardest problem is getting everyone on board with the answer to that. The third is figuring out how to build the content 1000x to support that. Way, way down the list is the runtime performance for a gameplay system. True ECS systems - and not frameworks that just have things called “entities” which own things called “components” - are hard to work with, almost by definition (ie you have to be very explicit about data layout and dependencies). They add a lot of friction upfront to solving the important and hard problem(s) while purporting to solve something that isn’t actually an issue in most cases (guess what, your N is likely < 10, modern cpus go brrr, etc). If you are working in a domain where you already know something about the performance and input size characteristics - particle systems are the go to example - then maybe ECS makes sense as a framework. Otherwise, I’d advocate for simpler oop approaches with heavy composition.
- danybittel 5y agoAnd if N > 100000, you probably want to use the GPU, ie. a particle system.
- arc619 5y ago> just have things called “entities” which own things called “components” - are hard to work with, almost by definition (ie you have to be very explicit about data layout and dependencies). My experience has been completely the opposite to this. In fact being explicit about data layout and dependencies is a hallmark of a OOP rather than ECS. In compiled languages the dependencies in object hierarchies are fixed at compile time and can only support tree designs, so you have to plan ahead for all possible combinations to even build relationships with OOP, even with composition (because its static). With ECS everything is decoupled so you can write a system that does X and it affects nothing else. This leaves you free to design by isolated processes rather than by code structure, and entities naturally do whatever processes their data supports dynamically. Makes iterating designs incredibly rapid and offers design options that are convoluted and fragile with OOP such as completely changing what an entity does at run time. For instance you can move the keyboard input component from a player entity to a monster or even something as random as a building and it just works - you didn't have to design for it, you don't even need to change any code. Remove the health component, now the entity is invincible, remove the gravity component and now it can fly, add a homing component and now it seeks a target. All this is trivial and can be done at run time. Want flying flaming lampposts the player can control? Just combine the appropriate components. Need to drastically pivot the design? Vastly less work than OOP - sometimes just a case of changing the data in components or their combination in entities without touching systems. Don't need this flexibility? Still gives you a more modular and less coupled design. As a nice bonus this flexibility comes with more cache friendly performance than static hierarchies to boot.
- megameter 5y agoIt's a "where are the bullet holes on the planes that survived" kind of problem. The thing that overwhelmingly kills game projects is overscoped design, which manifests into a need for very detailed, configurable entities with rich scripting functionality. So if you pursue scalability at the level of the entity system itself, as a thing you should invest substantial engineering resources to - you are effectively saying, "yeah, I have a team of 100 people to throw at the game's implementation and they are going to add literally every feature we brainstormed and also stuff we haven't". Because if you actually don't intend to do that, then you can instead adopt a pattern of prototyping it in whatever works well for authoring, followed by profiling and hardcoding a fast path as necessary. "Fast from the beginning" is just guessing about the bottlenecks. And that doesn't mean OOP is definitely good at the authoring task, either. It just happens to be good at kicking the can down the road and letting things work inconsistently, which may be correct in a prototype when you don't know if you're actually shipping that feature, and only poses an issue if you've tied the authoring to the runtime implementation in a deep fashion. Godot doesn't assume this; while it does have hierarchical relationships of objects, it has some boundary points with respect to reuse(scenes and scene instancing) that make the path of least resistance be to make separate authoring and runtime versions of entities, with one spawning the other.
- jayd16 5y ago>OOP bakes these decisions into the inheritance hierarchy This is what I don't understand about OOP haters. Inheritance is an optional feature. In fact most ECS frameworks are in OOP languages.