outfox / fennecs

... the tiny C# ECS that loves you back!
https://fennecs.tech
MIT License
223 stars 10 forks source link

Unify Entity and Identity #31

Open thygrrr opened 1 week ago

thygrrr commented 1 week ago

Entity currently is a struct that marries a reference to its world with its Identity, to allow convenient interaction.

Disadvantages

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

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)