EntityLocation
Where an entity durably is, independent of which worker holds it: an opaque scope key, a container id and a pose in that container's local space.
Nebula · Packages/com.1by3.nebula/Runtime/Containers/EntityLocation.cspublic readonly struct EntityLocation : IEquatable<EntityLocation>Where an entity durably is, independent of which worker holds it: an opaque scope key, a container id and a pose in that container's local space. A NetworkIdentity reports its current location as NetworkIdentity.Location and a PersistedEntityRecord its saved one as PersistedEntityRecord.Location; both are this type, and two processes given the same value resolve the same container (Resolve).
The scope key is the string the game chose for the entity's simulation scope: PublicScope (empty) for the public world, or the instance key (TemplateId/key, as passed to NebulaWorker.PrepareInstance) for a private instance. Nebula never parses or interprets it; it only compares it with ordinal string equality. The container id is the container's string id (Container.ContainerId), whose form tells the kind (ContainerKind). Equality is exact: ordinal on the strings and per component on the pose, never approximate.
The value does not carry the authority epoch, the owning worker or the wire index of the container, which are the parts of an entity's placement that change on a handover, a lease change or a rebuild. The design of record is docs/location-contract.md.
Constructors
EntityLocation
public EntityLocation(string scopeKey, string containerId, Vector3 localPosition, Quaternion localRotation);Build a location from its three parts. Null strings read as empty.
Fields
PublicScope
public const string PublicScope = "";The scope key of the public world: the empty string.
LocalPosition
public readonly Vector3 LocalPosition;Position in the container's local space (world space when ContainerId is empty).
LocalRotation
public readonly Quaternion LocalRotation;Rotation in the container's local space (world space when ContainerId is empty).
None
public static readonly EntityLocation None = new EntityLocation(PublicScope, "", default, Quaternion.identity);A location in no container, at the world origin, in the public world.
Properties
ScopeKey
public string ScopeKey { get; }Opaque key of the entity's simulation scope. PublicScope for the public world. Never null.
ContainerId
public string ContainerId { get; }String id of the container the pose is expressed in (Container.ContainerId), or "" when there is none. Never null.
IsPublic
public bool IsPublic { get; }The location is in the public world (its scope key is empty).
HasContainer
public bool HasContainer { get; }The location names a container (its container id is not empty).
ContainerKind
public LocationContainerKind ContainerKind { get; }The kind of container ContainerId names, from the id's form: empty is LocationContainerKind.None, rt_ followed by a decimal 64-bit number is LocationContainerKind.Runtime, an id containing # is LocationContainerKind.Dynamic, anything else is LocationContainerKind.Static.
Methods
Of
public static EntityLocation Of(Container container, Vector3 localPosition, Quaternion localRotation);The location of a pose inside container: the container's scope key (Container.ScopeKey) and id, and the pose as given. A null container is "no container".
Resolve
public Container Resolve();The container this location names in this process, or null when there is none here. The lookup is by ContainerId in ContainerRegistry, which every role (worker, client, gateway, orchestrator) fills from the same scene, manifest and lease rows; a container found under the id but belonging to another scope (Container.ScopeKey differs from ScopeKey) is not returned. Null also when the container has not arrived yet: a dynamic container arrives with its carrier, a runtime container with its lease.
Write
public void Write(NetworkWriter writer);Serialize as string scope_key, string container_id, vector3 local_position, quaternion local_rotation (the primitive encodings of the wire protocol). The bytes are the same on every process and every release within a protocol major.
Read
public static EntityLocation Read(NetworkReader reader);Read a location written by Write.
Equals
public bool Equals(EntityLocation other);
public override bool Equals(object obj);Exact equality: ordinal on both strings, per component on the pose.
GetHashCode
public override int GetHashCode();operator ==
public static bool operator ==(EntityLocation a, EntityLocation b);operator !=
public static bool operator !=(EntityLocation a, EntityLocation b);ToString
public override string ToString();scope:container@(x, y, z)/(x, y, z, w), with public for the public world and none for no container. Invariant culture, round-trip float format.