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

@ -1,5 +1,6 @@
using AcDream.App.Audio;
using AcDream.Core.Selection;
using AcDream.Runtime.Entities;
namespace AcDream.App.Streaming;
@ -62,22 +63,22 @@ internal sealed class WorldGenerationQuiescence
private readonly WorldGenerationAvailabilityState _availability;
private readonly SelectionState _selection;
private readonly GpuWorldState _world;
private readonly Func<uint, uint?> _resolveLocalEntityId;
private readonly Func<uint, RuntimeEntityKey?> _resolveProjectionKey;
private readonly IWorldAudioQuiescence? _audio;
public WorldGenerationQuiescence(
WorldGenerationAvailabilityState availability,
SelectionState selection,
GpuWorldState world,
Func<uint, uint?> resolveLocalEntityId,
Func<uint, RuntimeEntityKey?> resolveProjectionKey,
IWorldAudioQuiescence? audio)
{
_availability = availability
?? throw new ArgumentNullException(nameof(availability));
_selection = selection ?? throw new ArgumentNullException(nameof(selection));
_world = world ?? throw new ArgumentNullException(nameof(world));
_resolveLocalEntityId = resolveLocalEntityId
?? throw new ArgumentNullException(nameof(resolveLocalEntityId));
_resolveProjectionKey = resolveProjectionKey
?? throw new ArgumentNullException(nameof(resolveProjectionKey));
_audio = audio;
}
@ -89,8 +90,8 @@ internal sealed class WorldGenerationQuiescence
uint? selected = firstEdge ? _selection.SelectedObjectId : null;
bool clearWorldSelection =
selected is uint selectedGuid
&& _resolveLocalEntityId(selectedGuid) is uint localEntityId
&& _world.IsLiveEntityVisible(localEntityId);
&& _resolveProjectionKey(selectedGuid) is RuntimeEntityKey key
&& _world.IsLiveEntityVisible(key);
_availability.Begin(generation);
if (!firstEdge)