Entity currently is a struct that marries a reference to its world with its Identity, to allow convenient interaction.
Disadvantages
64 bits of redundant data copied for each Entity passed into EntityActions
includes Marshal interference
Identities across multiple Worlds overlap (first Entity in each world looks the same)
no support for EntityActions in Jobs (without lots of extra code)
Change
We'd like to keep this convenience, while encoding the world directly in the Entity's stored bits. This allows faster copying of Entities (only 64 bits instead of 128), and allows making entities available in more place, and to reference entities across worlds without conflicts.
Limited number of Worlds
Worlds limited to 255 Worlds total (users seldom need more than one or two)
Generations
Generation moves to the front of the entity (into its newly created Header)
GenerationMask = HeaderMask = 0xFFFF_0000_0000_0000ul. This Header is also the TypeExpression Header (see new TypeExpression layout).
Generation is no longer stored for Relations - they may only target a living entity, and the ECS removes all relations when the Entity is Despawned.
Generation is planned to be treated as a ushort, for 64k possible generations.
Identity changes
World's IdentityPool annotates the entity with the world index in its 64 bit pattern.
WorldMask = 0x0000_00FF_0000_0000ul
Binary Layout
Entities have a Key and Flag field (other kinds of constructs may also use flags):
EntityFlagMask = 0x0000_FF00_0000_0000ul, the top nibble of which is always 0xE.
Entities (Identities) always have the same 4 bit "key type", set to 0xE:
EntityKey = 0x0000_E000_0000_0000ul
This will be used for advanced matching and storage logic. Where the entity is used as a Key (i.e. a relation), this makes these keys very easy to identify visually and test for.
Disabled Entities (when that feature comes) will likely use
DisabledEntityKey = 0x0000_D000_0000_0000ul but could also be using one of 4 bits in its flag field's lower nibble for this.
Links will use LinkKey = 0x0000_8000_0000_0000ul, and TypeMask = 0x0000_0FFF_0000_0000ul that contains a type. This means there can only be 4096 object link types.
Wildcard keys are TBD, possibly 0x1-0x7 and 0xF.
Entity Properties
public property World that looks up its world.
public property Meta that returns the Meta value at its index. (even if entity is dead - the Meta struct will have the same entity with a different generation, or default)
Future / Optional
Having to resolve the world for each operation can be slow, an EntityModifier struct can be returned by the first Structural change on an entity to make subsequent ones faster. This works like the current 0.5.x Entity struct.
Impact
The added features should cause NO breaking changes on their own. Code using 0.5.x Entity will work the same for 0.6.0.
Technically breaking: The number of supported Types for Object Links is reduced to 4096. Component types still stay at 16k (may be expanded). This frees 12k logical space for additional types of backing storage.
Technicaly breaking: Users with more than 255 worlds are out of luck. (easy to mitigate with a single Relation Tag, and a sufficient number of "world anchor" entities)
Entity currently is a struct that marries a reference to its world with its Identity, to allow convenient interaction.
Disadvantages
Change
Limited number of Worlds
Worlds limited to 255 Worlds total (users seldom need more than one or two)
Generations
Generation moves to the front of the entity (into its newly created Header)
GenerationMask = HeaderMask = 0xFFFF_0000_0000_0000ul
. This Header is also the TypeExpression Header (see new TypeExpression layout).Generation is no longer stored for Relations - they may only target a living entity, and the ECS removes all relations when the Entity is Despawned.
Generation is planned to be treated as a
ushort
, for 64k possible generations.Identity changes
World's IdentityPool annotates the entity with the world index in its 64 bit pattern.
WorldMask = 0x0000_00FF_0000_0000ul
Binary Layout
Entities have a Key and Flag field (other kinds of constructs may also use flags):
EntityFlagMask = 0x0000_FF00_0000_0000ul
, the top nibble of which is always 0xE.Entities (Identities) always have the same 4 bit "key type", set to
0xE
:EntityKey = 0x0000_E000_0000_0000ul
This will be used for advanced matching and storage logic. Where the entity is used as a Key (i.e. a relation), this makes these keys very easy to identify visually and test for.
Disabled Entities (when that feature comes) will likely use
DisabledEntityKey = 0x0000_D000_0000_0000ul
but could also be using one of 4 bits in its flag field's lower nibble for this.Links will use
LinkKey = 0x0000_8000_0000_0000ul
, andTypeMask = 0x0000_0FFF_0000_0000ul
that contains a type. This means there can only be 4096 object link types.Wildcard keys are TBD, possibly
0x1
-0x7
and0xF
.Entity Properties
World
that looks up its world.Meta
that returns the Meta value at its index. (even if entity is dead - theMeta
struct will have the same entity with a different generation, ordefault
)Future / Optional
Having to resolve the world for each operation can be slow, an
EntityModifier
struct can be returned by the first Structural change on an entity to make subsequent ones faster. This works like the current 0.5.xEntity
struct.Impact
The added features should cause NO breaking changes on their own. Code using 0.5.x
Entity
will work the same for 0.6.0.Technically breaking: The number of supported Types for Object Links is reduced to 4096. Component types still stay at 16k (may be expanded). This frees 12k logical space for additional types of backing storage.
Technicaly breaking: Users with more than 255 worlds are out of luck. (easy to mitigate with a single Relation Tag, and a sufficient number of "world anchor" entities)