test(overhaul): land reviewed C1c replay correction and retire AD-118

This commit is contained in:
Erik 2026-09-05 12:35:45 +02:00
parent 744b1b0efb
commit 42afec6141
10 changed files with 492 additions and 176 deletions

View file

@ -218,8 +218,10 @@ remaining closeout gates. No merge main.
## #472 — Stair-arch walk fixture cannot distinguish retail e229 residency from block rejection
**Status:** IN-PROGRESS — capture complete; §40's diagnostic resolves the
mismatch. Permanent default replay correction and review remain before closure.
**Status:** DONE 2026-09-05 — C1c made the captured matrix path, explicit
next-marker pose, and live-view EC multiplicity the permanent shared replay
defaults. The exact 25-frame Signature8 proof passes; no renderer defect was
established. Geometry/membership closeout remains a separate C1a chunk.
**Severity:** EVIDENCE BLOCKER (no production renderer defect established)
**Component:** InstalledDat walk-conformance harness / retail capture corpus
@ -266,8 +268,9 @@ next-marker pose, and per-live-view EC recording reproduce all four stair
frames exactly (2158/2158), with e229 Outside and no LC/SC. All six OH walk
fixtures plus the new capture are exact (25/25 complete frames). The historical
capture/acceptance paragraphs above are superseded; this is a replay-harness
defect, not an accepted x87 renderer divergence. Packet §40 contracts the
permanent correction, regression tests and reviews. #472 is not closed yet.
defect, not an accepted x87 renderer divergence. C1c permanently corrected the
shared replay/parser/recorder and added discriminating regression tests; #472
is closed. This does not claim universal bit-identical D3D/x87 projection.
## #471 — Production walk-ordered building detail was classified but never rendered
@ -633,23 +636,24 @@ so this class is caught on every gate, not only when the lead remembers the env
## #458 — Walk admits land block `a9c9` at holtburg-doorway-still that retail does not draw
**Status:** REOPENED 2026-09-05 — the former x87-only attribution below is
disproven by S5 packet §40's diagnostic. Corrected matrix rays/projection and
next-marker pose reproduce all four doorway frames exactly (1185/1185).
Permanent default replay correction, KnownFailure removal and review remain.
The 2026-09-03 investigation/resolution below is retained as superseded history.
**Status:** DONE 2026-09-05 — C1c permanently corrected the shared replay to
the captured matrix ray/projection path and explicit next-marker pose. All four
doorway frames reproduce exactly (1185/1185); the ordinary frame-1 row passes
and its KnownFailure trait is removed. The 2026-09-03 investigation/resolution
below is retained as superseded history.
**Severity:** MEDIUM (retail-order exactness; one far land cell drawn that retail skips — no known visible artifact)
**Component:** `WalkLandscape.CheckBlocks` / `LandCellCheck` block-level visibility at a LOD-ring boundary
**Symptom:** replaying `docs/research/2026-09-01-overhaul/oh-capture/holtburg-doorway-still.walk.log`
**Superseded symptom:** replaying `docs/research/2026-09-01-overhaul/oh-capture/holtburg-doorway-still.walk.log`
frame 2 (camera cell `a9b4013f`) through `RetailFrameWalk`, the signature diverges at token 165:
retail `…LC:a8c90001|SC:a8c90001|LC:95c60001…` vs acdream
`…LC:a8c90001|SC:a8c90001|LC:a9c90001|SC:a9c90001|LC:95c60001…` — acdream admits the
side-1 (ring ≥ 5) block `a9c9` through the interior root's exit views; retail's
`LScape::draw_check_blocks` @0x00505f80 / `landcell_check` @0x005050a0 do not. The other
three kit poses (terrace-edge, cathedral-arrival, foundry-deep) reproduce exactly.
`WalkTraceConformanceTests.Oh_doorway_still_first_frame_diff` carries the row tagged
`Status=KnownFailure` with the position documented.
`WalkTraceConformanceTests.Oh_doorway_still_first_frame_diff` formerly carried
the row tagged `Status=KnownFailure`; C1c removed the trait after the ordinary
shared-path frame-1 equality passed.
**Lead experiment (2026-09-03):** with `DegradeMultiplier = 0f` (the FW0 sibling's
cdb-depressed value) the row diverges at the SAME token 165 — the degrade level is NOT the
@ -695,7 +699,7 @@ pose against the decomp (the per-view union, the block MinZ/MaxZ clip heights, t
exit-view edge planes, not the cell test. Resolve in the S3 review round or an S3 chunk 5;
remove the KnownFailure trait in the same commit.
**Resolution (2026-09-03 afternoon, lead + owner, two live cdb captures on the paired 2013
**Superseded resolution (2026-09-03 afternoon, lead + owner, two live cdb captures on the paired 2013
client at a NEARBY doorway pose — `docs/research/2026-09-01-overhaul/oh-capture/
holtburg-doorway-still.blockset.log` and `.blockcheck.log`, templates
`tools/walk-oracle/oh/oh-capture-blockset.cdb.template` / `oh-capture-blockcheck.cdb.template`):**
@ -718,8 +722,11 @@ no `LC`. One far LOD block, one corner, one plane, at a boundary. The morning z-
structural notes above stand (slab and loop shape match). No bit-exact fix exists short of
reproducing D3D's x87 projection and `copy_view`'s float rounding; the conformance row stays
`Status=KnownFailure` with its doc comment rewritten to this finding, and the register
carries it as AD-118. The two look-in-flood divergences (2)/(3) above are the pre-existing
FW1 near-win gate state and remain tracked by `WalkLookInGateSweepTests` (skipped).
carries it as AD-118. C1c later disproved that attribution: the capture used the
matrix branch and next-marker pose, and the corrected shared replay reproduces
the literal transcript. The two historical look-in-flood observations likewise
disappear under the corrected association; the text above remains history, not
an accepted current failure.
## #457 — Two App tests pass only in Release (IL-offset pins fail under Debug)

File diff suppressed because one or more lines are too long

View file

@ -743,6 +743,13 @@ Rynthid Recall6150→3032001C corroborates owner generation4; historical route
labels are not location evidence (479-rynthid-location-evidence.md). #479
transform cause remains unproven. No change to G4 FAIL or the open obligations.
C1c current (packet§53): reviewed nine-file test/doc return now lands from
scratch963728612; all17 source/TRX hashes rechecked, prior lead68/68 and both
review lenses closed. Six test blobs unchanged; production/fixtures untouched.
#458/#472 closed as harness defects, AD-118 retired, counted104/13/91.
Clean post-landing Release/canonical conformance is next, then §45 activation.
The later476F1 AD-121 must preserve this retirement and produce92 active rows.
## 14. Risk register (condensed)
- **R1 second scene graph.** Graph records own only topology/membership facts;

View file

@ -3763,6 +3763,25 @@ AcDream.App.dll copies remained SHA-256
ACE remains UDP 9000/PID 13340. Do not build production or launch another
graphical client beside the owner's running client.
**C1c permanent result (uncommitted implementer return, 2026-09-05):** the
ordinary replay now uses the coherent captured `newmethod=1` matrix path; the
parser retains literal P(N) while exposing events(N)/P(N+1), including the
last raw marker; and the shared Recorder emits EC once per live `TopView`
before OC once per cell. The permanent proof consumes all six historical OH
walks plus the new capture: 25/25 complete frames match at full ordered
Signature8, the doorway frame-1 row passes without KnownFailure, the stair
pins four EC turns/two adjacent duplicate pairs and no LC/SC:e2290001, and
the focused restored lanes pass 29/29 parser/projection, 27/27 conformance,
and 12/12 production-world context invariance. The five required mutations
were run separately and restored: legacy rays fail the center round trip at
0.7078837 px; one-EC-per-cell fails the stair pin (expected 4, actual 2);
same-marker association fails the synthetic final-marker ID and doorway
frame 1 at token 165; changing matrix word 0 fails the captured-word binding
(1065698052 vs 1065698053); redirecting the sixth fixture fails on the absent
canonical `.walk.log`. No fixture or production byte changed, and this result
does not claim universal bit-identical D3D/x87 math. Geometry/membership C1a
remains separate.
### 40.2 C1c scope — permanent test-only correction
One OpenAI implementer uses the existing scratch, fast-forwarding this
@ -4776,3 +4795,22 @@ requirement (AD-121 at landing), actual-command/coherence witnesses and mutation
No global allocator expansion; unchanged phase/lifetime review stays closed.
Prepared route-476-capture-current-frame.txt preserves first request plus two
real resizes, then settled hand-item views; NOT RUN. No new client launched.
## 53. C1c accepted test-only return landed
While #476 F1 is implemented, root landed the already-reviewed nine-file C1c
return from §43. Scratch96372861249a092998dd0dc6deed6d1d4196eb8a preserves
the exact six reviewed test blobs; root rechecked all17 source/TRX hashes in
artifacts/s5-c1c-02219318a/README.txt before committing. Both prior reviews and
root68/68 proof in§43 remain applicable; no new code finding or review round.
The three documentation hunks merge without replacing later campaign evidence.
#458/#472 close as replay-harness defects; AD-118 retired in this same commit.
Fresh root physical-row recount104 total/13 retired/91 active AD rows.
No production, fixture, package or graphical change. Exact current production
remains #477 + #480; #476 is still unintegrated. Post-landing clean Release and
canonical conformance checks are next, classifying every nonpassing identity.
Only after those checks may §45's separately bounded geometry/membership witness
activate on a new clean base. F1's later AD-121 addition must preserve retired
AD-118 and make the combined AD count92, not restore the stale pre-C1c header.
No new graphical run; G4 FAIL, remaining owner issues/full lanes/C2 still open.

View file

@ -13,7 +13,10 @@ namespace AcDream.App.Tests.Rendering.Walk;
///
/// The final frame of every capture is dropped: the harness detaches at
/// the frame MARKER, so the last frame never records its draws and would
/// read as a false "outdoor, no landscape" frame.
/// read as a false "outdoor, no landscape" frame. Its raw P record is
/// nevertheless retained as the preceding complete frame's ReplayPose:
/// RenderNormalMode's entry marker is prior-frame state, so events(N) pair
/// with P(N+1), not their literal P(N) marker.
/// </summary>
public static class WalkOracleTrace
{
@ -23,6 +26,7 @@ public static class WalkOracleTrace
List<WalkOracleEvent>? current = null;
int currentNumber = 0;
WalkOraclePose? currentPose = null;
int frameAwaitingReplayPose = -1;
foreach (string line in lines)
{
@ -30,7 +34,10 @@ public static class WalkOracleTrace
if (frameMatch.Success)
{
if (current is not null)
{
frames.Add(new WalkOracleFrame(currentNumber, current, currentPose));
frameAwaitingReplayPose = frames.Count - 1;
}
currentNumber = int.Parse(
frameMatch.Groups[1].Value, CultureInfo.InvariantCulture);
current = new List<WalkOracleEvent>();
@ -60,6 +67,17 @@ public static class WalkOracleTrace
BitConverter.Int32BitsToSingle((int)raw[5]),
BitConverter.Int32BitsToSingle((int)raw[6]),
BitConverter.Int32BitsToSingle((int)raw[7]));
// RenderNormalMode's entry marker observes the PREVIOUS
// rendered frame: events(N) therefore use marker P(N+1).
// Assign it explicitly to the already-complete prior frame.
// This also consumes the last raw P marker even though its
// own event-incomplete frame remains deliberately dropped.
if (frameAwaitingReplayPose >= 0)
{
frames[frameAwaitingReplayPose] = frames[frameAwaitingReplayPose]
with { ReplayPose = currentPose };
frameAwaitingReplayPose = -1;
}
continue;
}
@ -180,7 +198,7 @@ public static class WalkOracleTrace
private static readonly Regex ObjectCellTurnPattern = new(@"^OC ([0-9a-f]{8})\s*$", RegexOptions.Compiled);
}
/// <summary>The camera pose dumped at the frame marker (raw dwords from
/// <summary>The literal camera pose dumped at the frame marker (raw dwords from
/// <c>Render::viewer_pos</c> @0x0081ef00): the camera's cell id, world
/// origin, and the Frame quaternion's four raw components (q0..q3 in
/// storage order — axis convention resolved by the replay runner).
@ -196,8 +214,14 @@ public sealed record WalkOraclePose(
public sealed record WalkOracleFrame(
int Number,
IReadOnlyList<WalkOracleEvent> Events,
WalkOraclePose? Pose = null)
WalkOraclePose? Pose = null,
WalkOraclePose? ReplayPose = null)
{
/// <summary><see cref="Pose"/> is the literal P record after this frame's
/// marker. <see cref="ReplayPose"/> is the following marker's P record,
/// the camera state this frame's events actually rendered with. The
/// parser fills it from the raw final marker without creating a fake
/// event frame.</summary>
/// <summary>The frame's root: the first DrawInside cell, or null when outdoor-rooted.</summary>
public uint? InteriorRootCell
=> Events.FirstOrDefault(e => e.Kind == WalkOracleEventKind.DrawInside)?.CellId;

View file

@ -20,7 +20,7 @@ public sealed class WalkOracleTraceTests
private const string OhRoot = "docs/research/2026-09-01-overhaul/oh-capture";
/// <summary>(root, fixture name) pairs. Every FW0 still/posed fixture
/// keeps its old bare name under <see cref="FwRoot"/>; the five OH
/// keeps its old bare name under <see cref="FwRoot"/>; the six OH
/// walk captures (§11.2 B3) join under <see cref="OhRoot"/> with the
/// <c>.walk</c> filename-half suffix.</summary>
public static readonly TheoryData<string, string> AllFixtures = new()
@ -40,6 +40,7 @@ public sealed class WalkOracleTraceTests
{ OhRoot, "cathedral-arrival.walk" },
{ OhRoot, "foundry-deep.walk" },
{ OhRoot, "cathedral-leak.walk" },
{ OhRoot, "cathedral-stair-arch.walk" },
};
[Theory]
@ -55,6 +56,33 @@ public sealed class WalkOracleTraceTests
Assert.All(frames, f => Assert.NotEmpty(f.Events));
}
[Fact]
public void Replay_pose_uses_next_marker_including_the_dropped_final_frame()
{
string[] lines =
[
"F 1",
"P 11110100 3f800000 40000000 40400000 3f800000 00000000 00000000 00000000",
"LS",
"F 2",
"P 22220200 40800000 40a00000 40c00000 00000000 3f800000 00000000 00000000",
"LS",
"F 3",
"P 33330300 40e00000 41000000 41100000 00000000 00000000 3f800000 00000000",
];
IReadOnlyList<WalkOracleFrame> frames = WalkOracleTrace.Parse(lines);
Assert.Equal(2, frames.Count); // F3 remains an incomplete event frame.
Assert.Equal(0x11110100u, frames[0].Pose!.CellId);
Assert.Equal(0x22220200u, frames[0].ReplayPose!.CellId);
Assert.Equal(new System.Numerics.Vector3(4f, 5f, 6f), frames[0].ReplayPose!.Origin);
Assert.Equal(0x22220200u, frames[1].Pose!.CellId);
Assert.Equal(0x33330300u, frames[1].ReplayPose!.CellId);
Assert.Equal(new System.Numerics.Vector3(7f, 8f, 9f), frames[1].ReplayPose!.Origin);
Assert.DoesNotContain(frames, frame => frame.Number == 3);
}
/// <summary>S3 chunk 1 fix round 1 (G8/G10): the "assert separately"
/// half of <see cref="WalkTraceReplayContext.Signature8(WalkOracleFrame)"/>'s
/// own doc comment — that method's derivation never produces the

View file

@ -0,0 +1,123 @@
using System.Globalization;
using System.Numerics;
using AcDream.App.Rendering.Walk;
namespace AcDream.App.Tests.Rendering.Walk;
public sealed class WalkReplayProjectionTests
{
private const string OhRoot =
"docs/research/2026-09-01-overhaul/oh-capture";
[Fact]
public void Captured_matrix_screen_ray_screen_round_trips_without_legacy_half_pixel()
{
WalkOracleFrame captured = Assert.Single(WalkOracleTrace.Load(
OhRoot,
"cathedral-stair-arch-e229.combined-r1"));
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(captured.ReplayPose);
var context = new WalkTraceReplayContext(
pose,
new Dictionary<uint, WalkCell>());
Vector2[] points =
[
new(512f, 360f),
new(0f, 0f),
new(1024f, 0f),
new(1024f, 720f),
new(0f, 720f),
new(127.25f, 83.75f),
new(817.5f, 611.125f),
];
foreach (Vector2 point in points)
{
Vector3 ray = context.Rays.RayThrough(point.X, point.Y);
Vector2 roundTrip = context.ProjectWorldToScreen(
pose.Origin + ray * 100f);
float error = Vector2.Distance(point, roundTrip);
Assert.True(
error <= 0.001f,
string.Create(
CultureInfo.InvariantCulture,
$"matrix round-trip error {error:R} at {point}"));
}
Vector3 legacyCenterRay = LegacyRayThrough(pose, 512f, 360f);
Vector2 legacyCenter = context.ProjectWorldToScreen(
pose.Origin + legacyCenterRay * 100f);
Assert.InRange(MathF.Abs(legacyCenter.X - 512f), 0.45f, 0.55f);
Assert.InRange(MathF.Abs(legacyCenter.Y - 360f), 0.45f, 0.55f);
}
[Fact]
public void Configured_projection_is_bound_to_captured_newmethod_matrix_words()
{
string[] lines = File.ReadAllLines(FixturePath(
"cathedral-stair-arch-e229.projection-mode"));
int newMethod = Array.FindIndex(lines, line => line.Trim() == "NEWMETHOD");
Assert.True(newMethod >= 0);
Assert.Matches(@"\s00000001\s*$", lines[newMethod + 1]);
int heading = Array.FindIndex(lines, line => line.Trim() == "VIEW_TO_CLIP");
Assert.True(heading >= 0);
uint[] captured = lines.Skip(heading + 1)
.Take(4)
.SelectMany(ParseDumpRow)
.ToArray();
Matrix4x4 configured = WalkTraceReplayContext.CapturedViewToClip();
uint[] actual =
[
Bits(configured.M11), Bits(configured.M12), Bits(configured.M13), Bits(configured.M14),
Bits(configured.M21), Bits(configured.M22), Bits(configured.M23), Bits(configured.M24),
Bits(configured.M31), Bits(configured.M32), Bits(configured.M33), Bits(configured.M34),
Bits(configured.M41), Bits(configured.M42), Bits(configured.M43), Bits(configured.M44),
];
Assert.Equal(captured, actual);
}
private static Vector3 LegacyRayThrough(
WalkOraclePose pose,
float screenX,
float screenY)
{
var rotation = new Quaternion(pose.Q1, pose.Q2, pose.Q3, pose.Q0);
Vector3 right = Vector3.Transform(Vector3.UnitX, rotation);
Vector3 forward = Vector3.Transform(Vector3.UnitY, rotation);
Vector3 up = Vector3.Transform(Vector3.UnitZ, rotation);
float u = screenX * 0.00025f - 0.127875f;
float w = screenY * 0.00025f - 0.089875f;
return right * u + forward * 0.1330766976f - up * w;
}
private static IEnumerable<uint> ParseDumpRow(string line)
{
string[] fields = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
Assert.Equal(5, fields.Length);
return fields.Skip(1).Select(value => uint.Parse(
value,
NumberStyles.HexNumber,
CultureInfo.InvariantCulture));
}
private static uint Bits(float value) =>
BitConverter.SingleToUInt32Bits(value);
private static string FixturePath(string fixtureName) => Path.Combine(
FindRepositoryRoot(),
Path.Combine(OhRoot.Split('/')),
fixtureName + ".log");
private static string FindRepositoryRoot()
{
DirectoryInfo? directory = new(AppContext.BaseDirectory);
while (directory is not null)
{
if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx")))
return directory.FullName;
directory = directory.Parent;
}
throw new InvalidOperationException("AcDream.slnx not found.");
}
}

View file

@ -308,8 +308,7 @@ public sealed partial class WalkTraceConformanceTests
Assert.NotEmpty(poseFrames);
Assert.True(poseFrames.Count > 1, $"{fixtureName}: need a captured frame 2.");
WalkOracleFrame poseFrame = poseFrames[1];
Assert.NotNull(poseFrame.Pose);
WalkOraclePose pose = poseFrame.Pose!;
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(poseFrame.ReplayPose);
IReadOnlyList<WalkAlphaDepthFrame> depthFrames = WalkAlphaDepthTrace.Load(OhCaptureRoot, fixtureName);
Assert.True(depthFrames.Count > 1, $"{fixtureName}: need a captured frame 2's PM/PC content.");
@ -394,8 +393,7 @@ public sealed partial class WalkTraceConformanceTests
Assert.NotEmpty(poseFrames);
Assert.True(poseFrames.Count > 1, $"{fixtureName}: need a captured frame 2.");
WalkOracleFrame poseFrame = poseFrames[1];
Assert.NotNull(poseFrame.Pose);
WalkOraclePose pose = poseFrame.Pose!;
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(poseFrame.ReplayPose);
IReadOnlyList<WalkAlphaDepthFrame> depthFrames = WalkAlphaDepthTrace.Load(OhCaptureRoot, fixtureName);
Assert.True(depthFrames.Count > 1, $"{fixtureName}: need a captured frame 2's AM/FL content.");

View file

@ -34,19 +34,18 @@ public sealed partial class WalkTraceConformanceTests
/// ORACLE side (<see cref="WalkTraceReplayContext.Signature8(WalkOracleFrame)"/>)
/// moved off derivation onto its own literal captured EC/OC lines.
///
/// <para>KNOWN LIMIT (S3 review fix round 1, F4a): the production
/// transcript prints <c>EC</c> once per LIVE VIEW of a flood cell
/// (retail's <c>setup_view</c>/<c>DrawEnvCell</c> loop,
/// <c>PView::DrawCells</c> @0x005a4ab10x005a4acc), but this replay
/// side's <see cref="WalkTraceReplayContext.AppendFloodTurns"/> still
/// derives ONE <c>EC</c> per cell — the sink event carries no per-cell
/// view count. Every fixture passes only because no captured flood cell
/// holds more than one live view at DrawCells time. A fixture with a
/// two-view flood cell would fail here on the second <c>EC</c>; S5's
/// transcript closeout carries the per-cell view count through the
/// sink event and removes this note.</para></summary>
/// <para>C1c: the recorder borrows the real cell map and reads each
/// cell's live <c>TopView.ViewCount</c> while the flood callback still
/// owns it. That reproduces retail's setup_view/DrawEnvCell loop at
/// <c>PView::DrawCells</c> @0x005a4ab10x005a4acc without changing a
/// production event or deriving oracle EC/OC from DC.</para></summary>
private sealed class Recorder : IWalkEventSink
{
private readonly IReadOnlyDictionary<uint, WalkCell> _cells;
public Recorder(IReadOnlyDictionary<uint, WalkCell> cells) =>
_cells = cells;
public readonly List<WalkEvent> Events = new();
public readonly List<string> Tokens = new();
@ -78,7 +77,7 @@ public sealed partial class WalkTraceConformanceTests
// CellStatic, _lookIn still false) defers to
// OnInteriorFloodDrawTurn below — see that method.
if (_lookIn == true)
WalkTraceReplayContext.AppendFloodTurns(Tokens, walkEvent.Cells);
WalkTraceReplayContext.AppendFloodTurns(Tokens, walkEvent.Cells, _cells);
break;
}
}
@ -94,7 +93,7 @@ public sealed partial class WalkTraceConformanceTests
public void OnBuildingTurn(WalkBuilding building) => _lookIn = true;
public void OnInteriorFloodDrawTurn(IReadOnlyList<uint> cells, int outsideViewCount)
=> WalkTraceReplayContext.AppendFloodTurns(Tokens, cells);
=> WalkTraceReplayContext.AppendFloodTurns(Tokens, cells, _cells);
/// <summary>S3 review fix round 1 (F4b): retail's trailing per-frame
/// weather turn (<c>GameSky::Draw(sky,1)</c> @0x00506ff0, fired by
@ -132,17 +131,17 @@ public sealed partial class WalkTraceConformanceTests
Assert.NotEmpty(frames);
using DatCollection dats = OpenDats();
WalkOracleFrame frame = frames[1]; // frame 2: pose settled (marker timing)
Assert.NotNull(frame.Pose);
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkLandscapeDatBuilder.BuiltWorld world =
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
WalkLandscapeDatBuilder.Build(dats, pose.CellId, pose.Origin);
var ctx = new WalkTraceReplayContext(pose, world.Cells)
{
Buildings = world.Buildings,
};
var walk = new RetailFrameWalk(100f, 0.99f);
var recorder = new Recorder();
var recorder = new Recorder(world.Cells);
walk.WalkFrame(frame.Pose.CellId, null, world.Landscape, ctx, recorder);
walk.WalkFrame(pose.CellId, null, world.Landscape, ctx, recorder);
string expected = WalkTraceReplayContext.Signature(frame);
string actual = WalkTraceReplayContext.Signature(recorder.Events);
@ -162,14 +161,14 @@ public sealed partial class WalkTraceConformanceTests
Assert.NotEmpty(frames);
using DatCollection dats = OpenDats();
WalkOracleFrame frame = frames[1];
Assert.NotNull(frame.Pose);
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkLandscapeDatBuilder.BuiltWorld world =
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
WalkLandscapeDatBuilder.Build(dats, pose.CellId, pose.Origin);
var ctx = new WalkTraceReplayContext(pose, world.Cells)
{
Buildings = world.Buildings,
};
WalkCell camera = Assert.Contains(frame.Pose.CellId, world.Cells);
WalkCell camera = Assert.Contains(pose.CellId, world.Cells);
// Render::deg_mul is DYNAMIC (auto-tuned by frame load), and this
// capture ran right after the heavy terrace-edge capture with the
// multiplier depressed: at mul ≤ 0 the degrade thresholds sit at or
@ -179,9 +178,9 @@ public sealed partial class WalkTraceConformanceTests
// max). The recon session's live dump read 0.99 under the same cdb
// load. Re-dump deg_mul per capture at the next retail session.
var walk = new RetailFrameWalk(100f, 0f);
var recorder = new Recorder();
var recorder = new Recorder(world.Cells);
walk.WalkFrame(frame.Pose.CellId, camera, world.Landscape, ctx, recorder);
walk.WalkFrame(pose.CellId, camera, world.Landscape, ctx, recorder);
string expected = WalkTraceReplayContext.Signature(frame);
string actual = WalkTraceReplayContext.Signature(recorder.Events);
@ -191,48 +190,16 @@ public sealed partial class WalkTraceConformanceTests
}
/// <summary>
/// PINNED RED 2026-09-03 (S3 chunk 1 fix round 1, G10 — un-skip with the
/// fix): the eight-kind signature is the FIRST comparison ever run at
/// LC/SC placement/content against a DAT-built world for this fixture
/// (the old four-kind Signature filtered LC/SC out entirely — how the
/// G7 SC-ordering regression shipped green). One real divergence
/// survives after fixing the LandblockId=0 fixture bug this same round
/// uncovered (WalkLandscapeDatBuilder.cs — a genuinely separate,
/// already-fixed defect): at token index 165, the replay draws ONE
/// EXTRA land-cell pair retail never does —
/// <c>…SC:a8c90001|LC:a8c90001|SC:a8c90001|</c> retail jumps straight to
/// <c>LC:95c60001</c>; the replay inserts <c>LC:a9c90001|SC:a9c90001</c>
/// first. A single spurious block admission at a ring-2/ring-3 LOD
/// boundary near this pose — a real <c>WalkLandscape.CheckBlocks</c>
/// visibility question, not a print-site or ordering bug, and out of
/// this round's print-only scope (§11.4) — needs the retail oracle
/// (decomp/cdb) to resolve. Filed as docs/ISSUES.md #458.
/// terrace-edge/cathedral-arrival/foundry-deep all reproduce EXACTLY at
/// this same eight-kind level; only this row's specific pose hits the
/// boundary. S3 chunk 1 fix round 2 (§11.6 H3) switched the ORACLE side
/// of the eight-kind signature from a derived EC/OC to retail's own
/// LITERAL captured EC/OC lines — re-verified 2026-09-03 that this
/// divergence stays at the SAME token index 165 (an LC/SC-only mismatch,
/// upstream of any EC/OC content) under the new comparison; #458's
/// position is unchanged.
///
/// <para>RESOLVED 2026-09-03 (lead, two live cdb captures — see
/// docs/ISSUES.md #458 and register row AD-118): it is a PRECISION
/// BOUNDARY, not a structural walk divergence. At this fixture pose the
/// replay's block test for <c>a9c9</c> (ring 21 north, z slab 75..330)
/// has three of the four block corners OUTSIDE the doorway's fourth
/// edge plane and the south-west corner just INSIDE it, so
/// <c>block_plane_check</c> says PartiallyInside and the block draws;
/// retail's plane sits about 0.5% away (measured at a nearby pose:
/// retail's clip heights 300.4/310.2 m vs the replay's 298.8/308.5 m
/// for the same block, with the SAME sentinel pattern and the SAME
/// verdicts 1 then 0 in the two views) and puts that last corner
/// outside too. The row stays KnownFailure on purpose: the fixture is
/// retail's literal frame, and no bit-exact fix exists short of
/// reproducing D3D's x87 projection.</para>
/// C1c supersedes the former #458 KnownFailure. The literal eight-kind
/// fixture exposed <c>LC/SC:a9c90001</c> only because the replay used
/// <c>Render::copy_view</c>'s inactive legacy-ray branch and paired the
/// events with the stale same-frame marker. Retail's captured
/// <c>newmethod=1</c> matrix path plus the explicit next-marker replay
/// pose reproduces the complete frame exactly. The historical numeric
/// investigation remains in docs/ISSUES.md; it is not a current
/// production divergence or permission to relax this equality.
/// </summary>
[Fact]
[Trait("Status", "KnownFailure")]
public void Oh_doorway_still_first_frame_diff()
{
// S3 chunk 1 (§11.2 B3): the OH kit pose's own doorway-still capture
@ -248,19 +215,19 @@ public sealed partial class WalkTraceConformanceTests
"docs/research/2026-09-01-overhaul/oh-capture", "holtburg-doorway-still.walk");
Assert.NotEmpty(frames);
using DatCollection dats = OpenDats();
WalkOracleFrame frame = frames[1];
Assert.NotNull(frame.Pose);
WalkOracleFrame frame = frames[0];
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkLandscapeDatBuilder.BuiltWorld world =
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
WalkLandscapeDatBuilder.Build(dats, pose.CellId, pose.Origin);
var ctx = new WalkTraceReplayContext(pose, world.Cells)
{
Buildings = world.Buildings,
};
WalkCell camera = Assert.Contains(frame.Pose.CellId, world.Cells);
WalkCell camera = Assert.Contains(pose.CellId, world.Cells);
var walk = new RetailFrameWalk(100f, 0.99f);
var recorder = new Recorder();
var recorder = new Recorder(world.Cells);
walk.WalkFrame(frame.Pose.CellId, camera, world.Landscape, ctx, recorder);
walk.WalkFrame(pose.CellId, camera, world.Landscape, ctx, recorder);
// S3 chunk 1 fix round 1 (G10): the OH kit pose carries LC/SC/EC/OC
// — compare at the full eight-kind level (see Signature8's own doc
@ -272,6 +239,93 @@ public sealed partial class WalkTraceConformanceTests
$"walk diverged from retail\nEXPECTED: {expected}\nACTUAL: {actual}");
}
[Fact]
public void Oh_walk_corpus_reproduces_all_25_complete_frames_at_full_signature8()
{
string[] fixtures =
[
"holtburg-doorway-still.walk",
"terrace-edge.walk",
"cathedral-arrival.walk",
"foundry-deep.walk",
"cathedral-leak.walk",
"cathedral-stair-arch.walk",
"cathedral-stair-arch-e229.combined-r1",
];
using DatCollection dats = OpenDats();
int comparedFrames = 0;
foreach (string fixture in fixtures)
{
IReadOnlyList<WalkOracleFrame> frames =
WalkOracleTrace.Load(OhCaptureRoot, fixture);
Assert.Equal(
fixture == "cathedral-stair-arch-e229.combined-r1" ? 1 : 4,
frames.Count);
WalkOraclePose anchor = Assert.IsType<WalkOraclePose>(frames[0].ReplayPose);
WalkLandscapeDatBuilder.BuiltWorld world =
WalkLandscapeDatBuilder.Build(dats, anchor.CellId, anchor.Origin);
var walk = new RetailFrameWalk(100f, 0.99f);
foreach (WalkOracleFrame frame in frames)
{
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkLandscapeDatBuilder.SetViewer(
world.Landscape, pose.CellId, pose.Origin);
var context = new WalkTraceReplayContext(pose, world.Cells)
{
Buildings = world.Buildings,
};
WalkCell? camera = null;
if ((pose.CellId & 0xFFFFu) >= 0x100u)
{
camera = Assert.Contains(pose.CellId, world.Cells);
}
var recorder = new Recorder(world.Cells);
walk.WalkFrame(
pose.CellId, camera, world.Landscape, context, recorder);
if (fixture == "cathedral-stair-arch.walk")
{
Assert.Equal(4, recorder.Tokens.Count(t => t == "EC:f4180106"));
Assert.Equal(2, recorder.Tokens.Zip(recorder.Tokens.Skip(1))
.Count(pair => pair.First == "EC:f4180106"
&& pair.Second == "EC:f4180106"));
Assert.DoesNotContain("LC:e2290001", recorder.Tokens);
Assert.DoesNotContain("SC:e2290001", recorder.Tokens);
}
string expected = WalkTraceReplayContext.Signature8(frame);
string actual = WalkTraceReplayContext.Signature8(recorder.Tokens);
Assert.True(
expected == actual,
$"{fixture} frame {frame.Number} diverged at token "
+ $"{FirstMismatch(expected, actual)}\n"
+ $"EXPECTED: {expected}\nACTUAL: {actual}");
comparedFrames++;
}
}
Assert.Equal(25, comparedFrames);
}
private static string FirstMismatch(string expected, string actual)
{
string[] expectedTokens = expected.Split('|');
string[] actualTokens = actual.Split('|');
int common = Math.Min(expectedTokens.Length, actualTokens.Length);
int index = 0;
while (index < common && expectedTokens[index] == actualTokens[index])
index++;
string expectedToken = index < expectedTokens.Length
? expectedTokens[index]
: "<end>";
string actualToken = index < actualTokens.Length
? actualTokens[index]
: "<end>";
return $"{index}: expected {expectedToken}, actual {actualToken}";
}
private const string FwOracleRoot = "docs/research/2026-08-30-fw-walk-oracle";
/// <summary>S3 chunk 1 (§11.2 B3): the OH capture directory — its OWN
@ -294,20 +348,20 @@ public sealed partial class WalkTraceConformanceTests
Assert.NotEmpty(frames);
using DatCollection dats = OpenDats();
WalkOracleFrame frame = frames[1];
Assert.NotNull(frame.Pose);
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkLandscapeDatBuilder.BuiltWorld world =
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
WalkLandscapeDatBuilder.Build(dats, pose.CellId, pose.Origin);
var ctx = new WalkTraceReplayContext(pose, world.Cells)
{
Buildings = world.Buildings,
};
WalkCell? camera = (frame.Pose.CellId & 0xFFFFu) >= 0x100
? Assert.Contains(frame.Pose.CellId, world.Cells)
WalkCell? camera = (pose.CellId & 0xFFFFu) >= 0x100
? Assert.Contains(pose.CellId, world.Cells)
: null;
var walk = new RetailFrameWalk(100f, 0.99f);
var recorder = new Recorder();
var recorder = new Recorder(world.Cells);
walk.WalkFrame(frame.Pose.CellId, camera, world.Landscape, ctx, recorder);
walk.WalkFrame(pose.CellId, camera, world.Landscape, ctx, recorder);
// S3 chunk 1 fix round 1 (G10): the OH kit-pose rows carry
// LC/SC/EC/OC — compare THOSE two rows at the full eight-kind level
@ -360,51 +414,39 @@ public sealed partial class WalkTraceConformanceTests
IReadOnlyList<WalkOracleFrame> frames = WalkOracleTrace.Load(fixture);
Assert.True(frames.Count >= 3);
using DatCollection dats = OpenDats();
WalkOraclePose anchor = frames[1].Pose!;
WalkOraclePose anchor = Assert.IsType<WalkOraclePose>(frames[1].ReplayPose);
WalkLandscapeDatBuilder.BuiltWorld world =
WalkLandscapeDatBuilder.Build(dats, anchor.CellId, anchor.Origin);
var walk = new RetailFrameWalk(100f, 0.99f);
for (int n = 1; n < frames.Count - 1; n++)
for (int n = 1; n < frames.Count; n++)
{
WalkOracleFrame frame = frames[n];
if (frame.Number >= stopBeforeFrame) break;
string expected = WalkTraceReplayContext.Signature(frame);
// The marker dumps the PREVIOUS frame's camera, so frame N's
// true camera state lies between pose(N) and pose(N+1) — a
// capture artifact, not a port ambiguity. A frame passes when
// the replay matches under either adjacent pose.
string? firstActual = null;
bool matched = false;
foreach (WalkOraclePose pose in new[] { frames[n + 1].Pose!, frame.Pose! })
// The parser pairs this event frame explicitly with P(N+1),
// including the final raw marker. Never try the stale same-frame
// marker as a fallback.
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkLandscapeDatBuilder.SetViewer(world.Landscape, pose.CellId, pose.Origin);
var ctx = new WalkTraceReplayContext(pose, world.Cells)
{
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 actual = WalkTraceReplayContext.Signature(recorder.Events);
firstActual ??= actual;
if (actual == expected)
{
matched = true;
break;
}
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(world.Cells);
walk.WalkFrame(pose.CellId, camera, world.Landscape, ctx, recorder);
string actual = WalkTraceReplayContext.Signature(recorder.Events);
Assert.True(
matched,
$"frame {frame.Number} diverged under both adjacent poses ({fixture})\n"
+ $"EXPECTED: {expected}\nACTUAL: {firstActual}");
actual == expected,
$"frame {frame.Number} diverged at its explicit next-marker pose ({fixture})\n"
+ $"EXPECTED: {expected}\nACTUAL: {actual}");
}
}
@ -420,13 +462,13 @@ public sealed partial class WalkTraceConformanceTests
foreach (WalkOracleFrame frame in frames)
{
Assert.NotNull(frame.Pose);
WalkCell camera = Assert.Contains(frame.Pose!.CellId, cells);
var ctx = new WalkTraceReplayContext(frame.Pose, cells);
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkCell camera = Assert.Contains(pose.CellId, cells);
var ctx = new WalkTraceReplayContext(pose, cells);
var walk = new RetailFrameWalk(100f, 0.99f);
var recorder = new Recorder();
var recorder = new Recorder(cells);
walk.WalkFrame(frame.Pose.CellId, camera, landscape, ctx, recorder);
walk.WalkFrame(pose.CellId, camera, landscape, ctx, recorder);
Assert.Equal(
WalkTraceReplayContext.Signature(frame),
@ -455,22 +497,22 @@ public sealed partial class WalkTraceConformanceTests
"docs/research/2026-09-01-overhaul/oh-capture", "foundry-deep.walk");
Assert.NotEmpty(frames);
using DatCollection dats = OpenDats();
Assert.NotNull(frames[0].Pose);
WalkOraclePose anchor = Assert.IsType<WalkOraclePose>(frames[0].ReplayPose);
WalkLandscapeDatBuilder.BuiltWorld world = WalkLandscapeDatBuilder.Build(
dats, frames[0].Pose!.CellId, frames[0].Pose!.Origin);
dats, anchor.CellId, anchor.Origin);
foreach (WalkOracleFrame frame in frames)
{
Assert.NotNull(frame.Pose);
WalkCell camera = Assert.Contains(frame.Pose!.CellId, world.Cells);
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
WalkOraclePose pose = Assert.IsType<WalkOraclePose>(frame.ReplayPose);
WalkCell camera = Assert.Contains(pose.CellId, world.Cells);
var ctx = new WalkTraceReplayContext(pose, world.Cells)
{
Buildings = world.Buildings,
};
var walk = new RetailFrameWalk(100f, 0.99f);
var recorder = new Recorder();
var recorder = new Recorder(world.Cells);
walk.WalkFrame(frame.Pose.CellId, camera, world.Landscape, ctx, recorder);
walk.WalkFrame(pose.CellId, camera, world.Landscape, ctx, recorder);
// S3 chunk 1 fix round 1 (G10): full eight-kind comparison —
// see Signature8's own doc comment.

View file

@ -19,28 +19,30 @@ namespace AcDream.App.Tests.Rendering.Walk;
/// </summary>
public sealed class WalkTraceReplayContext : IWalkFrameContext, IRetailFrameWalkContext
{
// Retail projection globals, dumped live from the capture client
// (recon 2026-08-30 evening: Render::bw/bh/xinvscale/yinvscale/tx/ty/vdst).
// The declared capture configuration. The active retail path is
// Render::copy_view @0054dfc0's newmethod=1 arm, which calls
// PrimD3DRender::ScreenToViewTransform @0059aa40 with the actual
// viewport and the inverse WorldToView/ViewToClip matrices. The old
// scalar xinvscale/tx ray is the other branch and is not equivalent:
// it shifts this configuration's center by about half a pixel.
public const float RetailViewportWidth = 1024f;
public const float RetailViewportHeight = 720f;
public const float RetailXInvScale = 0.00025f;
public const float RetailYInvScale = 0.00025f;
public const float RetailTx = 0.127875f;
public const float RetailTy = 0.089875f;
public const float RetailVdst = 0.1330766976f;
private sealed class RetailRayCaster(
Vector3 right, Vector3 forward, Vector3 up) : IWalkRayCaster
private sealed class CapturedD3dRayCaster(
Matrix4x4 inverseWorldToView,
Matrix4x4 viewToClip,
float viewportWidth,
float viewportHeight) : IWalkRayCaster
{
// Retail's unproject (copy_view's ray path; equal to
// ScreenToViewTransform for these globals):
// u = sx·xinvscale tx; w = sy·yinvscale ty
// ray = Xaxis·u + Yaxis·vdst Zaxis·w
public Vector3 RayThrough(float screenX, float screenY)
{
float u = screenX * RetailXInvScale - RetailTx;
float w = screenY * RetailYInvScale - RetailTy;
return right * u + forward * RetailVdst - up * w;
float ndcX = screenX * 2f / viewportWidth - 1f;
float ndcY = 1f - screenY * 2f / viewportHeight;
var view = new Vector3(
ndcX / viewToClip.M11,
ndcY / viewToClip.M22,
1f);
return Vector3.TransformNormal(view, inverseWorldToView);
}
}
@ -73,21 +75,57 @@ public sealed class WalkTraceReplayContext : IWalkFrameContext, IRetailFrameWalk
Vector3 up = Vector3.Transform(Vector3.UnitZ, rotation);
Vector3 right = Vector3.Transform(Vector3.UnitX, rotation);
// The exact retail frustum: tan(halfFovY) = ty/vdst, aspect = tx/ty.
float fovY = 2f * MathF.Atan(RetailTy / RetailVdst);
Matrix4x4 view = Matrix4x4.CreateLookAt(pose.Origin, pose.Origin + forward, up);
Matrix4x4 projection = Matrix4x4.CreatePerspectiveFieldOfView(
fovY, RetailTx / RetailTy, 0.1f, 5000f);
Matrix4x4 view = CreateLeftHandedWorldToView(
pose.Origin, right, up, forward);
Matrix4x4 projection = CapturedViewToClip();
_viewProjection = view * projection;
ViewportWidth = RetailViewportWidth;
ViewportHeight = RetailViewportHeight;
_rays = new RetailRayCaster(right, forward, up);
Assert.True(Matrix4x4.Invert(view, out Matrix4x4 inverseView));
_rays = new CapturedD3dRayCaster(
inverseView,
projection,
ViewportWidth,
ViewportHeight);
// The retail CY near plane: N = forward, d = dot(eye, forward) znear.
CyPlane = new WalkPlane(forward, -Vector3.Dot(pose.Origin, forward) - 0.1f);
}
internal Vector2 ProjectWorldToScreen(Vector3 point)
{
WalkScreenPoint screen = WalkScreenClip.TransformToScreen(
point,
_viewProjection,
ViewportWidth,
ViewportHeight);
return new Vector2(screen.X / screen.W, screen.Y / screen.W);
}
private static Matrix4x4 CreateLeftHandedWorldToView(
Vector3 eye,
Vector3 right,
Vector3 up,
Vector3 forward) => new(
right.X, up.X, forward.X, 0f,
right.Y, up.Y, forward.Y, 0f,
right.Z, up.Z, forward.Z, 0f,
-Vector3.Dot(right, eye),
-Vector3.Dot(up, eye),
-Vector3.Dot(forward, eye),
1f);
internal static Matrix4x4 CapturedViewToClip()
{
static float F(uint bits) => BitConverter.UInt32BitsToSingle(bits);
return new Matrix4x4(
F(0x3F854304), 0f, 0f, 0f,
0f, F(0x3FBD8723), 0f, 0f,
0f, 0f, F(0x3F8000D2), F(0x3F800000),
0f, 0f, F(0xBDCCCE1D), 0f);
}
/// <summary>Building placements (camera-block-local) for the landscape
/// fixtures; empty for the interior-only ones.</summary>
public Dictionary<WalkBuilding, WalkWorldDatAdapter.BuildingEntry> Buildings { get; set; }
@ -297,9 +335,12 @@ public sealed class WalkTraceReplayContext : IWalkFrameContext, IRetailFrameWalk
}
/// <summary><c>PView::DrawCells</c>'s two complete reverse loops: every
/// EnvCell shell far-to-near, THEN every object-list turn far-to-near —
/// the SAME reversed cell order twice (not one reversed EC/OC pair per
/// cell). S3 chunk 1 fix round 2 (§11.6 H3): this is now ONLY the
/// live view's EnvCell entry far-to-near, THEN every cell's object-list
/// turn far-to-near — the SAME reversed cell order twice, with EC
/// repeated by the cell's live <c>TopView.ViewCount</c> and OC once.
/// This reads the borrowed live cells while the flood callback still
/// owns their view stacks, matching @005a4ab1005a4acc and
/// @005a4ade005a4b1a. S3 chunk 1 fix round 2 (§11.6 H3): this is ONLY the
/// REPLAY side's derivation — <see cref="WalkTraceConformanceTests"/>'s
/// <c>Recorder</c> calls this at the exact hook that fires for each
/// flood (a look-in's own <c>DrawCells</c> immediately; the interior
@ -310,10 +351,18 @@ public sealed class WalkTraceReplayContext : IWalkFrameContext, IRetailFrameWalk
/// this — the ORACLE side reads its own captured EC/OC lines literally
/// instead of re-deriving them (see that method's own doc comment for
/// why: a derivation compared to itself proves nothing).</summary>
internal static void AppendFloodTurns(List<string> tokens, IReadOnlyList<uint> cells)
internal static void AppendFloodTurns(
List<string> tokens,
IReadOnlyList<uint> cells,
IReadOnlyDictionary<uint, WalkCell> liveCells)
{
for (int i = cells.Count - 1; i >= 0; i--)
tokens.Add($"EC:{cells[i]:x8}");
{
WalkCell cell = liveCells[cells[i]];
int liveViewCount = cell.NumView > 0 ? cell.TopView.ViewCount : 0;
for (int view = 0; view < liveViewCount; view++)
tokens.Add($"EC:{cells[i]:x8}");
}
for (int i = cells.Count - 1; i >= 0; i--)
tokens.Add($"OC:{cells[i]:x8}");
}