54

The two key benefits that I constantly hear lauded about entity systems are 1) the easy construction of new kinds of entities due to not having to tangle with complex inheritance hierarchies, and 2) cache efficiency. Note that (1) is a benefit of component-based design, not just ES/ECS. You can use components in many ways that do not have the "systems" part ...


34

I know you do not conceptualize this as collisions, however what you are doing is colliding a circle centered at the creature, with all food. You really do not want to check food that you know is distant, only what is nearby. That is the general advice for collision optimization. I would like to encourage to search for techniques to optimize collisions, and ...


16

You should adopt a space partitioning algorithm like BVH to reduce complexity. To be specific to your case, you need to make a tree that consists of axis-aligned bounding boxes that contain food pieces. To create a hierarchy, put food pieces close to each other in AABBs, then put those AABBs in bigger AABBs, again, by distance between them. Do this until ...


14

Mick West's article explains the process of linearising entity component data, in full. It worked for the Tony Hawk series, years ago, on much less impressive hardware than we have today, to greatly improve performance. He basically used global, pre-allocated arrays for each distinct type of entity data (position, score and whatnot) and references each array ...


14

Remember to not get carried away with entities and components. It's totally fine to not have your World as a component. If you know for sure there's only going to be one of something, it doesn't make much sense to make it a component. Components are made to be reused in numerous entities, combined with other components. This doesn't make the game less pure, ...


13

Fork-Join You don't need separate copies of components. Just use a fork-join model, which is (extremely poorly) mentioned in that article from Intel. In an ECS, you effectively have a loop something like: while in game: for each system: for each component in system: update component Change this to something like: while in game: for each ...


13

Short version: no, your job as an engineer is to evaluate all applicable solutions to problems before choosing a solution Long Version: "ECS" is an overloaded term. It had a somewhat clear definition at first but it's been overly muddled since. It doesn't matter much, though, since the answer is the same either way: every architecture has pros and cons. If ...


12

This seems great, considering fast access for a component using entity id and more importantly, fast iteration over elements of array (because systems do this all the time) and fewer cache misses than if I store components in Entity or use: Have you actually measured cache misses? Are they in any way being a problem for you? Would eliminating them for your ...


11

The simple version: don't. One could argue that you have perhaps a slight misunderstandings about how to build an ECS (why would you sent a list of Entity* to a system to update? the System is supposed to have its own self-contained collection of the components it cares about, and the global entity list should barely ever even be used... a "true" ECS doesn'...


10

Can Component hold the logic? or it should not and stay as a bag of data? That's how you like. I suggest to stick with the first implementation and finish your project, then see if it worked out for you or not. If you do that, however, I suggest you drop the concept of System as you described it, as you'll have two lanes of doing things, which will, in ...


9

In ECS everything is broken down to components that describe functions. A weapon is a physical item so one component will be a physical position. If it is on the ground or thrown at an enemy (sword / throwing knife) then you need the physical position component to decide if it was picked up or hit something (e.g. wall or monster). When a weapon is held you ...


9

In a "pure" ECS, your entities consist of just a unique ID, which shared among its components. For example you may have these entities: Entity ID 123, it is drawn and moved Entity ID 234, which is only drawn Thus you'll have the following component collections: Drawn components: <123, 234> Moved components: <123> There is no need to filter in this ...


9

First, you should not have a strict 1-1 mapping of Components to Systems. It's unclear to me from your question if that's the case already. You may very well have singular systems that use or interact with numerous components. Rendering, physics, AI, etc. are all Systems (they perform a cohesive set of updates and logic) but interact with many Components. A ...


9

Is there some advantage to having each attribute laid out contiguously in memory? It's better for cache locality of data access. Memory access is slowest part of all modern computing systems. As memory buses pull in multiple bytes in "cachelines" and most modern CPUs will prefetch memory that it detects are being accessed contiguously, keeping data that is ...


8

Your approach is fine, and was used widely by game developers of the past. You see with inheritance hierarchy you often find yourself in a situation there you want inherit from a multiple classes, but they don't usually mix well (including The diamond problem). Because of that, a component based architecture is being widely adopted. One variation of this ...


8

To add to the other answers here, you can use something like in the following code to have a bit set of arbitrary length that grows on demand. This method even lets you do a simple form of compression; if your most common components have the lowest ID values, the majority of your entities will use a small amount of bitset memory to track their components, ...


8

One of the big reasons some ECS proponents favour a strict separation of components and systems is that it helps architect game functionality in a data-oriented style. In the ideal data-oriented flow, all your major systems work like particle systems: churning through big batches of data at a time that all need the same kind of operation performed on them. ...


8

It is perfectly possible to mix both styles. The same GameObject can have some of its functionality implemented with the new ECS system and other functionality in classic MonoBehaviour events. What Unity recommends in their ECS tutorial is in fact to start with a project which uses the old style and then look for features which you think would benefit from ...


7

I'm afraid you've got this a bit wrong. The entire reason for component-based entity systems is that you should be favouring composition over inheritance. You should not be using inheritance over Entity. Entity exists as a composed piece of data / functionality, consisting of Components only. It is, so to speak, intended to be a final class, i.e. no ...


7

At the moment I'm using std::shared_ptr to support multiple ownership of GameObjects so that they are held by both the scene and any other GameObjects within the game Don't do that. shared_ptr is often the wrong tool for the job, and that certainly applies here. Remember that smart pointers are for managing ownership; shared_ptr is about sharing ownership. ...


7

Merging systems, such as collision and collision response, is a bad idea. The reason being that there can be many different responses to collisions: Physics based, and game-logic based. In most game engines I have seen (ECS and non-ECS and all the greys in-between), there is some kind of inter-system communication system, because this is what makes the ...


6

Partly to allow data-driven operations, and partly because an ECS is a specific subset of all possible component-based designs. A main point of component-based approach to aggregation (be it ECS or another use of components) is to allow you to reconfigure game objects without needing a recompile. You have an editor that your designers and game scripters ...


6

Database reads are usually via network and from hard-drive. That means database queries will always take a few ms, no matter how simple they are. Databases can get faster with in-memory techniques and smart database designs with good indexing concepts, but their speed is often still insufficient for real-time processing. Blocking your process while a ...


Only top voted, non community-wiki answers of a minimum length are eligible