using AcDream.App.Rendering.Walk; namespace AcDream.App.Tests.Rendering.Walk; /// /// S3 chunk 3 (§9.3 T1): + /// + /// reproduce frame /// 2's LC and SC sequences of BOTH OH cathedral captures /// exactly — order, block membership, and per-block LOD side all pinned in /// one pass, at the depth the two owner-verified transcripts (S3 §9.1 R2) /// recorded them. /// /// Viewer: block f4/18, sq cell (1, 1) (the frame-2 `P` /// line: x 36.6, y 24.0 — floor(36.6/24)=1, floor(24.0/24)=1). /// Grid radius (25) — the /// captured blocks span Chebyshev ring 24 (§9.1 R2 fact i), comfortably /// inside it. Only the SET of blocks/cells the transcript itself visited is /// placed on the grid (a real 51×51 window's un-streamed slots stay null /// exactly the same way in production — /// skips a null/Outside slot regardless of why it's empty); each block's /// is set DIRECTLY from the /// transcript's own LC membership (this test is an ORDER pin, not a second /// visibility-math proof — that is WalkVisibilityMathTests's /// job) so is the ONLY production /// order machinery under test. /// public sealed class WalkLandCellOrderTests { private const int ViewerBlockX = 0xf4; private const int ViewerBlockY = 0x18; private const int ViewerSqX = 1; private const int ViewerSqY = 1; [Theory] [InlineData("cathedral-arrival")] [InlineData("cathedral-leak")] public void Frame2_ProducedLandCellSequence_MatchesTheCapturedRetailOrderExactly( string fixtureName) { IReadOnlyList frames = WalkOracleTrace.Load( "docs/research/2026-09-01-overhaul/oh-capture", fixtureName + ".walk"); WalkOracleFrame frame2 = Assert.Single(frames, f => f.Number == 2); List landCellEvents = frame2.Events .Where(e => e.Kind is WalkOracleEventKind.LandCell or WalkOracleEventKind.SortCell) .ToList(); Assert.NotEmpty(landCellEvents); // Extract the block visit order (first-appearance order = retail's // OWN far-to-near block sequence) and, per block, its side (from // the observed SC cell count — every SC-visited block emits // side² SC turns under AlwaysDrawObjects, R1) and its LC membership. var blockOrder = new List(); var blockSeen = new HashSet(); var sideByBlock = new Dictionary(); var scCountByBlock = new Dictionary(); var lcMembersByBlock = new Dictionary>(); foreach (WalkOracleEvent e in landCellEvents) { uint cellId = e.CellId!.Value; uint blockPrefix = cellId & 0xFFFF0000u; uint lodId = cellId & 0xFFFFu; if (blockSeen.Add(blockPrefix)) { blockOrder.Add(blockPrefix); lcMembersByBlock[blockPrefix] = new HashSet(); } if (e.Kind == WalkOracleEventKind.SortCell) { scCountByBlock[blockPrefix] = scCountByBlock.GetValueOrDefault(blockPrefix) + 1; } else { lcMembersByBlock[blockPrefix].Add(lodId); } } foreach ((uint blockPrefix, int scCount) in scCountByBlock) { int side = (int)Math.Round(Math.Sqrt(scCount)); Assert.Equal(scCount, side * side); sideByBlock[blockPrefix] = side; // Cross-check against the LOD-by-ring pyramid the ownership // map's R2 names explicitly (ring 0-1 -> 8, ring 2 -> 4, ring // 3-4 -> 2, ring >= 5 -> 1) — an independent confirmation that // the transcript's own per-block cell count matches production's // ring rule, not just an internally-consistent side count. int bx = (int)(blockPrefix >> 24) & 0xFF; int by = (int)(blockPrefix >> 16) & 0xFF; int ring = Math.Max(Math.Abs(bx - ViewerBlockX), Math.Abs(by - ViewerBlockY)); Assert.Equal(WalkLandscapeAssembler.SideCellCountForRing(ring), side); } // Build the synthetic grid: only the transcript-visited blocks are // populated (production leaves everything else null too), each at // its REAL grid offset from the viewer block, with the REAL side // WalkLandscapeAssembler.SideCellCountForRing computed above. const int midWidth = WalkLandscapeAssembler.GridWidth; const int midRadius = WalkLandscapeAssembler.MidRadius; var landscape = new WalkLandscape { MidWidth = midWidth, Blocks = new WalkLandBlock?[midWidth * midWidth], ViewerBlockX = midRadius, ViewerBlockY = midRadius, ViewerCellX = ViewerSqX, ViewerCellY = ViewerSqY, }; foreach (uint blockPrefix in blockOrder) { int bx = (int)(blockPrefix >> 24) & 0xFF; int by = (int)(blockPrefix >> 16) & 0xFF; int gridX = bx - ViewerBlockX + midRadius; int gridY = by - ViewerBlockY + midRadius; Assert.InRange(gridX, 0, midWidth - 1); Assert.InRange(gridY, 0, midWidth - 1); int side = sideByBlock[blockPrefix]; var block = new WalkLandBlock { LandblockId = blockPrefix, SideCellCount = side, MaxZ = 0f, MinZ = 0f, }; block.EnsureCellArrays(); HashSet lcMembers = lcMembersByBlock[blockPrefix]; for (int cellIndex = 0; cellIndex < side * side; cellIndex++) { int coarseX = cellIndex / side; int coarseY = cellIndex % side; uint retailLodId = (uint)(coarseX * 8 + coarseY + 1); block.CellInView[cellIndex] = lcMembers.Contains(retailLodId) ? WalkBoundingType.EntirelyInside : WalkBoundingType.Outside; } block.InView = WalkBoundingType.PartiallyInside; // admitted; never Outside landscape.Blocks[gridX * midWidth + gridY] = block; } // LandWalkOrder.GetBlockOrder + FillCellOrderFarToNear (the ONLY // production order machinery under test — CheckBlocks is // deliberately not called; CellInView above is authoritative). landscape.CalcDrawOrder(); var producedLc = new List(); var producedSc = new List(); for (int i = landscape.BlockDrawCount - 1; i >= 0; i--) { WalkLandBlock? block = landscape.Blocks[landscape.BlockDrawList[i]]; if (block is null) continue; int cellCount = block.SideCellCount * block.SideCellCount; for (int k = 0; k < cellCount; k++) { int cellIndex = block.DrawArray[k]; int coarseX = cellIndex / block.SideCellCount; int coarseY = cellIndex % block.SideCellCount; uint fullId = block.LandblockId | (uint)(coarseX * 8 + coarseY + 1); if (block.CellInView[cellIndex] != WalkBoundingType.Outside) producedLc.Add(fullId); producedSc.Add(fullId); // AlwaysDrawObjects: every cell of an admitted block. } } List expectedLc = landCellEvents .Where(e => e.Kind == WalkOracleEventKind.LandCell) .Select(e => e.CellId!.Value) .ToList(); List expectedSc = landCellEvents .Where(e => e.Kind == WalkOracleEventKind.SortCell) .Select(e => e.CellId!.Value) .ToList(); Assert.Equal(expectedSc, producedSc); Assert.Equal(expectedLc, producedLc); } }