On Sun, Jan 11, 2015 at 4:02 PM, Klaim - Joël Lamotte
On Sun, Jan 11, 2015 at 8:41 AM, Matus Chochlik
wrote:
[8<]
I've been playing with some ECS designs lately and tried to implement two of my own [1],[2] (maybe those are among those you've already seen) (and sorry for the shameless plug). Based on what I've seen, if the ECS is to
be
used according to the usage patterns you usually see in a game (or rendering) engine, I believe it is better for the component instances to be stored together, outside of the entities (for locality of reference, efficient (re-)allocation, etc.).
I violently agree.
The entity should IMO be just an unique identifier
My experiments so far reach to the same conclusion: it's the most flexible and potentially efficient approach.
and in both of my implementations there is a `manager` class that can be used to store/modify/query/remove/etc. the components of an entity. This way operations that are common, like execute this function (every iteration of the update loop) on all entities with this set of components can be implemented more efficiently.
In my current implementation I call the object holding all components a "cluster". The Cluster hold one "pool" of component by type of components. Currently all the pools are the same type and basically are augmented flat_maps but I recently realized that a more flexible system could be implemented by letting the cluster user insert different kinds of polls depending on how he wants the component type to be memory managed ( like a vector or like an actual pool or with allocated nodes?), how "updates" are processed (in parallel, concurrent, jsut a loop?). I plan to try this design in the coming months.
Ditto, In my second implementation I've defined an interface for the component storage objects (classes managing instances of components of one type in the manager). The interface is flexible enough to allow local or remote mutable/immutable storages, or storages using an RDBS, a web service, etc., to actually store the component instances. From the users' POV all this is transparent, they manipulate the components uniformly through the manager, they just need to specify what kind of storage should be used when registering the component type in a manager.
I didn't solve the component-inter-requirements problem though, I'm not sure if I should implement this at all, and if yes should it be compile-time checked as Vincente suggests? In which case the cluster would have to know the types it can manage at compile time too, because I see no way for an entity to be able to be checked at compile time except for a construct like the suggested "subject".
I'm not sure what Vincente's use case is, but in game engines the ECS *deliberately* places very few constraints on the components and how they can be combined in an entity. The idea is that the programmer does not have enough knowledge of what the content creators or modders will want to do and statically constraining the components too much requires complete recompilation every time a change is made in the game logic accessing the ECS which is undesirable for the original content creators and usually impossible for modders. Furthermore game engines very often support modification of the ECS through scripting which again could be hindered if constraints were placed on how the components are combined. These concerns IMHO apply also on other applications, like CAD/CAM, etc. using an ECS. [8<]
But having implemented several apps using this approach I find it quite limiting in some situations that the group of components is static. Sometimes it is useful (for example for debugging) to have the ability to add/remove component *types* on-the-fly. [2] allows this but its unfinished.
I can do that in my implementation indeed, it is helpful. As said before I think it can be improved by allowing the user to provide the container of component for a type, making him chose how to manage them as long as the container match a specific set of requirement (concept?).
I use an abstract interface and so far the overhead from virtual function calls is not very dramatic.
[8<]
Le 11/01/15 20:30, Matus Chochlik a écrit :
I'm not sure what Vincente's use case is, but in game engines the ECS *deliberately* places very few constraints on the components and how they can be combined in an entity. The idea is that the programmer does not have enough knowledge of what the content creators or modders will want to do and statically constraining the components too much requires complete recompilation every time a change is made in the game logic accessing the ECS which is undesirable for the original content creators and usually impossible for modders. Furthermore game engines very often support modification of the ECS through scripting which again could be hindered if constraints were placed on how the components are combined.
These concerns IMHO apply also on other applications, like CAD/CAM, etc. using an ECS.
As I said I don't know nothing about the Games domain. It is more a principle I want to follow, prefer compile-time check, then link time and the run-time. I understand the compile time concern, but I would prefer to have to define the relations between the different type of my system, if possible, at compile time. Vicente
On Mon, Jan 12, 2015 at 1:07 AM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
As I said I don't know nothing about the Games domain. It is more a principle I want to follow, prefer compile-time check, then link time and the run-time.
It is not a game-domain-specific issue, you shouldn't focus on this. It's useful as soon as you want to modelize a context where entites do not all have the same properties (physical, behavioral, etc.). It's even useful to replace inheritance when modelizing a company employees. Compile checks just goes half against the advantages of a component system: - easy paralellize processing when possible; - faster batch processing by type or for all component instances; - easy runtime composition and extensibility; Usually trying to call a function in a component which don't exist for an entity will not do anything at all, maybe report a warning or something. You want to add a constraint. I'm not sure if it is: 1. All component types are checked at compile time see if they are compatible. 2. All component of an entity are checked at compile time see if they are allowed and compatible. I think both constraints can be added over a run-time checked component system, I just never tried to do so but that must be an interesting exercise.
participants (3)
-
Klaim - Joël Lamotte
-
Matus Chochlik
-
Vicente J. Botet Escriba