fix(streaming): preserve exact live projection identity

Carry RuntimeEntityKey through spatial residency, visibility transitions, rebucketing, quiescence, landblock retirement, and origin recentering. This prevents stale incarnation edges from mutating a replacement projection while retaining the static DAT-entity path.

Validated by 104 focused ownership/streaming tests, the Release solution build, and 8,444 complete Release tests with five existing skips.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-25 22:09:55 +02:00
parent 420e5eea70
commit e937cc36df
8 changed files with 338 additions and 120 deletions

View file

@ -951,7 +951,10 @@ public sealed class LiveEntityRuntime : ILiveEntityRadarSource
{
try
{
_spatial.RebucketLiveEntity(entity, spatialCellOrLandblockId);
_spatial.RebucketLiveEntity(
key,
entity,
spatialCellOrLandblockId);
}
catch (AggregateException error)
{
@ -974,7 +977,7 @@ public sealed class LiveEntityRuntime : ILiveEntityRadarSource
runtimeNotificationFailure: null);
return false;
}
bool visible = _spatial.IsLiveEntityProjectionResident(entity.Id);
bool visible = _spatial.IsLiveEntityProjectionResident(key);
record.IsSpatiallyVisible = visible;
RefreshPresentation(record);
if ((spatialCellOrLandblockId & 0xFFFFu) != 0xFFFFu)
@ -1483,6 +1486,23 @@ public sealed class LiveEntityRuntime : ILiveEntityRadarSource
return false;
}
internal bool TryGetProjectionKey(
uint serverGuid,
out RuntimeEntityKey key)
{
if (_projections.TryGetCurrent(
serverGuid,
out LiveEntityRecord? record)
&& record.ProjectionKey is { } found)
{
key = found;
return true;
}
key = default;
return false;
}
public bool ClearAnimationRuntime(uint serverGuid)
{
if (!_projections.TryGetCurrent(serverGuid, out LiveEntityRecord? record)
@ -2942,25 +2962,26 @@ public sealed class LiveEntityRuntime : ILiveEntityRadarSource
}
}
private void OnSpatialVisibilityChanged(uint localEntityId, bool visible)
private void OnSpatialVisibilityChanged(RuntimeEntityKey key, bool visible)
{
// GpuWorldState serializes re-entrant visibility callbacks. A callback
// may delete an incarnation and materialize the same server GUID before
// an older queued edge drains. Apply an edge only while it still
// matches current spatial truth; otherwise it belongs to the displaced
// projection and must not mutate the replacement generation.
if (_spatial.IsLiveEntityProjectionResident(localEntityId) != visible)
if (_spatial.IsLiveEntityProjectionResident(key) != visible)
return;
if (!_projections.TryGetByLocalId(
localEntityId,
if (!_projections.TryGet(
key,
out LiveEntityRecord? record)
|| record.WorldEntity is not { } entity
|| entity.Id != localEntityId)
|| entity.Id != key.LocalEntityId)
return;
uint serverGuid = record.ServerGuid;
bool wasVisible = record.IsSpatiallyVisible;
RuntimeEntityKey key = RequireProjectionKey(record);
if (RequireProjectionKey(record) != key)
return;
bool wasOrdinaryRoot = _spatialRootObjects.TryGetValue(
key,
out LiveEntityRecord? indexedRoot)