test(physics): Phase W triage — fix stale GetMaxSpeed tests; file #104 (particle cell-clip deferral)

GetMaxSpeed deliberately does NOT branch on ForwardCommand — it returns RunAnimSpeed x run-rate as the InterpolationManager.AdjustOffset catch-up speed (doc comment + ACE MotionInterp.cs:670-678, retail-verified; the slow catch-up fixed the 1-Hz remote-blip). The 3 failing tests (WalkForward/WalkBackward/Idle) asserted a REMOVED command-branching design. Consolidated into one [Theory] pinning the no-branch contract across commands.

Also files #104 (LOW): scene VFX particles not clipped to the PView visible cell set — deferred out of the Phase W seal (entity bleed already gated by Stage 5; scene particles depth-tested; sky particles scissored). Needs OwnerCellId plumbing (~6-8 files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-02 16:37:49 +02:00
parent 872dd34943
commit 21609a7cd7
2 changed files with 47 additions and 29 deletions

View file

@ -838,40 +838,27 @@ public sealed class MotionInterpreterTests
Assert.Equal(MotionInterpreter.RunAnimSpeed * 1.5f, speed, precision: 4); // 6.0
}
[Fact]
public void GetMaxSpeed_WalkForward_ReturnsWalkAnimSpeed()
[Theory]
[InlineData(MotionCommand.WalkForward)]
[InlineData(MotionCommand.WalkBackward)]
[InlineData(MotionCommand.Ready)]
[InlineData(MotionCommand.RunForward)]
public void GetMaxSpeed_IgnoresForwardCommand_AlwaysReturnsRunRate(uint command)
{
// WalkForward max speed is always WalkAnimSpeed (3.12) — no run-rate scaling.
// GetMaxSpeed is the InterpolationManager.AdjustOffset catch-up speed — it deliberately
// returns RunAnimSpeed × run-rate REGARDLESS of the current ForwardCommand (see GetMaxSpeed's
// doc comment: the bare run rate × RunAnimSpeed, ACE MotionInterp.cs:670-678, retail-verified
// — the slow catch-up is intentional, it fixed the 1-Hz remote-blip). It does NOT branch
// per-command. These previously asserted a REMOVED command-branching design (WalkForward →
// WalkAnimSpeed, WalkBackward → ×0.65, Idle → 0); that contract no longer exists, so they are
// consolidated here to PIN the no-branch contract across commands (Phase W green-tests triage).
var interp = MakeInterp();
interp.InterpretedState.ForwardCommand = MotionCommand.WalkForward;
interp.MyRunRate = 1.75f;
interp.InterpretedState.ForwardCommand = command;
float speed = interp.GetMaxSpeed();
Assert.Equal(MotionInterpreter.WalkAnimSpeed, speed, precision: 4);
}
[Fact]
public void GetMaxSpeed_WalkBackward_ReturnsWalkAnimSpeedTimesBackwardsFactor()
{
// BackwardsFactor = 0.65, from adjust_motion @ 0x00528010 in the named retail decomp.
var interp = MakeInterp();
interp.InterpretedState.ForwardCommand = MotionCommand.WalkBackward;
float speed = interp.GetMaxSpeed();
Assert.Equal(MotionInterpreter.WalkAnimSpeed * 0.65f, speed, precision: 4);
}
[Fact]
public void GetMaxSpeed_Idle_ReturnsZero()
{
// Ready / non-locomotion commands → 0 (no movement speed).
var interp = MakeInterp();
interp.InterpretedState.ForwardCommand = MotionCommand.Ready;
float speed = interp.GetMaxSpeed();
Assert.Equal(0f, speed, precision: 4);
Assert.Equal(MotionInterpreter.RunAnimSpeed * 1.75f, speed, precision: 4);
}
[Fact]