Three final pins complete the still-fixture set: (1) the CELL portal side decode is the INVERSE of the 0x2 bit (uniform with the building convention; the doorway-still flood proved it - ov=2 n=3 exact, and foundry-deep stays green); (2) interior frames key the landscape order off the OUTSIDE-projected landcell (get_outside_cell_id - derived from the camera origin); (3) the outdoor pview has draw_landscape=FALSE so look-in floods discard exit portals - the ov=0 pattern of every traced look-in. CONFORMANT: foundry-deep (every frame), doorway-still, street-outdoor, terrace-center, terrace-edge (the #456 acceptance pose), cathedral-arrival - full frames identical to retail. The moving four diverge only at punch-edge frames (walkabout F9, foundry-entry F67) - pose-timing sensitivity parked in the driver Skip note. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
206 lines
8.6 KiB
C#
206 lines
8.6 KiB
C#
using AcDream.App.Tests.Rendering;
|
|
using AcDream.App.Rendering.Walk;
|
|
using DatReaderWriter;
|
|
using DatReaderWriter.Options;
|
|
|
|
namespace AcDream.App.Tests.Rendering.Walk;
|
|
|
|
/// <summary>
|
|
/// FW1's conformance gate, first slice: replay pose-stamped oracle
|
|
/// fixtures through the ported walk and require the identical event
|
|
/// sequence. The projection-light interior fixtures gate first
|
|
/// (docs/research/2026-08-30-fw-walk-oracle/README.md, posed round);
|
|
/// the outdoor/landscape fixtures join as the landscape world build
|
|
/// lands.
|
|
/// </summary>
|
|
[Trait("Lane", "InstalledDat")]
|
|
public sealed class WalkTraceConformanceTests
|
|
{
|
|
private sealed class Recorder : IWalkEventSink
|
|
{
|
|
public readonly List<WalkEvent> Events = new();
|
|
public void Emit(in WalkEvent walkEvent) => Events.Add(walkEvent);
|
|
}
|
|
|
|
private static DatCollection OpenDats()
|
|
{
|
|
string? datDir = CornerFloodReplayTests.ResolveDatDir();
|
|
if (datDir is null)
|
|
{
|
|
Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
|
|
}
|
|
return new DatCollection(datDir!, DatAccessType.Read);
|
|
}
|
|
|
|
[Fact]
|
|
public void Street_outdoor_first_frame_diff()
|
|
{
|
|
// The first landscape-involving conformance case: diff-first (the
|
|
// assert prints both signatures on mismatch for adjudication).
|
|
IReadOnlyList<WalkOracleFrame> frames =
|
|
WalkOracleTrace.Load("posed/holtburg-street-outdoor");
|
|
Assert.NotEmpty(frames);
|
|
using DatCollection dats = OpenDats();
|
|
WalkOracleFrame frame = frames[1]; // frame 2: pose settled (marker timing)
|
|
Assert.NotNull(frame.Pose);
|
|
WalkLandscapeDatBuilder.BuiltWorld world =
|
|
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
|
|
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
|
|
{
|
|
Buildings = world.Buildings,
|
|
};
|
|
var walk = new RetailFrameWalk();
|
|
var recorder = new Recorder();
|
|
|
|
walk.WalkFrame(frame.Pose.CellId, null, world.Landscape, ctx, recorder);
|
|
|
|
string expected = WalkTraceReplayContext.Signature(frame);
|
|
string actual = WalkTraceReplayContext.Signature(recorder.Events);
|
|
Assert.True(
|
|
expected == actual,
|
|
$"walk diverged from retail\nEXPECTED: {expected}\nACTUAL: {actual}");
|
|
}
|
|
|
|
[Fact]
|
|
public void Doorway_still_first_frame_diff()
|
|
{
|
|
// Interior flood adjudication: DI + DC(ov=2, n=3) + the landscape
|
|
// through two exit views — tests the flood depth in isolation from
|
|
// the building look-in machinery.
|
|
IReadOnlyList<WalkOracleFrame> frames =
|
|
WalkOracleTrace.Load("posed/holtburg-doorway-still");
|
|
Assert.NotEmpty(frames);
|
|
using DatCollection dats = OpenDats();
|
|
WalkOracleFrame frame = frames[1];
|
|
Assert.NotNull(frame.Pose);
|
|
WalkLandscapeDatBuilder.BuiltWorld world =
|
|
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
|
|
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
|
|
{
|
|
Buildings = world.Buildings,
|
|
};
|
|
WalkCell camera = Assert.Contains(frame.Pose.CellId, world.Cells);
|
|
var walk = new RetailFrameWalk();
|
|
var recorder = new Recorder();
|
|
|
|
walk.WalkFrame(frame.Pose.CellId, camera, world.Landscape, ctx, recorder);
|
|
|
|
string expected = WalkTraceReplayContext.Signature(frame);
|
|
string actual = WalkTraceReplayContext.Signature(recorder.Events);
|
|
Assert.True(
|
|
expected == actual,
|
|
$"walk diverged from retail\nEXPECTED: {expected}\nACTUAL: {actual}");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("posed/terrace-center")]
|
|
[InlineData("posed/terrace-edge")]
|
|
[InlineData("posed/cathedral-arrival")]
|
|
public void Still_fixture_first_frame_reproduces_exactly(string fixture)
|
|
{
|
|
IReadOnlyList<WalkOracleFrame> frames = WalkOracleTrace.Load(fixture);
|
|
Assert.NotEmpty(frames);
|
|
using DatCollection dats = OpenDats();
|
|
WalkOracleFrame frame = frames[1];
|
|
Assert.NotNull(frame.Pose);
|
|
WalkLandscapeDatBuilder.BuiltWorld world =
|
|
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
|
|
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
|
|
{
|
|
Buildings = world.Buildings,
|
|
};
|
|
WalkCell? camera = (frame.Pose.CellId & 0xFFFFu) >= 0x100
|
|
? Assert.Contains(frame.Pose.CellId, world.Cells)
|
|
: null;
|
|
var walk = new RetailFrameWalk();
|
|
var recorder = new Recorder();
|
|
|
|
walk.WalkFrame(frame.Pose.CellId, camera, world.Landscape, ctx, recorder);
|
|
|
|
string expected = WalkTraceReplayContext.Signature(frame);
|
|
string actual = WalkTraceReplayContext.Signature(recorder.Events);
|
|
Assert.True(
|
|
expected == actual,
|
|
$"walk diverged from retail ({fixture})\nEXPECTED: {expected}\nACTUAL: {actual}");
|
|
}
|
|
|
|
[Theory(Skip = "FW1 moving-fixture tail (2026-08-30): the six STILL fixtures are "
|
|
+ "fully conformant; the moving four diverge only at punch-edge frames "
|
|
+ "(walkout/transitions F2: retail punches 001e where the replay does "
|
|
+ "not; walkabout diverges at F9, foundry-entry at F67) - pose-timing/"
|
|
+ "threshold sensitivity to adjudicate next (the exact pose-application "
|
|
+ "point within the frame).")]
|
|
[InlineData("posed/holtburg-walkout")]
|
|
[InlineData("posed/holtburg-transitions")]
|
|
[InlineData("posed/holtburg-walkabout")]
|
|
[InlineData("posed/foundry-entry")]
|
|
public void Moving_fixture_reproduces_every_pairable_frame(string fixture)
|
|
{
|
|
// Marker timing: the pose stamped at frame N+1 is the camera state
|
|
// frame N drew with (fixture README) — pair events(N) with
|
|
// pose(N+1). One walk + one landscape carry state across frames,
|
|
// reproducing retail's cross-frame caches (the stale cell-order
|
|
// quirk included).
|
|
IReadOnlyList<WalkOracleFrame> frames = WalkOracleTrace.Load(fixture);
|
|
Assert.True(frames.Count >= 3);
|
|
using DatCollection dats = OpenDats();
|
|
WalkOraclePose anchor = frames[1].Pose!;
|
|
WalkLandscapeDatBuilder.BuiltWorld world =
|
|
WalkLandscapeDatBuilder.Build(dats, anchor.CellId, anchor.Origin);
|
|
var walk = new RetailFrameWalk();
|
|
|
|
for (int n = 1; n < frames.Count - 1; n++)
|
|
{
|
|
WalkOracleFrame frame = frames[n];
|
|
WalkOraclePose pose = frames[n + 1].Pose!;
|
|
Assert.NotNull(pose);
|
|
WalkLandscapeDatBuilder.SetViewer(world.Landscape, pose.CellId, pose.Origin);
|
|
var ctx = new WalkTraceReplayContext(pose, world.Cells)
|
|
{
|
|
Buildings = world.Buildings,
|
|
};
|
|
WalkCell? camera = null;
|
|
if ((pose.CellId & 0xFFFFu) >= 0x100)
|
|
{
|
|
Assert.True(
|
|
world.Cells.TryGetValue(pose.CellId, out camera),
|
|
$"frame {frame.Number}: interior camera cell {pose.CellId:x8} not loaded");
|
|
}
|
|
var recorder = new Recorder();
|
|
|
|
walk.WalkFrame(pose.CellId, camera, world.Landscape, ctx, recorder);
|
|
|
|
string expected = WalkTraceReplayContext.Signature(frame);
|
|
string actual = WalkTraceReplayContext.Signature(recorder.Events);
|
|
Assert.True(
|
|
expected == actual,
|
|
$"frame {frame.Number} diverged ({fixture})\nEXPECTED: {expected}\nACTUAL: {actual}");
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Foundry_deep_reproduces_every_complete_frame_exactly()
|
|
{
|
|
IReadOnlyList<WalkOracleFrame> frames = WalkOracleTrace.Load("posed/foundry-deep");
|
|
Assert.NotEmpty(frames);
|
|
using DatCollection dats = OpenDats();
|
|
Dictionary<uint, WalkCell> cells =
|
|
WalkWorldDatAdapter.BuildInteriorCells(dats, 0xA9B40000u);
|
|
var landscape = new WalkLandscape { MidWidth = 1, Blocks = new WalkLandBlock?[1] };
|
|
|
|
foreach (WalkOracleFrame frame in frames)
|
|
{
|
|
Assert.NotNull(frame.Pose);
|
|
WalkCell camera = Assert.Contains(frame.Pose!.CellId, cells);
|
|
var ctx = new WalkTraceReplayContext(frame.Pose, cells);
|
|
var walk = new RetailFrameWalk();
|
|
var recorder = new Recorder();
|
|
|
|
walk.WalkFrame(frame.Pose.CellId, camera, landscape, ctx, recorder);
|
|
|
|
Assert.Equal(
|
|
WalkTraceReplayContext.Signature(frame),
|
|
WalkTraceReplayContext.Signature(recorder.Events));
|
|
}
|
|
}
|
|
}
|