Table of Contents

Struct EntityId

Namespace
Typhon.Engine
Assembly
Typhon.Engine.dll

64-bit entity identifier: 48-bit monotonic EntityKey (upper) + 16-bit per-DB archetype routing id (lower). Routes to the correct per-archetype LinearHash and uniquely identifies an entity within the engine.

public readonly struct EntityId : IEquatable<EntityId>
Implements
Inherited Members

Remarks

EntityKey is monotonic per-archetype, never recycled — no ABA problem, no version field needed. 2^48 ≈ 281 T allocations per archetype.

ArchetypeId is the low 16 bits: the per-DB, engine-assigned archetype routing id (persisted in ArchetypeR1.RoutingId, re-matched by name on reopen). Up to 65,536 archetypes composable into one database. The word-aligned 48/16 split needs no mask constant — the routing id is (ushort)value and the key is value >> 16.

Fields

Null

The null entity sentinel.

public static readonly EntityId Null

Field Value

EntityId

Properties

ArchetypeId

16-bit per-DB archetype routing id (low bits). Routes to the correct per-archetype storage instance for the owning engine.

public ushort ArchetypeId { get; }

Property Value

ushort

EntityKey

48-bit monotonic key, unique within the archetype's LinearHash.

public long EntityKey { get; }

Property Value

long

IsNull

True if this is the null/default entity (no entity).

public bool IsNull { get; }

Property Value

bool

RawValue

Raw packed value: the 48-bit EntityKey in the upper bits and the 16-bit ArchetypeId in the lower bits.

public ulong RawValue { get; }

Property Value

ulong

Remarks

For carrying an identity somewhere the engine does not own — an application's own wire messages, its account or character rows in another store, its logs, its admin tooling, or a client's "target" field coming back in. Round-trips through FromRawValue(ulong).

Stable within one database, NOT across databases. ArchetypeId is the per-DB routing id persisted in ArchetypeR1.RoutingId and re-matched by archetype NAME on reopen, so a raw value stays valid across restarts of the same database — and means something different, or nothing, in another one. Renaming an archetype without setting ArchetypeAttribute.PreviousName breaks the match and invalidates every raw value already persisted outside the engine: the name is the durable identity, not the number.

Methods

Equals(object)

Returns true when obj is an EntityId equal to this one.

public override bool Equals(object obj)

Parameters

obj object

Returns

bool

Equals(EntityId)

Returns true when other has the same packed identifier value.

public bool Equals(EntityId other)

Parameters

other EntityId

Returns

bool

FromParts(long, ushort)

Rebuilds an EntityId from the two parts EntityKey and ArchetypeId expose.

public static EntityId FromParts(long entityKey, ushort archetypeId)

Parameters

entityKey long

The 48-bit monotonic key (see EntityKey). Must be non-negative and fit in 48 bits.

archetypeId ushort

The per-DB archetype routing id (see ArchetypeId).

Returns

EntityId

The identifier.

Remarks

The range check is unconditional, unlike the internal constructor's. That one guards behind Enabled, which is off by default so the JIT folds it away — correct for a path the engine itself feeds with values it just produced. This one takes numbers from outside the engine, where the whole point is to reject a bad one, and a check that disappears in Release would hand back a silently corrupt identity.

Exceptions

ArgumentOutOfRangeException

entityKey is negative or does not fit in 48 bits.

FromRawValue(ulong)

Rebuilds an EntityId from a RawValue.

public static EntityId FromRawValue(ulong rawValue)

Parameters

rawValue ulong

A value previously read from RawValue.

Returns

EntityId

The identifier.

Remarks

Every bit pattern is a representable identifier, so this cannot fail and does not validate: a value that was not produced by RawValue yields an id that resolves to no entity rather than an exception. Read RawValue's remarks for what "the same database" means before persisting one.

GetHashCode()

Hash of the packed 64-bit identifier value.

public override int GetHashCode()

Returns

int

ToString()

Human-readable form, e.g. Entity(Key=42, Arch=3), or Entity(Null) for the null entity.

public override string ToString()

Returns

string

TryParse(ReadOnlySpan<char>, out EntityId)

Parses the form ToString() produces.

public static bool TryParse(ReadOnlySpan<char> text, out EntityId id)

Parameters

text ReadOnlySpan<char>

Either Entity(Key=<key>, Arch=<routingId>) or Entity(Null).

id EntityId

The parsed identifier, or Null when this returns false.

Returns

bool

true when text was one of those two forms and both numbers were in range.

Remarks

Exists so a log line or a diagnostic dump is reversible: the id that appears in a trace can be fed back to a tool without the reader hand-extracting two integers. Culture-invariant, because ToString() is. Surrounding whitespace is tolerated; anything else in the string is not, so a half-matching line fails rather than silently parsing its prefix.

TryParse(string, out EntityId)

Parses the form ToString() produces.

public static bool TryParse(string text, out EntityId id)

Parameters

text string

The text, or null.

id EntityId

The parsed identifier, or Null when this returns false.

Returns

bool

true on success; false for null or an unrecognised form.

Operators

operator ==(EntityId, EntityId)

Value equality of two EntityId values.

public static bool operator ==(EntityId left, EntityId right)

Parameters

left EntityId
right EntityId

Returns

bool

operator !=(EntityId, EntityId)

Value inequality of two EntityId values.

public static bool operator !=(EntityId left, EntityId right)

Parameters

left EntityId
right EntityId

Returns

bool