fix(rendering): publish scene deltas at update boundary

Move the ordinary shadow-scene drain out of the conditional spatial reconciler and into an explicit final update-frame commit phase. This publishes deltas after streaming, network, teleport, camera, and conditional reconciles even while world simulation is quiesced.

Release gate: 3,733 App tests / 3 skips; 8,217 complete-solution tests / 5 skips.

Co-Authored-By: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-24 23:00:31 +02:00
parent 91463db551
commit 9fab1feb46
7 changed files with 57 additions and 9 deletions

View file

@ -30,6 +30,7 @@ public sealed class UpdateFrameOrchestratorTests
"teleport",
"auto-entry",
"camera",
"commit",
],
calls);
}
@ -65,6 +66,7 @@ public sealed class UpdateFrameOrchestratorTests
"inbound-player-projection",
"inbound-player-reconcile",
"camera",
"commit",
],
calls);
}
@ -89,7 +91,7 @@ public sealed class UpdateFrameOrchestratorTests
[
"teardown", "clock", "streaming", "input", "objects",
"network", "commands", "ordinary-reconcile", "liveness",
"teleport", "auto-entry", "camera",
"teleport", "auto-entry", "camera", "commit",
],
calls);
Assert.Equal([0.0], observed.PublishedTimes);
@ -153,6 +155,7 @@ public sealed class UpdateFrameOrchestratorTests
Assert.Equal(3, calls.Count(call => call == "network"));
Assert.Equal(3, calls.Count(call => call == "teleport"));
Assert.Equal(3, calls.Count(call => call == "camera"));
Assert.Equal(3, calls.Count(call => call == "commit"));
Assert.Equal([0.25f, 0.25f, 0.25f], observed.LiveDeltas);
Assert.Equal([0.25f, 0.25f, 0.25f], observed.TeleportDeltas);
}
@ -190,7 +193,7 @@ public sealed class UpdateFrameOrchestratorTests
[
"teardown", "clock", "streaming", "input", "objects", "network",
"commands", "ordinary-reconcile", "liveness", "teleport",
"auto-entry", "camera",
"auto-entry", "camera", "commit",
];
Assert.Equal(oneFrame.Concat(oneFrame), calls);
}
@ -228,6 +231,7 @@ public sealed class UpdateFrameOrchestratorTests
typeof(ILocalPlayerTeleportFramePhase),
typeof(IPlayerModeAutoEntryFramePhase),
typeof(ICameraFramePhase),
typeof(IUpdateFrameCommitPhase),
typeof(IWorldGenerationAvailability),
];
@ -907,6 +911,7 @@ public sealed class UpdateFrameOrchestratorTests
new RecordingTeleport(calls, observed, teleportPlace),
new RecordingAutoEntry(calls),
new RecordingCamera(calls, observed, inboundCreatedPlayer),
new RecordingCommit(calls),
availability);
}
@ -1023,6 +1028,12 @@ public sealed class UpdateFrameOrchestratorTests
}
}
private sealed class RecordingCommit(List<string> calls)
: IUpdateFrameCommitPhase
{
public void Commit() => calls.Add("commit");
}
private sealed class FrameObservations
{
public List<double> PublishedTimes { get; } = [];