feat(render) Campaign FW3.1: production walk world data behind the seam

The retail frame walk's world model now materializes from production
landblock-build owners through the legal IDatReaderWriter seam, with
zero frame wiring (FW3.2 roots the frame):

- WalkCellFactory: WalkCell built in the SAME pass as LoadedCell
  (EnvCellLandblockBuild.BuildVisibilityCell) from the raw portal
  Flags/polygons/planes/stab lists already parsed there; stored as
  LoadedCell.Walk, committed atomically with the cell. The
  fixture-pinned decodes (inverse-0x2 portal side, 0xFFFF->0xFFFFFFFF
  exit widening) live here.
- WalkBuildingFactory + WalkBuildingRegistry: the production
  WalkBuilding build (drawing BSP with PORT nodes, degrade ladder,
  portal sides/stab lists, sort center, model frame) from the SAME
  LandBlockInfo the streaming build already fetches, under the
  factory's existing DAT lock - closing the gap where BuildingLoader
  drops every walk field at load.
- WalkLandscapeAssembler: the retail 51x51 viewer-centred grid
  (mid_radius 25) fed incrementally from landblock publish/retire;
  per-block z-slab (heightTable[max]+200 / [min]-1) computed
  worker-side in LandblockBuildFactory from the heights already in
  hand. O(1) SetViewer on same-block frames.
- WalkProductionFrameContext: the walk's frame contexts over
  CellVisibility + WalkBuildingRegistry with a generic
  inverse-view-projection ray caster (rays feed cross products only -
  scale-free) and the znear=0.1 CY plane.
- Publication: LandblockRenderPublisher owns both walk registries,
  publishing in the same AdvanceCompleteOne step as BuildingRegistry
  and retiring in RemoveBuildingRegistry - same commit, same
  retirement, no new ticket stage.

Conformance: ALL TEN oracle fixtures replay identically through the
PRODUCTION builders (WalkProductionWorldConformanceTests) - same
signatures as the test adapter, first run. Known gap documented for
FW3.2: far-tier landblocks carry no EnvCell transaction, so their
z-slab never reaches the assembler.

Suites: full Release build 0 warnings; Walk lane 186/1 skip;
hermetic 6,738/0 (+24); RuntimeDatAccessArchitectureTests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-30 13:19:22 +02:00
parent b95850defe
commit b10ad662b0
14 changed files with 1711 additions and 2 deletions

View file

@ -12,6 +12,7 @@
using System.Collections.Generic;
using System.Numerics;
using AcDream.App.Rendering.Walk;
namespace AcDream.App.Rendering;
@ -114,6 +115,21 @@ public sealed class LoadedCell
/// test fixtures use low ids for interior cells, so keying on the id would misfire.
/// </summary>
public bool IsOutdoorNode;
/// <summary>
/// Campaign FW3.1: the retail frame walk's model of this cell (portal
/// side/exact-match decode, portal polygons + planes, stab list,
/// UNLIFTED transform), built atomically alongside this
/// <see cref="LoadedCell"/> by
/// <c>EnvCellLandblockBuildBuilder.BuildVisibilityCell</c> — see
/// <c>WalkCellFactory.FromParsed</c>. Null only for hand-built test
/// fixtures that construct a <see cref="LoadedCell"/> directly instead of
/// through the streaming build. <c>WalkProductionFrameContext.GetVisible</c>
/// is the walk's sole read of this field — the committed registry
/// (<see cref="CellVisibility.TryGetCell"/>) is the walk's only cell
/// source; its dead BFS role is unrelated.
/// </summary>
public WalkCell? Walk { get; internal set; }
}
/// <summary>