feat(runtime): bridge executor completion to the placement stream
Cutover slice C0 (docs/plans/2026-08-02-placement-cutover.md): the seam work that lets C3 flip hosts onto a complete receipt stream instead of growing one mid-cutover. The executor's Released exit now publishes an acknowledge-only ExecutorCompleted receipt through the one placement projection stream — registered before observer dispatch, correlated to the full execution receipt, reaped exactly once on acknowledgement/ discard/session-clear, and counted in the convergence ledger. All three production placement sinks acknowledge-and-ignore the new kind via early returns proven behavior-preserving for every existing kind; without them the first such receipt at cutover would permanently wedge the exact-head FIFO behind sinks that return false. Provably inert today: the publisher has no production caller. Execute's live inputs now derive from Runtime's own owners bound at GameRuntime construction: UsePositionFromServer is retail's exact autonomy_level != 2 (CommandInterpreter::UsePositionFromServer 0x006B3B40, startup-only knob), and PlayerDistance uses the live movement controller's position with a null-safe fallback to the caller struct — never a fabricated origin. TryPrepareAndSubmitAuthoredPlacement chains the prepared-collision Setup read through PrepareMover to submission with zero validation-semantics changes. TryCommitParent and CommitWithdrawal gain the sibling cancellation flow (residence + ordinary placement family); TryCommitParent deliberately omits LeaveWorld — retail's set_parent performs its single gated leave_world (0x00515A90) and a second would have no counterpart. Not fully dormant: the two cancellation fixes change Runtime paths production already calls (today as no-op-adjacent hardening, since nothing upstream begins a residence yet); everything else is reachable only by tests. Reviewed: retail-conformance PASS + architecture/ adversarial PASS after one fix round (sink wedge, completion-receipt lifecycle, null-controller distance). Runtime 921/921; complete Release solution 10,716 passed / 4 intentional skips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
27e05b99e4
commit
67f63e85e5
14 changed files with 1639 additions and 11 deletions
|
|
@ -340,6 +340,51 @@ public sealed class RuntimeCharacterStateTests
|
|||
Assert.False(state.CaptureOwnership().MovementSkillsAreReset);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// C0-2: retail CommandInterpreter::autonomy_level/UsePositionFromServer
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void AutonomyLevel_DefaultsToFullAndMirrorsRetailUsePositionFromServer()
|
||||
{
|
||||
using var state = new RuntimeCharacterState();
|
||||
|
||||
Assert.Equal(RuntimeCharacterState.FullAutonomyLevel, state.AutonomyLevel);
|
||||
Assert.False(state.UsePositionFromServer);
|
||||
Assert.True(state.CaptureOwnership().AutonomyIsDefault);
|
||||
|
||||
Assert.True(state.TrySetAutonomyLevel(0u));
|
||||
Assert.Equal(0u, state.AutonomyLevel);
|
||||
Assert.True(state.UsePositionFromServer);
|
||||
Assert.False(state.CaptureOwnership().AutonomyIsDefault);
|
||||
|
||||
Assert.True(state.TrySetAutonomyLevel(1u));
|
||||
Assert.True(state.UsePositionFromServer);
|
||||
|
||||
// Retail's SetAutonomyLevel rejects anything above 2; the level and
|
||||
// the derived UsePositionFromServer gate stay exactly as they were.
|
||||
Assert.False(state.TrySetAutonomyLevel(3u));
|
||||
Assert.Equal(1u, state.AutonomyLevel);
|
||||
|
||||
Assert.True(state.TrySetAutonomyLevel(RuntimeCharacterState.FullAutonomyLevel));
|
||||
Assert.False(state.UsePositionFromServer);
|
||||
Assert.True(state.CaptureOwnership().AutonomyIsDefault);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResetSession_RestoresAutonomyLevelToFull()
|
||||
{
|
||||
using var state = new RuntimeCharacterState();
|
||||
Assert.True(state.TrySetAutonomyLevel(0u));
|
||||
Assert.True(state.UsePositionFromServer);
|
||||
|
||||
state.ResetSession();
|
||||
|
||||
Assert.Equal(RuntimeCharacterState.FullAutonomyLevel, state.AutonomyLevel);
|
||||
Assert.False(state.UsePositionFromServer);
|
||||
Assert.True(state.CaptureOwnership().AutonomyIsDefault);
|
||||
}
|
||||
|
||||
private static ActiveEnchantmentRecord MakeVitae(uint spellId, float val) =>
|
||||
new(
|
||||
spellId, LayerId: 0u, Duration: -1f, CasterGuid: 0u,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue