feat(core): Phase W Stage 0 — [cell-swept] diagnostic (swept vs static cell, no behavior change)

Add ProbeSweptEnabled (ACDREAM_PROBE_SWEPT=1) to PhysicsDiagnostics mirroring
ProbeCellEnabled. Emits one [cell-swept] line per ResolveWithTransition call —
sp.CurCellId and sp.CheckCellId (the transition's swept cells) alongside the
incoming cellId so a doorway capture shows whether the swept cell is stable
where ResolveCellId strobes. No ResolveCellId call in the probe — avoids the
CellGraph.CurrCell side effect. No behavior change.

TDD: ProbeSweptEnabled_DefaultsToFalse RED→GREEN in PhysicsDiagnosticsTests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-02 14:08:00 +02:00
parent 50b168bc1e
commit 851cecc757
3 changed files with 35 additions and 0 deletions

View file

@ -408,6 +408,21 @@ public static class PhysicsDiagnostics
public static bool ProbePlacementFailEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_PLACEMENT_FAIL") == "1";
/// <summary>
/// Phase W Stage 0 (2026-06-02): one <c>[cell-swept]</c> line per
/// <see cref="PhysicsEngine.ResolveWithTransition"/> call — the
/// transition's swept cell (<c>sp.CurCellId</c>/<c>sp.CheckCellId</c>)
/// vs the position-derived cell the legacy static
/// <see cref="PhysicsEngine.ResolveCellId"/> path used. Proves the swept
/// cell is stable where the static one strobes at the doorway boundary.
///
/// <para>
/// Initial state from <c>ACDREAM_PROBE_SWEPT=1</c>. Zero cost when off.
/// </para>
/// </summary>
public static bool ProbeSweptEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_SWEPT") == "1";
/// <summary>
/// A6.P3 issue #98 step-walk investigation (2026-05-23). When true,
/// emits one <c>[step-walk]</c> line at selected points in the transition

View file

@ -898,6 +898,15 @@ public sealed class PhysicsEngine
$"[resolve] ent=0x{movingEntityId:X8} in=({currentPos.X:F3},{currentPos.Y:F3},{currentPos.Z:F3}) cell=0x{cellId:X8} tgt=({targetPos.X:F3},{targetPos.Y:F3},{targetPos.Z:F3}) out=({probePost.X:F3},{probePost.Y:F3},{probePost.Z:F3}) cell=0x{sp.CheckCellId:X8} ok={ok} groundedIn={isOnGround} cp={probeCp} hit={probeHit} walkable={sp.HasLastWalkablePolygon}"));
}
// Phase W Stage 0 (2026-06-02): [cell-swept] probe — swept cell vs static-derived cell.
// Emits before the ResolveResult is built so it shows what BOTH paths would return.
// No ResolveCellId call here (it has a CellGraph.CurrCell side effect). No behavior change.
if (PhysicsDiagnostics.ProbeSweptEnabled)
{
Console.WriteLine(System.FormattableString.Invariant(
$"[cell-swept] ent=0x{movingEntityId:X8} ok={ok} inCell=0x{cellId:X8} curCell=0x{sp.CurCellId:X8} checkCell=0x{sp.CheckCellId:X8} curPos=({sp.CurPos.X:F3},{sp.CurPos.Y:F3},{sp.CurPos.Z:F3}) checkPos=({sp.CheckPos.X:F3},{sp.CheckPos.Y:F3},{sp.CheckPos.Z:F3})"));
}
ResolveResult resolveResult;
if (ok)
{

View file

@ -143,6 +143,17 @@ public class PhysicsDiagnosticsTests
}
}
// -----------------------------------------------------------------------
// ProbeSweptEnabled — Phase W Stage 0 (2026-06-02): [cell-swept] diagnostic.
// -----------------------------------------------------------------------
[Fact]
public void ProbeSweptEnabled_DefaultsToFalse()
{
PhysicsDiagnostics.ProbeSweptEnabled = false;
Assert.False(PhysicsDiagnostics.ProbeSweptEnabled);
}
// -----------------------------------------------------------------------
// ProbeDumpGfxObjs — parallel of ProbeDumpCells (A6.P3 #98, evening v2).
// -----------------------------------------------------------------------