Nebula
Containers

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.

generated from the sources
public 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.

On this page