Entitas
Entitas copied to clipboard
Components with default and mandatory values
While working with Entitas I ran into several issues having to do with the lack of expressiveness regarding the relations between components and entities and component lifecycle:
- Some components need to always exist, and once they are created they should never change, IDs are one example, an entity should always have one and only one ID and it should never change. It would be great to have the entity constructor take the components that are mandatory or somehow accept a factory and remove all methods that deal with mutation of said component, and somehow reflect the safety of reading the component value in getter method names.
- Some components can change, but they are mandatory, when they are removed they will assume a default value. An example use case could be a configuration value or some injected service. This would work similarly to an immutable component but would add mutating methods such as
RemoveComponent
andReplaceComponent
.
WDYT? This has several implications, for example not being able to use sharedInstance
for example but I think that ultimately it can save a lot of redundant validation, human error and time.
I've had a little bit of time to begin an implementation, the API right now looks like this.
For a Game context with one immutable component:
[Game, Access(Immutable)]
public class NameComponent() : IComponent {
public string Value;
}
This generates the following methods for the entity and context:
public partial class GameEntity {
public NameComponent nameSafe { get { return (NameComponent)GetComponent(GameComponentsLookup.Name); } }
}
public sealed partial class GameContext : Entitas.Context<GameEntity> {
public GameEntity CreateEntity(NameComponent name);
}
As can be seen, all removal and replacements are not generated and the non-generated context methods enforce the immutability and safety of the field which means the component will always exist and no tests for existence need to be made. CreateEntity
is now generated and Immutable
and mandatory
components must be provided. There are some issues that still need to be addressed, for example the Unity visual debug plugin will still attempt to add and remove these components etc, still need to work on those things.
For a Meta context with one mandatory component:
[Meta, Access(Mandatory)]
public class AgeComponent() : IComponent {
public int Value;
}
This generates the following methods for the entity and context:
public partial class MetaEntity {
public AgeComponent ageSafe { get { return (AgeComponent)GetComponent(MetaComponentsLookup.Age); } }
public void ReplaceAge(int newValue);
}
public sealed partial class MetaContext : Entitas.Context<MetaEntity> {
public MetaEntity CreateEntity(AgeComponent age);
}
In this case the component can be replaced, but not removed, only replacement is generated.
Hi. Did you ever sort out default values? I'm in that situation now where I have to provide default values that are setup later in systems and it's yuk.