@Joachim_Ante_1 ,here is the scenario in which I need the IComponentData Class. Basically it boils down to a compatibility issue with subscene and the use of hash code (that could be worked around).
This is explained to the best of my languages ability and hope it makes sense (it’s almost a draft documentation of the thing…)
I’m not yet ready to call that a release so for know let’s consider it as an alpha preview .
What is the goal ?
Make a designer friendly skill system
What is a skill ?
The skill is an ability that produce effects on one or several entities. The effect can for example be from reducing a pool (HP/Mana/Bullet magazine), moving an entity (apply a push back, teleport,…), triggering a message.
Skill have some properties in common (ex : a range, a cost, …) but each have a unique set of effects.
Some skills can however share the same effects.
The effect can be applied either to the target or « caster » of the skill.
As I said an effect can be a wide range of actions. An the action it has on entities can depend on other factor to the entities itself (damage can be reduced by armor based on the damage type,…)
How to convey such effect in DOTS?
To covey the effect on the different entities we can use a flavor of an event system.
We could for instance add a IComponentData to the affected entities where the IComponentData have a the necessary data to apply the effect in a system that iterate aver all entities with that component (and the ones needed for the effect to apply like armor).
The drawback is that this implementation trigger a change in the archetype every time we want to apply an effect.
To work around that we can implement a custom event system with native containers (native stream) and have a system that consume the stream to apply the effect to the necessary entities.
This work great when we know the effect we want to apply when codding the actual game logic, but that’s not designer friendly.
When thinking about it a skill effect should not change at runtime it’s defined by the disigner when building the game and don’t change once the game run (it’s just applied).
So my idea is to make a registry based event system.
What is a registry based event system ?
Like the name should imply it’s an event system that uses a registry of possible events.
The idea is to let the designer define the set of effect a skill should have through the editor with some custom editors. That way we can author the behavior with the handy abstractions of OOP while having a (hopefully) performant runtime.
How does it work ?
This process work in several phases :
The authoring phase
The authoring phase consist in defining the list of effects that a skill should have through the unity editor.
The conversion phase
The conversion phase add this list of effect in an IComponentData class to be consumed by the next phase.
The initialization phase
The initialization phase iterate over all the entities with the IComponentData class added at the conversion phase. This IComponentData class contains the list of effect (IEffect) to be added to the skill, it adds it to a registry (a singleton class containing a dictionary of dictionary). The registry returns a reference to the effect (the reference is composed of a hash of the effect type and a hash of the effect itself). The registration is unique so if I try to register 2 identical effect, there is only one instance in the registry and when trying to add the second one the registry returns the same reference.
The effect reference is then added to a dynamic buffer of effect reference.
Doing that allow the next phase to trigger effect without knowing what it actually is.
The work done by the initialization phase cannot be done at convert time because it would not work for entities having skill in subscene (the registry is a simple singleton so it’s not persisted in the serialized subscene and the effect reference relies on the hash which would be different at runtime because not computed by the same process) That’s why I need the IComponentData Class.
The production phase
During this phase, any system that need to trigger effect grab a native queue from the dispatcher system and enqueue an effect command containing the emitter entity, the target entity and the reference of the effect.
The dispatcher phase
The dispatcher loop through the list of native queue requested by the producer systems and dispatch the effect in a native multi hashmap (command map) based on the effect type id (contained in the effect reference)
The consumer Phase
In the consumer phase a IJob per effect type gets the list of effect to apply from the dispatcher (command map). It take all the necessary component data for the application of the effect and apply it.
That way, the effect can be handle in parallel (careful about the order so that 2 consumer don’t alter the same component).
End notes
For now I don’t have the skill system per say, it’s just the effect that I apply based on the collisions between entities. (each skill will probably be an entity that has a buffer of effect and that is triggered by some system) (skill themselves will likely be attached to a « skill bar » buffer of the player entity)
The effect system POC work in my playground tank game. (implementation in this sample is « full » of bad code)
Now I’m trying to extract the registry based event to a package with proper unit and performance tests, to improve both the « cleanness » of the code an performance.
Tank demo playground :