Why I removed Components from my Game Engine

  Рет қаралды 43,275

Joshua Manton

Joshua Manton

Күн бұрын

Пікірлер: 203
@QIZI94
@QIZI94 Жыл бұрын
For me even if ECS wasn't best for performance, I would still use it. I spent a lot of time in OOP and the main hero of the ECS paradigm are Systems. (Entities and Components are just details that can have any shape) Systems help not to hide dependencies and I know any code that is running is inside of Systems and there are no hard to see links between components When I come back to by code bases, I do not need to know hierarchies of objects referencing each other, since ECS provide flat architecture I look at the individual systems and know what they do and what they interact with.
@aurelianspodarec2629
@aurelianspodarec2629 10 ай бұрын
That's like true and false IMO context matters a lot
@NEO97online
@NEO97online 8 ай бұрын
ECS looks good to you because you're coming from OOP. You know what else provides you the same thing as what you're valuing Systems for? Its called a "function"
@QIZI94
@QIZI94 8 ай бұрын
@@NEO97onlineI coming from C++ and C I spent years at jobs using them so OOP is just one of the paradigms I am coming from. For me the concept of the system or as you called just a function isn't about if its a function or function "attached" to instance of an class, its about design of ECS that only interactions between entities and components happens in those chosen functions and nowhere else. In OOP where you often make hard links between other objects that in big enough code base become forgotten/invisible dependencies, which leads interactions happening everywhere. Can you use "advanced" software architecture in designing your OOP structure and mitigate the interactions and dependencies happening everywhere ? Yes. But will most programmers do it ? No. This forced "order" structure, kinda makes it harder to make these hard links and dependencies. Should you use ECS everywhere ? No not even close. Should you at least consider ECS when starting project instead of going OOP by default ? Yes.
@notactuallyarealperson2267
@notactuallyarealperson2267 8 ай бұрын
@@NEO97onlineI think that’s what OP was saying. Systems are just functions as components and entities can be arbitrary
@QIZI94
@QIZI94 7 ай бұрын
@@NEO97online I have mostly spent most of my work in C and C++ some rust and then python and other popular languages. So OOP isn't only thing I spent my time with. System doesn't have to be a function it can be anything that can manage interactions between components and entities. It looks good to me because I went into OOP for significant amount of time and identified main drawbacks of which few of them are addressed by ECS.
@RenderingUser
@RenderingUser Жыл бұрын
my youtube reccomendations be like: yesterday: inheritance sucks today : ESC sucks tomorrow : your existence sucks
@marksmithcollins
@marksmithcollins 9 ай бұрын
video always recommended : dod and ecs will cure cancers
@saritsotangkur2438
@saritsotangkur2438 Жыл бұрын
A lot of false dichotomies in this rant. You say that Systems are primarily for performance optimization and if you don’t need the performance then it’s unnecessary increasing complexity. This is all incorrect. Systems force developers to make explicit dependencies on the Components they care about and then to write focused code pertaining to just those components. Rather than having long complicated update logic that touches many different aspects of the game, a good ECS implementation will use several Systems, each doing a fairly small straightforward task. Like in your on fire example, you might have a flammable component and an on fire component. The PropagateFireSystem might find all flammable entities next to on fire entities and decides whether or not to also set those to on fire. Then the FireDamageSystem would take all thinks that are on fire and have a hitpoint component and start deducting hit points. Then a AssignDeadSystem marks any hitpoint entity with 0 points with a dead component, and so on. Coding this way is incredibly simple, not an addition of complexity that you claimed. This is just one of the few false dichotomies that you’re providing throughout the video.
@marksmithcollins
@marksmithcollins 9 ай бұрын
Your logic is typical trait of ideology. Coders need to know more humanities....
@filmamundo9194
@filmamundo9194 9 ай бұрын
​@@marksmithcollins Sure...but nothing proves he is wrong
@rodrigoserafim8834
@rodrigoserafim8834 8 ай бұрын
@@marksmithcollins No. Appeal to feelings is a typical trait of ideology. Logic is the complete opposite of that. The dude made a thoughtful explanation of each claim and how it works. Then made his conclusions based on those explanations. Not on his opinions. You are the one making blind assertions without any detail or train of logic. If anything, coders need to stay the hell away from your kind of "humanities".
@joshuamanton
@joshuamanton 6 ай бұрын
You just described the most rube-goldberg way to implement the fire spreading example. Instead of writing the code in a single spot with perfectly linear and easy to understand/debug code, it's just spread everywhere probably in 4 or 5 different files. This is insane. The complexity point was mainly about complexity of implementation of the underlying system powering all this nonsense. I don't even remember if I touched on complexity of usage, but that is also through the roof as you have outlined.
@iMagUdspEllr
@iMagUdspEllr 6 ай бұрын
​@joshuamanton I'm still generally on team entity. But, the point is that you don't need to give every entity every feature it could possibly have (which may involve adding new methods and fields to its class for every possible feature). You can design each feature separately and tack it on or remove it in a modular manner. That seems to be better. Anything that can be added and removed easily like that seems way better because you don't have to plan ahead as much. You could simply add and remove behaviors and states as specified in each system you write instead of needing to update the class for every entity to accommodate the new feature. But, I'll have to practice more to see where the downfalls are.
@BosonCollider
@BosonCollider Жыл бұрын
The other advantage of ECS systems is for *fast querying* of entities based on which components they have. Your example had to do a linear search for onfire objects. An archetype based ECS would have it handled by partitioning and be proportional to O(number of archetypes + number of onfire entities). If not using archetypes it can be implemented by hierarchical bitmaps. You will want something like it if you have a lot of very specific properties that your entities can have Also, the video does apply to handmade game engines, but not as much to when choosing an already made game engine with a mature ECS like Bevy, and comparing it to a mainstream one like say Godot which can be very object oriented. Chosing something like Bevy vs something like Godot is something that is strongly dependent on how you feel about composition vs inheritance
@LisaCoffee-i4s
@LisaCoffee-i4s Жыл бұрын
But composition and inheritance are complimentary...
@DaGhost141
@DaGhost141 9 ай бұрын
@@LisaCoffee-i4s depends, functional inheritance is great but combinding data and functions and inheriting both leads to all kinds of problems (see c++ diamond problem). Rust does this imo quite well, make functionality inheritable and to data via composition.
@neperion5939
@neperion5939 Жыл бұрын
To me the title is click bait. As you said, I can't see how your new paradigm isn't just replacing entities by entity array indices and components by entities. I totally agree that composition has nothing to do with ECS. But really in this video, you just switch from one way of implementing ECS to another that is simpler for your use case.
@BonktYT
@BonktYT Жыл бұрын
I agree! Simpler for his use case but also with worse cache-locality, memory efficiency, more branches and ultimately way less performant.
@CianMcsweeney
@CianMcsweeney 9 ай бұрын
​@@BonktYT that doesn't matter for this scale of game, but if it does in the the future, his point is that this system is much more manageable for the type of game he's making which will make it far easier for him to pull out the performance critical parts into a faster path when needed.
@BonktYT
@BonktYT 9 ай бұрын
I mean yes, this kind of unpure ECS is easier to implement than a pure archetypal or sparse set-based one. But when the implementation is in place the interface of his approach and a well written, pure ECS would be the same, making all points about simplicity moot. IMO it would make more sense for him to 1. Use an better off-the-shelf ECS implementation like flecs. Or 2. Spend the time he is yapping and video editing about his objectively worse ECS implementation to actually implement a stronger ECS, because as I said, the whole argument of simplicity is only really applicable to the implementation details. A good, pure and performant ECS can have an interface just as simple and with even better debuggability and features (relations etc...) than his approach.@@CianMcsweeney
@hansottoelneff2345
@hansottoelneff2345 2 ай бұрын
My first time watching this video, it went mostly over my head. Coming back to re-watch this now after working for about 7 months at a game studio that uses a custom ECS system, everything you said makes so much sense! I'm really impressed with the way you're able to independently navigate through these ideas and reach the same beneficial properties but in your own simplified manner. I suppose it goes to show just how solid an understanding you have of these underlying properties, that you're able to see right through all the unnecessary crap it's been wrapped into. I generally prefer to keep code simple and procedural but sometimes struggle to close the gap between that and the ideas that are built on top of OOP and modern language features. Your approach in this video really inspires me to keep learning and staying true to this way of programming. Thanks for sharing your insight.
@joshuamanton
@joshuamanton 2 ай бұрын
This is one of the best replies I have gotten so far. I'm so glad my ramblings were useful to you :)
@hansottoelneff2345
@hansottoelneff2345 2 ай бұрын
@@joshuamanton I hope to hear more ramblings from you in the future ;)
@DylanFalconer
@DylanFalconer Жыл бұрын
Nice video! Glad to see a different perspective that offers practical solutions besides the mega-entity. The sooner we learn how to detect when we are over-engineering solutions, the better.
@nobu-sh
@nobu-sh 9 ай бұрын
I partially agree, though I won't detail my reasons. Context is crucial. ECS can either streamline or complicate your project, depending on your objectives. I find ECS beneficial for networked games requiring deterministic simulations, as it centralizes data management, simplifying netcode. It also facilitates writing tests to guarantee consistent game logic replication. However, ECS isn't suited for every game type.
@gamemakertim
@gamemakertim Жыл бұрын
Great points in this video. The concept of "breaking down a paradigm into components and only using the components you need" can be applied on so many levels.
@V000idZer000
@V000idZer000 2 ай бұрын
If your ECS needs a cast to get to a concrete component type, you got your ECS wrong. Homogeneous access and bookkeeping can be implemented nice and fast. Ideology or not, having different entity types is the same as having one component per entity to contain way too much data in one place. Each game feature requires only a small subset of that data, but all of it will be pulled into cache, evicting what you need to apply your feature to these entities. And if you like to multi-thread this, you will need to assure entire entities are exclusively accessed by each of your threads, rather than small separate components. However, if you are brave enough to slice the same entities from different threads, false sharing will be huge. At a first glance, this video seems to make sense, but the more I think about, the less I feel agreeing.
@trixer230
@trixer230 9 ай бұрын
This was pretty well spoken brother! Lots of great advice here!
@GingerGames
@GingerGames Жыл бұрын
This is a great presentation!
@joshuamanton
@joshuamanton Жыл бұрын
Thanks Bill :)
@poetic9234
@poetic9234 Ай бұрын
I'm struggling to understand where you draw the line between "composition" and "components". In my mind, they are basically the same thing- and all this argument over ECS/non ECS seems to just be a discussion over how these elements should be arranged/optimized/queried. Can you explain what features you consider to indicate that an entity is using "components" instead of just using "composition"?
@asmonull
@asmonull 9 ай бұрын
Big benefit of systems almost nobody talks about is testability - having well-defined dependencies means having well defined interface and responsibilities, and this makes maintaining solid automated test suite so much easier than most alternatives. Other takes on composition (say, dependency injection) cover that case, but come with their own drawbacks - in case of DI, it's often mix of memory fragmentation and performance overhead from multiple levels of indirection. With a bit more complex take on systems (having update systems limited to updating one component only, and having all other updates go through event system) I got level of testability I'm personally happy with - everything can be automatically tested both in isolation and interconnected, without unnecessary overhead (a read-only rendering system doesn't need to be loaded at all for automated tests of game logic etc).
@avwie132
@avwie132 4 ай бұрын
Game developers almost never write automated tests. Why? I don’t know. 🤷
@colincurrie7930
@colincurrie7930 11 ай бұрын
Haha! Love the Periphery you were listening to on Spotify. Didn't realize they had new tracks out! Is Zagreus a reference to Hades (game)?
@joshuamanton
@joshuamanton 11 ай бұрын
No idea! The song doesn't seem to be explicitly about Hades or Greek mythology in general so it's probably more of a symbolic name I think.
@MaviLeb
@MaviLeb Жыл бұрын
I always thought that composition leads to objects that have components - independent of ECS or any other architecture. This is just wording but it was confusing at first. I think adding complexity is an interesting thing. For a small game project I worked on, I made a small framework which kind of made it possible to have game objects with components like in unity (without ECS). It has certainly added some complexity but focusing only on implementing the features that small project needed, it made development much faster and easier than without the abstractions. Having hidden complexity can enable you to be much faster in developing a product by using some good library. Sure, it will also cost you something but it might just make it that much easier to implement all the necessary features for your project. The component based architecture unity uses, enables lots of inexperienced programmers or even artists to make games they could not make without it. They probably won't have the most performant product in the end but they have something working. And by using unity or any other engine they probably use a lot more hidden complexity than you even would be able to produce with your own engine/framework. I think the composition over inheritance approach of ECS implementations is the most important factor. This makes engineering an object easier for less experienced people, because it forces them to think in different components instead of the big bloated player object which can do everything. At least if they try to keep to the principles. My take is that this is the biggest selling point of It, because it sounds so easy and straight forward to compose a complex game object using relatively simple components. And people somehow seem to think that is directly tied to having an ECS, which you correctly showed it is not.
@Spartan322
@Spartan322 Жыл бұрын
I've always found it interesting how devs (especially the ECS, DOD, and component fanatics) tend to forget that you can make OOP Composition systems too.
@JavaJack59
@JavaJack59 Жыл бұрын
This is orthogonal to the (solid) content of the video: the audio level seems a bit low.
@systemhalodark
@systemhalodark Жыл бұрын
It's not because one acquires a hammer that every problem will become a nail.
@matejzajacik8496
@matejzajacik8496 6 ай бұрын
A single struct to represent all entities (or as I call it -- actors) is exactly what I've settled on after two ECS/OOP shipped games and one in the making. For the player, I simply have a special additional global struct to hold all that extra data; it's not part of the actor struct. The most straightforward and simple actor architecture I know. Compared to ECS, which is, in my experience, heavy, verbose, and slow to get going, with questionable benefits.
@peterino2
@peterino2 Жыл бұрын
Very thought provoking. I had some similar conclusions recently myself. I intended to do an ecs in my game engine but instead stopped halfway, at just a way to create base entity types without components. This was because I shifted focus from making the engine to actually finishing my game for a rapidly approaching timeline and found that I really didn't miss much from having a formal ecs. Rather just a loose set of systems managing individual entity types with unique identifiers was more than sufficient for completing a fairly complex game.
@Sweenus987
@Sweenus987 Жыл бұрын
I always thought the whole point of ECS was just for its parallelisation ability. Lke using CPU-only OpenCL in a much easier way.
@alexanderduk5884
@alexanderduk5884 Жыл бұрын
I would agree that ECS is not a golden bullet and a good programmer can write code which would be faster, though, it is not something any junior -middle programmer will be able to do. Also, I feel like you have a small misconception about how ECS works. This shows in the cache locality discussion and in the first example of "ignite all entities" The problem with having an entity class, is that with time, it becomes a lot bigger. And in the code you showed as the first example, you iterate over the array of entities, meaning you get all the fields of the entity, except the two you actually need (aabb and flags). And what ECS does, is arranges data depending on the systems you have automatically, so a system iterates over arrays which only have the data that system needs. This can be a huge difference if you game has big entities, and most of the times, entities tend to grow a lot. Also worth mentioning, that existing ECS systems differ quite a bit, and some of them can be faster to create new entities and slower on iteration and Vice versa
@alexanderduk5884
@alexanderduk5884 Жыл бұрын
Also ECS helps with data organization in some sense. Taking a look at your code on 11:15, you have an animator object which inherits baseEntity. Well, it does not sound like an animator should have a local_position, but now you do due to the inheritance. And now you have to carry that extra unused data everywhere. And any new data added to base entity will just make your animator bigger even if you don't need it. You might say that's you will be carefull but realistically, if you have a team of at least 10 people - this will happen. As a proof, take a look at UE5's BaseActor (which everyone inherits) which is huge and has a ton of non usually useful conponents
@joshuamanton
@joshuamanton Жыл бұрын
Thanks for the comment! The first example with the megastruct wasn't intended as a "this is how I would implement this in a huge game where I need to be careful about cache," it was just demonstrating that components and composition are separate concepts. One thing you could do (again, iff you discover that you need to improve your cache performance through profiling (which most people do not do, they just blindly copy whatever the flavor of the month thing is)) is pull that AABB out as a separate entity type and then iterate over all AABBs instead of all entities. > Taking a look at your code on 11:15, you have an animator object which inherits baseEntity. Well, it does not sound like an animator should have a local_position, but now you do due to the inheritance. The Spine_Animator is also the renderer, so it having a local_position is hugely valuable for offsetting and scaling it. This is something you often end up wanting in many "components" is the ability to move, rotate, and scale it. In this case, it's just an entity type, so my editor's gizmo tools work with it automatically, hugely valuable! > And any new data added to base entity will just make your animator bigger even if you don't need it. Sure, but if I profile and notice that this is a problem I will do something about it. Not sure what the problem is here. Some data you might want to pull out into separate storage (by pointer or index) if it's not touched often, other data you could just make it into a sub-entity type and have it as a child for the things that need it.
@megac0ffee
@megac0ffee Жыл бұрын
People see Unity's DOTS and think ECS is the ultimate solution for their own engine, when in reality ECS is a general solution to problems which may or may not exist in your game. In many cases it'll run slower and be harder to maintain than a solution hand-tailored to your game. Having said that, ECS is far more than a compression algorithm. One of the big benefits is existential processing, which avoids the classic mess at 2:21.
@simtrip6452
@simtrip6452 Жыл бұрын
I'm personally having a realisation of something like this as a Unity developer. I have zero experience with Unity.Entities and actually very little desire to use it., but I'm simultaneously very interested in ECS (or actually much more these general concepts about contiguous data vs random access, moving away from GameObject/MonoBehaviour spaghetti etc.) Honestly just from a developer productivity and control standpoint more than a strictly performance one. I'm noticing there is a distinct lack of resources on this which don't just assume you're going to import the Entities package and use an entirely new pre-made API, which to me brings with it all the same concerns I have with the standard GameObject workflow, mainly boiling down to it being a general-purpose package that can't make any assumptions about the kind of game you're trying to make. Videos like this are great, even if they aren't directly applicable to C#/unity. But the idea of taking ECS concepts, applying them to Unity but NOT using Unity.Entities and DOTS is proving a very hard thing to research.
@costelinha1867
@costelinha1867 Жыл бұрын
While it was fun to use Bevy ECS on my asteroids clone, now that I watched this video, I realize, I probably didn't need... to use the ECS... I mean, it's a literal asteroids clone. There's literally only like 3 things in the entire game: Asteroids, the player ship, and the projectiles the player can shoot. You can probably acheive the same result using classes, and you may not even need to use inheritance. But at the same time it was fun diving into another design pattern.
@verified_tinker1818
@verified_tinker1818 Жыл бұрын
My rule of thumb is to use Macroquad for simple games and Bevy for complex ones. (If I'm limiting myself to the Rust ecosystem, I mean. Otherwise, you could replace Macroquad with, say, Godot.)
@deadvirgin428
@deadvirgin428 Жыл бұрын
I mean, absolutely nothing wrong about using an engine with ECS, that's the point of using an engine, you get all the benefits from ECS without having to worry about the complexity behind it. I think this video is more about *implementing* ECS and why you don't need to do that for all your games.
@jomy10-games
@jomy10-games Жыл бұрын
The reason I use an ecs is because I find it easiest to manage
@joshuamanton
@joshuamanton Жыл бұрын
Easiest as opposed to what?
@jomy10-games
@jomy10-games Жыл бұрын
@@joshuamanton as opposed to more object oriented designs. I like in an ecs you can define an entity with some components and loop over all those that can for example take damage when touching another entity.
@0ia
@0ia Жыл бұрын
Noting problems are superstitious until measured is good, I see too many people (and myself) preparing for things that would never become an issue :) Helps a lot to hear your analysis! I'm going to further the idea "if you _can_ avoid a complicated system, that's a huge win" for my projects - because I remember hearing a nice quote that "programmers are not allergic to complexity." The audio could be louder - I had to turn my audio up to hear you well, and then I got jump-scared when I listened to something else.
@joshuamanton
@joshuamanton Жыл бұрын
Programmers love complexity when they're the ones writing it. When you know the system it's very difficult (or impossible) to think about what it looks like to a newcomer, having to learn it all from first principles. Yeah good call about the audio, will fix that in future videos :)
@0ia
@0ia Жыл бұрын
@@joshuamanton Very nice addition, I like that!
@barterjke
@barterjke 3 ай бұрын
I came to a similar conclusion on my own. I didn't learn the theory behind all of this and initially just tried to replicate all too familiar system from unity. I don't like oop to much, and the way c++ works it's pretty annoying to pre-declare all the dependencies for each entity. So i figured: component can hold any data, and can be child of or a parent to any other component, but no methods allowed. And all the logic is just functions which accepts components to manipulate on them (the idea is similar to systems, but not quite). This way it's all nicely structures: first data, then logic, and then dependency logic at the very end (which decieds how to initialize, store and query the data). And I also ditched the extra concept of the entities & inheritance. And in theory it can be even more perfomant then ecs, because inheritance can contribute to cash misses.
@joshuamanton
@joshuamanton 3 ай бұрын
Your thing about components being able to parent/child other components is exactly what I have in my engine now, though I call them entities instead of components :D I've considered switching to a different name entirely like `Atom` or something. I still have a liiiiittle bit of inheritance right now but it's basically always one level of inheriting. Hero is a subtype of Entity and it might have a Sprite entity as a child of it so that the sprite of the hero moves wherever the hero moves, etc.
@rmt3589
@rmt3589 Жыл бұрын
Singlehandedly answered all my questions, and made my decision. I'll be going with OOP instead of ECS. Now just to research frameworks.
@edwoodgrant
@edwoodgrant Жыл бұрын
I mean if I understand correctly (hopefully), you are describing a structure that is very similar to what the Godot engine does. A type system organized hierarchically (that can be extended with scripts) and a bunch of systems that iterate through this hierarchy and execute it.... very similar to an HTML render engine I'd say. Which is perfectly fine of course... although maybe I think you could call your system aggregation based, instead of composition based? (both which achieve the same objective by the way). But yeah in case anyone is interested on the Godot approach, look for the "Why isn't Godot an ECS-based game engine?" article that you can find on the web.
@bradocksolo
@bradocksolo Жыл бұрын
I was looking for this comment. I agree, the solution presented in the video is very similar to the Godot node system, which is a good thing!
@schelney
@schelney Жыл бұрын
your suggestion to store all the indices to various arrays in Entities is really just not good For one, you lose the advantage of flexibility because you can't iterate over 2 units of data at once (assuming the arrays are contiguous and not sparse). As an example, let's say you want to iterate over the renderable draw texts, if you just iterate from 1 to the length of the draw text and index both the draw text and the renderable, the data you're accessing isn't necessarily related. Two is you now need to manually manage and keep in sync the array with the rest of your entity pool. Effectively, you're manually performing an ECS algorithm The thing about the mega approach is that it is literally an unoptimized ECS. You have all the data stored in one struct and flags that determine and interpret the meaning of that data, this means that you're 1. wasting memory, 2. having to iterate over the entire ECS to just get a few entities. I agree with you, this just isn't a big a deal as it seems. But also, it is sometimes a big deal, and when it is, you should invest time into making an ECS. I think another issue with this approach is the lack of type safety from your data. Your entity stores absolutely everything, and from a glance, it can be difficult to gauge what a specific part of the entity is and whether a specific entity actually has the relevant data. A possible solution without going towards a full ECS is just splitting out the big Entity struct into separate arrays which are of length max entities, or of the maximum amount that specific component can have. An index of 1 corresponds to the same group of data in every array, this is a balance between the big megastruct approach and an ecs. This lets you get some of the type safety back, but still has the issue of needing to iterate over everything since the array is sparse. But honestly, an ecs isnt that complex of a thing. It's actually pretty simple if you're doing a sparse set based one, and it just overall makes your life a lot easier. Especially in languages without inheritance.
@stefdevs
@stefdevs Жыл бұрын
Nice vid! My project is currently in the 'entity megastruct' state and I want to break it into multiple entity types, but I'm not sure I can justify it since the game play is about as simple as it gets. I'll probably do it anyway because I'm bad at managing my time and it will be satisfying to do. Also, I'll note that bucket arrays are awesome; it's really nice being able to just take pointers to entities instead of indexing by ID. Maybe you have some reason to prefer IDs?
@joshuamanton
@joshuamanton Жыл бұрын
I definitely do take pointers to entities! It would be impossible to advance the game state meaningfully otherwise! However IDs are useful because on a frame boundary is when I go through and actually destroy any entities that were marked for destruction during the frame. So if you are holding a pointer to a random entity across a frame boundary, that entity could be destroyed and a new entity might take its place in the array and there's no way for you to know that. A generational index scheme solves this problem. What I have implemented currently is effectively a bucket array but instead of allocating a new chunk in order to "resize", I use VirtualAlloc to resize the array in place so no pointers are invalidated, yet the array can grow as needed.
@RockTo11
@RockTo11 Ай бұрын
Too much surface-level info. here. It is not all about cache-line efficiency. In this code, I see far too many conditional statements. Branch mispredictions will cause threading issues. Poor memory layout will cause cache evictions due to false sharing. Packing everything together into a bit-field or similar clearly necessitates this (per the code on in this video). Then when you go down into this paradigm, after a while there will be unsolvable problems (without major refactoring)... because the instruction pipelines will have tons of useless instructions which need to be drained. The super scalar out-of-order instruction execution will be unable to use such optimizations - and this is all due to long dependency chains.
@xbmarx
@xbmarx 5 ай бұрын
Over a year later, I'm coming back to this to say I finally came around and I'm pretty much removing ECS from my game too. 🤣 I think ECS is fine if you are making a completely generic engine, where you don't even know what type of game people will make with it. But I want something laser-focused to make something narrow, so I don't need or even want to support arbitrary behaviors or systems.
@s0lly
@s0lly Жыл бұрын
Let’s call this “Entity Component Chaining”
@SpookySkeleton738
@SpookySkeleton738 Жыл бұрын
Periphery spotted. I already agree with you. EDIT: And after watching, I still do. It's very easy for people (myself included) to end up getting the hammer/nail problem, and it gets worse when people "marry" a given data structure or technique, after that it becomes pure ideology.
@bertrodgers2420
@bertrodgers2420 Жыл бұрын
Thanks for this, I was hoping you could help though, how would you add custom behaviour to these entities, let's say I have an NPC that should teleport me when interacted with, where would that logic sit. It seems sort of impossible without using some kind of inheritance doesn't it? As I don't quite see how I could add a Teleporter object into my []Entity array
@joshuamanton
@joshuamanton Жыл бұрын
I don't have a problem with subtyping if you don't go psycho with it. I do one level of inheritance for my game; so I have a base Entity struct and then Teleporter would inherit from that. The all_entities array is an array of a union of all the entity types so the teleporter can live in there alongside other entities of different types. If you wanted your player to teleport on touching a teleporter the basic thing would be to do Player *player = ...; for (int64_t i = 0; i < all_entities.count; i++) { Entity *other = &all_entities[i]; if (other->type == ENTITY_TELEPORTER) { Teleporter *tp = (Teleporter *)other; if (is_overlapping(player, tp) { player->position = tp->exit_portal; } } }
@bertrodgers2420
@bertrodgers2420 Жыл бұрын
​@@joshuamanton That makes sense, I think that is the problem I'm having as Go can't treat embeded structs as their parent class, so I'd need an interface inbetween. I get that flow better now though thanks, so you'd switch the logic round, as where I'm putting the interact logic in the Teleporter class, you'd put it in the player
@Spartan322
@Spartan322 Жыл бұрын
This is closely tied with the confusion that people think Object-Oriented Programming and Data-Oriented Design are exclusives but in reality they are not, there are some times where you can have DOD or OOP and not the other, but there are also cases where you can and may even in fact do both at the exact same time, just as Composition is not exclusive to an ECS, Components system, or other forms of DOD, why then should you expect enforcement of these behaviors, plenty of big name game engines don't even take advantage of ECS, traditional Unity and Unreal absolutely don't, Source doesn't, and any UI toolkit doesn't, sometimes a composition system may even not be suitable, or sometimes it could be, it depends on the application as well. The sign of a true professional too is using the right paradigms for the right task or problem at hand, (that doesn't always mean the fastest or "most optimized" as optimization is not the end all of software) not trying to fit a paradigm you love into every problem, and unfortunately that's the most consistent problem among the DOD, ECS, and general component folks. As an example of OOP Composition look at Godot and how its developers advise you to develop your projects.
@gabe3538
@gabe3538 Жыл бұрын
Great video! You bring up a lot of good points, but you seem to be arguing against _implementing_ an ECS yourself. If you use a premade library like entt (that's already doing all the hard parts and giving a single header to get all the functionality out of the box) I wonder how much of your cons against ECS still hold true :)
@joshuamanton
@joshuamanton Жыл бұрын
All the cons still exist because the complexity is still there even if you choose to ignore it. In fact I think it's worse because you're taking on a large dependency you don't understand the implementation of for a system very core to your game.
@gabe3538
@gabe3538 Жыл бұрын
@@joshuamanton if we use this standard, then you should throw out the OS, CPU, GPU, assembler, programming language and everything. Those add hundreds of millions of lines of code and are core pieces to making your game run, after all. Atari games were coded directly into the hardware so we may as well do the same :D We don't do that though, because you have to draw a line somewhere haha. But, there are pros and cons to using a library beyond additional complexity. I've done all the methods you've mentioned in this video. I've used entt, I've coded my own ECS, and I've used simple arrays with indexing directly into the components. I've come to find that using a premade library saves a ton of maintenance for me, works better 99% of the time, and requires much less effort on my part. Last thing I want to mention is different libraries absolutely have varying levels of complexity that they add to your project. But you can always limit the complexity by wrapping the library. I've used ffmpeg lib, AV1, stb_image and several other libraries as some examples. Ffmpeg and AV1 sucked at providing a nice API, and it took hours just to get it to work right because of how leaky their API was. stb_image is super simple and takes a couple minutes to add to your project and use. These are all fair points that should be taken into account imo rather than just discounting a dependency because it adds complexity. The entity management system is a central part of the game and essential complexity that will be added no matter what. The hard part is figuring out how to manage it, and the pros/cons definitely change if you're _writing_ the library vs _using_ a prebuilt library :)
@joshuamanton
@joshuamanton Жыл бұрын
​@@gabe3538 > if we use this standard, then you should throw out the OS, CPU, GPU, assembler, programming language and everything I make games. If these things don't exist then I can't make games, I would have to do something else entirely. A decision to not use an ECS library doesn't limit my ability to make games, so the argument doesn't work. > But you can always limit the complexity by wrapping the library This adds MORE code. How could it possibly reduce complexity? That doesn't make any sense. I do of course agree that different libraries have different levels of complexity, and indeed I do use some libraries as a matter of convenience to save some time. But that's not a _good_ thing. It's not a good thing that I am bringing code I don't understand into my project; it is a concession. I would be strictly better off if I understood 100% of the code I depend on. As a group, programmers seem to take pride in their ability to cobble complexity on top of complexity and then call it engineering. This is the opposite of the right thing. > The entity management system is a central part of the game and essential complexity that will be added no matter what No. Different implementations have different amounts (and different kinds) of complexity. That's what the whole video is about. Figure out the properties you actually need and implement those. In doing that, you limit your complexity while meeting your requirements. Grabbing an off-the-shelf fully-general implementation might indeed solve your problems but it also solves a ton of other problems you don't have, and that's not free. You pay a runtime cost because the CPU is wasting time running code that solves problems that you do not have. If there are bugs in the library, YOU pay that cost. If the library is slow, YOU pay that cost. If the API isn't exactly what you need so you have to add cruft to map your game onto it, YOU pay that cost. If you don't know how the library works, YOU pay that cost. If you want to use an ECS library because you like it that's fine, it's just not the level of analysis I am working at here, and I don't believe it to be good software engineering. The problems don't go away because you've chosen to ignore them.
@gabe3538
@gabe3538 Жыл бұрын
@@joshuamanton it's funny because I agree with almost everything you've said here. All I'm saying, and it seems like you're saying the same thing, is there are tradeoffs when choosing to use a library vs rolling your own. Ignoring those tradeoffs doesn't mean they don't exist, and not taking those tradeoffs into consideration while analyzing this problem is not engineering either. The one thing I've learned about programming is not to be dogmatic about anything, because there are exceptions to every rule. A healthier analysis would determine if these tradeoffs are worth it along with the rest of your analysis ¯\_(ツ)_/¯
@joshuamanton
@joshuamanton Жыл бұрын
​@@gabe3538 Indeed they are tradeoffs, I just lean more towards them not being worth it in more cases than other programmers seem to.
@ikyyntts7807
@ikyyntts7807 Жыл бұрын
hi, what theme do you use? it looks amazing and i wanna use it myself
@omgnowairly
@omgnowairly 3 ай бұрын
Something doesn’t sound right. Goes from handwavy implementation details to academic specification of issues too quickly.
@lukagarner
@lukagarner 8 ай бұрын
The problem in this video is the rant about games while the title promised a rant about game engines. Games and game engines are not the same thing! I agree that a lot of games probably won't need ECS, so you shouldn't go through the hassle of implementing it. But in something like a game engine, your systems HAVE to SCALE. An engine is supposed to allow you to make any game, which requires crazy levels of flexibility and your solutions aren't for these kinds of applications, clearly. Otherwise a great topic for a video.
@maxwellsmart3156
@maxwellsmart3156 Жыл бұрын
Thanks I really enjoyed your video/talk. I know nothing about ECS as I was just introduced to the acronym recently. You're very clear but the pace is a bit fast for me. No worries that's what re-runs are for. Now I have to find out what the term component means in this context.
@handmadegamesdev
@handmadegamesdev Жыл бұрын
I'm very new to game programming, and even though I haven't attempted to program an ECS, I got a lot out of this video. I've already sensed that the programming can quickly get very complex beyond a very simple game, with many cross-cutting concerns. The question of how to deal with this as I progress to more complex games is always in the back of my mind. Avoiding the urge to generalize everything in a single Entity struct has greatly helped, but I've wondered if there was another way. Your examples have shown me how to use a single Entity struct but get the differentiation without too much bloat: bit flags and unions for tracking entity type. Thanks!
@anima94
@anima94 Жыл бұрын
Probably a noob question but at 2:30 why do you use this flag enum system instead of individual booleans? Is it just to avoid clutter? My guess is this has to do with using structs instead of objects?
@joshuamanton
@joshuamanton Жыл бұрын
It is just to avoid clutter and keep things small. A boolean is a full byte, so if you have 8 toggles then that will take up 8 bytes of memory. If instead you use flags, you can reduce the required storage to 8 _bits_. So 1/8th the size. This savings is important because the smaller your data footprint is, the faster your code can run because it's not having to fetch stuff from memory all the time! > My guess is this has to do with using structs instead of objects? "Object" is a metaphysical category that doesn't have any physical form. A struct can be an object and a class can be an object. The "objectness" exists only in the programmer's mind.
@anima94
@anima94 Жыл бұрын
@@joshuamanton oh that makes total sense, thanks! For some reason I had in my head that a boolean is just a bit eventhough when I think about it that shouldnt be the case because we adress via bytes
@kieren2870
@kieren2870 Жыл бұрын
Enjoyed this a lot. Good exploration of ECS. Lots of well thought out points. My one disagreement is in regards to cache locality. You dismiss the idea that ECS can provide performance advantages in terms of cache locality because components are often just randomly scattered on the heap. However, most of the ECS systems that I have looked at store their components in contiguous arrays. e.g. entt, Unity DOTS ECS.
@joshuamanton
@joshuamanton Жыл бұрын
Hi there! I assume you're talking about 7:57. If so, I didn't say that components are scattered on the heap. I said that people who say "ECS is good for cache locality" are responding to the object-oriented way of doing things where objects are scattered on the heap. The idea being that ECS isn't necessarily "good" for cache locality, it's just not obviously terrible as OOP is. I then go on to say that you can get the same "good" locality by just putting your entities in an array instead of randomly heap allocating them. If you have to process 1 megabyte of entity data, it doesn't really matter if that's one pass on a big array, or 10 passes on 10 "component" arrays. Any wins here are marginal and the real speedup comes in the form of the auto-parallelism as I went over around 7:33. Let me know if this clears anything up or if I've missed something :)
@kieren2870
@kieren2870 Жыл бұрын
Ah, you are right. I missed that you were talking about OOP and not ECS at this point. My mistake.
@kulkalkul
@kulkalkul 3 ай бұрын
​@@joshuamanton I was going to say the same thing with the OP about cache locality, but I'd like to add some bits here instead of creating a new comment. While it is true it is still way better than randomly heap allocated objects, I wouldn't say the impact is negligible. L1D cache of most of the chips are 32kb. Iterating over a list of bigger than L1 cache is probably negligible due to prefetching & time involved in operations. So, entities not fitting into L1D isn't much of an issue. But, imagine having random access to the entities, which is the case with entity-entity collision, where O(n^2) loop is required. Even though you can use accerelation structures to reduce the required iterations, the way it works causes random accesses within the entity array. So, in that case, say, 500 128byte size entities randomly accessed would certainly cause some cache misses. So, it is a trade-off in my view. I have a question. How's the branch predictor's reaction to having lots of branches for every entity, in your experience? I instinctively avoid branches, so seeing lots of branches in a hot path makes me anxious. Usual reply to this is "profile", but profiling a real case scenario requires a real case scenario, which I don't have right now. So I'd be grateful if you can share your own experience with it. Many thanks.
@Bevzthejcs
@Bevzthejcs 3 ай бұрын
Good video. I've been at this for many many years and seen many coding "paradigms" come and go... ultimately it only ever boils down to this... do it the way that seems sensible to you at the time. Don't overthink things. Some coders are zealots and they are very vocal about their chosen religion, at least until the next big thing comes along; these people lurch from one coding fashion to another and will flame anyone who speaks ill of it. Listen to what they're saying because sometimes there is gold there you can use, but don't drink the kool aid, take what you need and move on. Do what seems logical and sensible to you at the time, and above all remember there are NO POINTS for impressive code unless you're working in a huge team, if you're a lone coder or in a small team, the only points you get is for shipping no-one cares what your code looks like. No-one. This is why this is a good video, i think you present a practical view of what a strict ECS system gives you and doesn't give you and you've presented workable alternatives.
@KiaAzad
@KiaAzad Жыл бұрын
I wonder: What's the threshold number of objects that justifies going for more threads?
@RenderingUser
@RenderingUser Жыл бұрын
but it does depend on how heavy the process run by each object is sprites? a few hundred thousand if its physics objects, then yea a few thousand id personally run tests with both single thread or multithread and see which one is better
@AChannelINeed
@AChannelINeed 8 ай бұрын
Dude be like: "I don't need ECS for my 2D 8 sprites game". Good for you lol.
@joshuamanton
@joshuamanton 8 ай бұрын
Yes you have correctly identified the thesis of the video. Don't solve problems you don't have. Most indie games don't need anything resembling an ECS.
@techpriest4787
@techpriest4787 5 ай бұрын
I chose a middle ground. But first regarding composition. I use Rust because of that as a language in the first place. And instead of entities and components I use what I call Prefabs Nodes Systems. I still use systems for multi threading and plugins. I did not like the components limits of Bevy that only one component of one type can be added to the same entity. And that in the end not all can be done in parallel in the first place and even Bevy had to use entity handles too. So I just use node handles dalways instead of having to use entity handles and then having to extract the damn component anyways. So a group of data is essentially a prefab now instead of a entity. Though. Bevy seems messy. Flecs if I am not mistaken can use more than onen component of the same typenon the same entity?! Even events are systems in my Prefabs Nodes Systems (PNS) application kernel.
@BlazPecnikCreations
@BlazPecnikCreations Жыл бұрын
Please make more rant videos, but like, with louder audio Subbed Also, can you make a jai-programing language review/thoughts video?
@joshuamanton
@joshuamanton Жыл бұрын
> Also, can you make a jai-programing language review/thoughts video? It's very very very good. I might do such a thing when it's closer to public release :)
@FlameEngineDev
@FlameEngineDev Жыл бұрын
Thanks for a very good video! Your resulting engine is quite similar to how we do things in the Flame game engine too. :)
@leonsonstwie4816
@leonsonstwie4816 7 ай бұрын
This might have been the best video about software developement in general I have seen
@joshuamanton
@joshuamanton 6 ай бұрын
Thank you. :)
@SergeyLergDev
@SergeyLergDev 11 ай бұрын
Great video, you've put it nicely what I had on my mind about ECS. Subscribed. And hello from the Jai world.
@radioleta
@radioleta 11 ай бұрын
How did you get access to Jai?
@avwie132
@avwie132 4 ай бұрын
You need to pay to get access
@mastermati773
@mastermati773 Жыл бұрын
Fantastic video. Thought provoking.
@quickdudley
@quickdudley Ай бұрын
After watching this video I'm inclined to agree that the thing you're calling ECS isn't that great an idea. On the other hand the only slightly related thing that the Bevy developers call ECS seems pretty neat.
@minutesock9649
@minutesock9649 5 ай бұрын
0:19 Periphery spotted.
@ihydf
@ihydf Жыл бұрын
It took this video 8 minutes to get to the only real reason people are embracing ECS.
@joeblo1111
@joeblo1111 Жыл бұрын
Hey, I noticed looking over your channel that you have used Odin and are currently using Jai. I was wondering if you think you've used either enough to comment on the pros/cons of the two (vs each other). Which would you recommend and why? It would be a useful video for people who are in the "anti-OOP camp" and are showing an interest in those languages in particular.
@joshuamanton
@joshuamanton Жыл бұрын
Having used both for multiple years each I would say that they are different enough that a comparison doesn't make much sense. They are superficially similar in terms of syntax but the feeling of programming in each is very different. In short I would maybe say that Jai is to Odin as C++ is to C. C++ is a complete dumpster fire in practice but I just mean in the way that it allows a much higher-level of expression for the programmer. With Odin on the other hand, the design feels very focused and finely tuned to target a specific way of programming. I love and respect both :)
@nangld
@nangld 7 ай бұрын
Good argument!
@DetectivePoofPoof
@DetectivePoofPoof Жыл бұрын
Very good video, this is the type of thing I would like to see a whole lot more of.
@kdngrus
@kdngrus 9 ай бұрын
PERIPHERY MENTIONED RAAAAA
@Rockyzach88
@Rockyzach88 4 ай бұрын
I'm going to learn a lot from this channel.
@marksmithcollins
@marksmithcollins 9 ай бұрын
I totally agree. There are so many andies out there.
@danieljenikovsky9455
@danieljenikovsky9455 Жыл бұрын
I really like your videos! Good work.
@joshuamanton
@joshuamanton Жыл бұрын
Thank you Daniel!
@BigJMC
@BigJMC 10 ай бұрын
I get your point but you don't need ECS, it's mainly a middleware system that is incorporated for your editor portion of the engine to allow users to create more modular workflow, improve accessibility and to cater for a wider use case, but you can absolutely just create a game built directly off of the engine, It's just going to be very tightly intertwined.
@dafedidi
@dafedidi Жыл бұрын
I really took the time to listen to the video (three times) to fully understand what you mean. I agree to most if not everything of what you said, but there is some aspect of it that might require some thoughts. Let me explain. The moment you get elements out of the entity and refer to it, by any means - id or something else -, get us to the same point as components and entity. You can turn them around, call them something else, but it's effectively doing the same thing: make coherent bags of data somewhere else that you can refer to. And it gets us the same problems as components would (because they are the same idea). For example, the code will be plastered with calls such as get_x(e.character_id). You will have to do checks on the return value. You will need a generation index for these. Whether it's system doing it or anything else, we got to the same point. Composition for the entity's data put at an other place. In the end, the megastruct is very nice (or the inheritance one as well), like Godot did and some other engines. I agree it's way less complex. And it's a different approach to most EC and ECS designs. Thanks for the video, it was quality one that are more and more rare in these days! :)
@joshuamanton
@joshuamanton Жыл бұрын
Hey Daryl, thank you for the comment! I'm glad you enjoyed the video despite your criticisms :) The whole idea of what I have here is that I am _not_ pulling any data "out of the entity". A Hero in my game for example is a single struct. It has one child entity that is it's rendering data but that is actually somewhat good to separate out anyways because during the render pass I won't be polluting the cache with a bunch of gameplay specific Hero data. And I can reuse that entity type for other things. You need the generational index and the get_whatever() calls no matter what you do, really, since entities can be destroyed across frames you need some way to detect that that has happened (at least in the case where the holder of the handle isn't in control of the lifetime of the entity they are holding a handle to). It's just a matter of how much you have to do that stuff. For example, since I just have a single Hero struct, I don't have to do these get_whatever() calls for every tiny chunk of information like position or health or what have you, as you would have to do in a more component-y system. My solution does "smell" a little bit component-ish but because these are just labels we give to properties, or groups of properties, and any system that allows for composition will "smell" a little bit component-y at a high-level. The important part is that underlying implementation is much simpler than an ECS or even EC solution, because mine is just "E". Thank you again :)
@thygrrr
@thygrrr Жыл бұрын
ECS are definitely NOT good for designers. They are very expressive and good for worlds with lots of actors. The main benefit you get is, if you have a good scheduler, the chance to massively parallelize execution. And its all it cracked up to be.
@pup4301
@pup4301 Жыл бұрын
I just switched to a global list of data that can be queried in a multi-threaded way. Then I added the functionality part by taking a reference sample to the global list then operate on that. All in Rust.
@echoptic775
@echoptic775 3 ай бұрын
Pfff, you didnt make a new language to make your game engine? Mr blow would be disappointed
@fernandolener1106
@fernandolener1106 Жыл бұрын
The size of the functions you show in the video clearly states your programming knowledge. One day you will learn how to program. It took me 10 years to achieve it.
@joshuamanton
@joshuamanton Жыл бұрын
I've been programming for 12. It's okay, you'll get there one day 🙂
@Pandanubex
@Pandanubex 6 ай бұрын
Very good video
@hectormejia499
@hectormejia499 5 ай бұрын
In other words, start with the simplest possible solution that will get you to the goal the fastest, change it only when necessary. I've been coding for around 10 years, I feel my skills and ability to get stuff done increased drastically when i actually internalized this. Great video!!
@SuperG316
@SuperG316 Жыл бұрын
ECS is a tool and with data oriented a great tool. It isn’t compression it is decouple data from code. And the problem is not complexity it is idiots who think ecs is like a particle system or using it to make a authentic phong game. Then it is over enginering. The strengt of ECS DOD is wen you make a large scope game like homeworld or Xseries a rts game or ARMA milsim The strengt is that you manage complexity. Due to decoupling the code that matters is without side effects whitin that system and the component it mutates. For a game like arena shooter clasical cod ip , it is borderline overenginering. It is the best solution if you encounter c++ inheritance diamond like in ARMA you can easy implement a tank and a truck without, but you can have a halftrack armord car. For large studio who use lot of middle ware that can complicate ecs. It is huge difference entity component vs ecs . Avoiding inheritance in oop is good think because inheritance isn’t the default solution for good oop. The key problem with ecs is the huge experience with OOP most dev has SOLID understanding of oop. But are noobs in data oriented. And its difficult if dod feels weird but you know how to do it in goog oop. They start early on mixin oop with dod. Oop kills several benifits of dod and then it become a mess. No problem in small games but large scope game wich can use ecs get mess. Ecs is also not premature optisation. Optimisation in ecs is re-arange data to match optimale memory acces pattern by profiling. It is than only within one ore few systems. Also because of the decoupling multithreading within system is easier to do because non shared mutable data. Also if you need performance modern cpu are multi core. So you need build engine that uses a good multithreaded architecture and multithreade render api like dx12/vulkan.
@SimGunther
@SimGunther Жыл бұрын
Things like data oriented design and focusing on making everything "structure of arrays" isn't meant to be the first step in engineering a solution. Remember, ABM: Always Be Measuring You can inspect your loops and see what type of structure you need for the input/output array based SOLELY on the data you touch in a single iteration of the loop after you infer that this part of the code is slow in general. Don't just blindly have an array of Xs and an array of Ys without figuring out whether vectorize basic operations actually speed up your basic logic. It's best to trim the bloat before going in on special performance refactoring magic that could make the code much more unreadable for not significant speed gains.
@joshuamanton
@joshuamanton Жыл бұрын
I didn't mention SOA or data-oriented design anywhere in this video I don't think, so I'm not sure what youre going on about
@SimGunther
@SimGunther Жыл бұрын
@@joshuamanton I see an implicit structure of component arrays whose (relative) indices are stored in each entity in the ECS; hence, the reason why I mentioned SoA :) ECS is nothing more than an organization tool that makes it more possible to use DoD principles in the iteration of element updates. It doesn't mean that ECS is necessary at all to either organize the data to best utilize cache locality or do solid parallelism based on dependency graphs. Think of this system as a dial that some people experiencing the "Dunning-Kruger effect" will crank up to 11 as an exercise in mental self-indulgence without thinking to themselves whether they "should" based on tangible measurements or improvements in code readability.
@bungieanimator
@bungieanimator Жыл бұрын
Is Jai even out yet?
@joshuamanton
@joshuamanton Жыл бұрын
Not yet. It's in closed beta.
@cprn.
@cprn. Жыл бұрын
So... If you get ECS for free as a library or a framework and all you have to do is define what's a component + register systems and - boom! - everything magically works... Then your arguments of investing time in something you don't need will be irrelevant.
@joshuamanton
@joshuamanton Жыл бұрын
This is only true if you live in a fantasy land and don't care about the overall complexity level and performance of your program as a whole. Everything "working" is step 1. Libraries are not "free," they are debt you take on and often have to pay back with very high interest later on. Especially if you are making something non-trivial.
@cprn.
@cprn. Жыл бұрын
@@joshuamanton Fair point, libraries aren't free and I'm not familiar with your work so I don't know the complexity of your GE. I've seen your video because I was researching Bevy which is an ECS game engine in Rust. So far it seems "free" but it's in early stages. I wish someone did something big with it and share their experience so I'd know how much debt there really is.
@Lycam
@Lycam 7 ай бұрын
bro, i cant hear anything, its a lecture for ants
@cheerwizard21
@cheerwizard21 Жыл бұрын
So basically your arguments are very specific to your needs and your requirements. You didn't really objectively answered why is concept of "component" and "system" bad, as bad as you need to remove them from engine. Making a flags for each state of entity and then iterating through all entities and checking each state is already a waste of performance and memory usage. Of course, it depends on "scale" of your game and systems. But overall, for bigger projects its much worse than you think. Such separation as "component" and "system" is always better in a contexual sense. You know that in a specific system you work with specific data (component). And entity you use only for defining relation between bag of data (component) and other bag of data. And also you can make sort of "entity children array" for defining entity tree relation. Inheritance will not always work for defining some sort of universal game object. It's not always a perfect fit for understanding code, especially if it's very deep like in UE :)) Overall, almost everyone has different vision on "ECS" and adds different details to this "paradigm". Your concept is fine, until you face a really big projects.
@joshuamanton
@joshuamanton Жыл бұрын
The whole point of the video is an exercise in engineering a specific solution for one's specific problem. Breaking down a paradigm into its parts, evaluating the parts we actually need, and then composing a purpose-built solution from that. There is no "components and systems are objectively bad." This is engineering; its all about making informed tradeoffs based on the actual requirements you have. You were looking for a low-brow take on ECS and that's simply not what this is.
@GetIntoGameDev
@GetIntoGameDev 4 ай бұрын
No shade, but I must respectfully disagree. In the composition example, the idea of using bitmasks is very cool, but the entities are still essentially being checked for all possible behaviours, this is not good for cache locality as each successive entity can send the execution down different paths. The idea that an entity is a primary key in a database is incredibly powerful for cache friendly composition because it ensures no branching is done. Everything is batched up and ready to go. This can even be taken further, if an enemy is performing too much logic in its update then branch divergence becomes a problem, so "request objects" can be created, then processed by another system all in one go, and their results can then be processed by a sort of "post update" system. Anyway, massive tangent, sorry about that. Regarding parallelism, there's currently a lack of practical knowledge on implementing it in games, and saying "writing multithreaded code is hard" every time the topic comes out doesn't help that. Thanks for the video! I appreciate the perspective that we can't just follow trends because they philosophically "feel optimal". Keep up the good work!
@principleshipcoleoid8095
@principleshipcoleoid8095 Жыл бұрын
Honestly I use it just because that is how Bevy works and I wanted to try making a game in Rust.
@jerth
@jerth 11 ай бұрын
Honestly, I think it's worth warning anyone watching this video to take it with a grain of salt. The author makes a few good points, but misses others, and exudes a lack of experience. I think the biggest thing missed here, and the real reason people should use some sort of ECS or derivative (if their project meets some scale/effort criteria), is the organizational benefit. Having systems with strictly defined inputs, and the ability to perform fast and robust *queries* on the game state, is worth its weight in gold when a code base starts to grow. Performance should be a second or third class benefit one should expect. Remember that a properly implemented ECS is, essentially, a very fast and very specialized in memory column oriented database for your game data.
@Kenbomp
@Kenbomp 3 ай бұрын
Nice but linked list are usually slow but usually fast enough for enterprise systems As
@E2EE2ECC
@E2EE2ECC 15 күн бұрын
This entire video could be far more concise; your audience is not compromised of neophytes. We do not need exhaustive explanations or justifications on the paradigms you use. Brevity is beauty.
@bryanedds8922
@bryanedds8922 9 ай бұрын
Any particular reason you need to play your voice in fast forward? This makes this hard to understand and painful to listen to.
@christian-loock
@christian-loock 6 ай бұрын
Maybe you should remove the word Engine from your title. Your approach might work, because all you care about are the specific entities of your game. But as soon as you want to come up with a more generalized approach that actually works for a variety of game types and is reusable, you will need some form of composition, since a general use "Game Engine" doesn't know about the entities you need. Also you are not force to implement your own ECS you know. There are actually quite a few out there that are very good.
@joshuamanton
@joshuamanton 6 ай бұрын
>since a general use "Game Engine" doesn't know about the entities you need My engine doesn't "know" about my entity types so I'm not sure what the problem is there. It uses metaprogramming to find them all and generates the code required at build time to do what it needs to do. I don't need to modify engine code to add new entities to my game. >Also you are not force to implement your own ECS you know. There are actually quite a few out there that are very good. Why would I use a library for something that is the backbone of my game? That's just foolish.
@christian-loock
@christian-loock 6 ай бұрын
@@joshuamanton Why would you assume that you are more capable of solving problems that have been solve endless times before. That is just arrogant.
@joshuamanton
@joshuamanton 6 ай бұрын
​@@christian-loock Because I know the actual problems I need to solve and some several-10's-of-thousands-of-lines-of-code library solves basically none of them. The whole point of making an engine is reducing your dependence on other people in order to ship games. The more libraries you have, the less you know what your codebase is doing, the less you can debug, the less control you have. If you want to minimize the ratio of problems solved per line of code and maximize the ratio of problems invented per line of code, then use libraries because they help tremendously on both fronts.
@scottcastle9119
@scottcastle9119 Жыл бұрын
I have ECS in mine with built in scripts so I don’t have to code.
@Bloodlinedev
@Bloodlinedev 3 ай бұрын
Arguing about saving time by not making a full features ECS framework while using your own engine. I swear by god... you probably already use some third party libs, do yourself the favor and use an ECS library. The architecture is lightyears better than OO in my experience and having all the features from the get go gives you all the benefits of this - from clean code to designer friendly architecture by default to performance for free - the drawback people usually bring up is that it takes longer to write, which from my experience gets better over time + the time you save debugging etc. balances it out
@27klickslegend
@27klickslegend 6 ай бұрын
I disagree with your reasons for why ECS is good, its just good because its simple.
@p2k7777
@p2k7777 9 ай бұрын
It's a little quiet
@BonktYT
@BonktYT 9 ай бұрын
Your implementation is simply a simple (bad performing) unpure ECS implementation, regardless of what you want to call it. What part of a pure ECS is it that you don't agree with? that you find opinionated? Memory locality? Branchless iteration? Fast querying? You must be referring to... implementation details? I don't see how complex implementation details can be "opinionated" if it brings objectively positive, (or at least non-negative) features, such as performance, higher level composability (entity relationships), debuggability (a good ECS library will provide introspection API to get an overview of the world) etc. Your point about simplicity and API surface also makes no sense, Pure ECS never prescribed a complex API, an ECS being pure is about the implementation details, which has nothing to do with the surface complexity of an API. The library flecs has a very simple base API, you can choose to use "addons" if you like, but that is not an argument against pure ECS. Being too lazy to implement a good ECS or too stubborn to use a well-tested and high performance ECS library does not make it a worse solution to your problems. What is crazy is that you don't even argue against the composability and systems part of ECS, otherwise you would be proposing Inheritance based game objects. So really your only problem with ECS seems to be... Implementation details? Casey and Jonathan are great programmers, for sure, but their narrowminded dogmatism against perceived implementation complexities and using other people's code is not doing you or their other fans any Favours. @joshuamanton
@gsestream
@gsestream 7 ай бұрын
forced implementations shuggg. forced motivation is not there.
@arcaneminded
@arcaneminded 11 ай бұрын
I hate your idea. This whole child-parent tree thing is just a convoluted OOP solution. The benefit to having components is they can be used across various entities and systems are entity-agnostic, it's not about "compression". By having a bunch of Hero_entity etc. you've just invented objects.
@nekoill
@nekoill Жыл бұрын
Geezus, people stsly be doing programming under a genuine assumption that ECS is responsible for the composition? I thought at this point even the most diehard OOP coders learned that a) composition is another godly gift from FP deities to save humanity with grace and b) composition is superior to inheritance if there is any kind of support for the former functionality
@WeslomPo
@WeslomPo Жыл бұрын
You are completly wrong. You don't understand it at all. ECS not about optimization of code or performance of logical unit. ECS is design paradigm. It not neccesary a faster than default OOP. What "Ecs is fast" - are marketing bulshit with grain of salt. You really gain a performance when using ECS but point of making ECS architecture is not performance at all. ECS are just different paradigm of code architecture. It allows you to architect your game easily. Its goal to write and make game that you can support on long term with ease. If your ECS framework cannot do that - and only focused on speed - shame on it, change to another framework. We used not super fast framework, but with for component codegeneration - I think this is a best solution. ECS about data. Think about it as table in spreadsheets. Entity - row id, component are column. Systems are code that change or draw that data. Adding component to entity is like adding column in table in spreadsheets. Creating a entity - is like adding another row with data. Changing components is like changing data in cell of spreadsheets. Only systems can change that data according rules your writes in it. Also there are a systems that can react on changes in data, or unique rows that you can found by unique components and so on. I think you need to make two steps back, use other ECS framework, or even another language with another framework to understand ECS paradigm. It is not easy - to my experience it blow my mind before I understand how it works.
@joshuamanton
@joshuamanton Жыл бұрын
I covered everything you said. Most of the video was about architecture and _how_ ECS gives you the benefits you outlined, while showing that you can get those benefits without a big, complex, opinionated ECS in your way. Watch the video again.
@WeslomPo
@WeslomPo Жыл бұрын
​@@joshuamanton you gain loses when doing what are you suggested. You gain bloated code base that will be harder to maintain after some time. ECS is a thing that made for solve what you suggested. Ofcource you can make game without ECS, and it will work, and it will even can be maintainable and playable. To my opinion it is a hard to achieve. You hear me, I hear you, maybe Im wrong. I will be watching you xD
@BonktYT
@BonktYT 9 ай бұрын
What part of a pure ECS is opinionated? Memory locality? Branchless iteration? Fast Querying? You must be referring to... the implementation details?? I don't see how complex implementation details can be "opinionated" if it brings objectively positive, (or at least non-negative) features, such as performance, higher level composability (entity relationships), debuggability (a good ECS library will provide introspection API to get an overview of the world) etc. Being too lazy to implement a good ECS or too stubborn to use a well-tested and high performant ECS library does not make it a worse solution to your problems. What is crazy is that you don't even argue against the composability and systems part of ECS, otherwise you would be proposing Inheritance based game objects. So really your only problem with ECS seems to be... Implementation details?? Casey and Jonathan are great programmers, for sure, but their narrowminded dogmatism towards perceived implementation complexities and using other people's code is not doing you or their other fans any Favours. @@joshuamanton
@noxabellus
@noxabellus Жыл бұрын
"just a compression technique" no, dude, it's called an abstraction. it has many benefits besides compression, such as the easy graphing you outlined yourself. you luddites are ridiculous with this stuff i swear
@joshuamanton
@joshuamanton Жыл бұрын
"it has benefits, like those other benefits you mentioned" Good one, guy. Really got me there.
@joshuamanton
@joshuamanton Жыл бұрын
Also if you think abstraction is distinct from compression, you have not thought hard enough. The act of abstracting is the act of compressing out details that aren't important.
@noxabellus
@noxabellus Жыл бұрын
@@joshuamanton 🤦
@landru27
@landru27 Жыл бұрын
@@joshuamanton I'd like to begin by stressing that I agree with what I see as the main points of your video, that no specific programming technique has a monopoly on any of the benefits which acolytes to that technique claim, and programmers can fall into the trap of what's trendy or faddish, and that the fundamental solution to both of these is to think carefully about what one is actually building, applying good engineering principles. So I'm not here to fight. At the same time, I'd like to observe that there are certainly forms of abstraction that don't amount to compression. For example : a database access layer which lets a service layer make database reads and writes generically, and encapsulates the particulars of how certain things are done against different RDBMSes. That database access layer is an abstraction, but could not be said to be a compression. Introducing such an abstraction likely adds code, but even the things it does reduce (perhaps the database access API footprint used by the service layer) does not get rid of "details that aren't important". Indeed, it keeps those details, because they most certainly are important. Sure, it moves them, but compression isn't about moving things around, of course. As another example, refactoring a large method by extracting parts of it into separate, independent functions is certainly a form of abstraction, but is not compression. Again, the method in question ends up smaller, but only because stuff has been moved, not eliminated. The details are important, so they are retained, but they are reorganized; to the extent that the large method has been reduced, other functions have been created / increased. I'm certain we'd both agree that getting rid of details that aren't actually important "compresses" the code a bit, but (a) I'd call that "reduction" not "compression" (in the same way that deleting unwanted stuff from my hard drive isn't called "file compression"), (b) that's garden variety cleanup, and (c) that can certainly be done without abstracting anything. Abstraction, in fact, not uncommonly *adds* code. Somewhat paradoxically, it simultaneously reduced complexity, when done robustly. But I think it's fair to say that in software engineering generally, "abstraction" and "compression" are in fact distinct concepts, and distinct activities.
@joshuamanton
@joshuamanton Жыл бұрын
@@landru27 caseymuratori.com/blog_0015
@GreedoShot
@GreedoShot 4 күн бұрын
Skill issue
@ScaredHelmet
@ScaredHelmet 5 ай бұрын
Why are you so salty about this lmao
@alirezaahani-f4u
@alirezaahani-f4u 2 ай бұрын
bro why are you talking so fast are you in hurry to end the video asap
Switching Game Engines... Twice? - Devlog #7
10:55
TIMBER
Рет қаралды 86 М.
Bob Nystrom - Is There More to Game Architecture than ECS?
23:06
Roguelike Celebration
Рет қаралды 207 М.
БУ, ИСПУГАЛСЯ?? #shorts
00:22
Паша Осадчий
Рет қаралды 3 МЛН
FLECS - The Fast Lightweight Entity Component System (C/C++)
10:26
Gamefromscratch
Рет қаралды 22 М.
Entity Component System | Game Engine series
43:05
The Cherno
Рет қаралды 129 М.
I Tried The "Game Engine Of The Future"
26:13
Fredyy
Рет қаралды 21 М.
Entity Component System (ECS) - Definition and Simple Implementation
28:02
No One Hires Jr Devs So I Made A Game
39:31
ThePrimeTime
Рет қаралды 335 М.
When Optimisations Work, But for the Wrong Reasons
22:19
SimonDev
Рет қаралды 1,1 МЛН
Adding levels to my custom game engine (C#/MonoGame)
17:00
Rant: Entity systems and the Rust borrow checker ... or something.
1:01:51
When Your Game Is Bad But Your Optimisation Is Genius
8:52
Vercidium
Рет қаралды 1,5 МЛН
Dear Game Developers, Stop Messing This Up!
22:19
Jonas Tyroller
Рет қаралды 730 М.
БУ, ИСПУГАЛСЯ?? #shorts
00:22
Паша Осадчий
Рет қаралды 3 МЛН