The [dyn-route] trace pinned the through-wall remote player (visible
from 0xF4180101 AND outdoors while parented at 0xF4180112 - a cell
with no retail sightline chain from either): the legacy visibility
builder invents cross-building cell views at the cathedral (REAL
3-5-plane cones for 0x112, not the zero-plane trapdoor), the viewcone
admits his sphere, and he rides the last dynamics pass - post-clear on
interior roots (walls'' depth wiped) and post-world outdoors.
The stage-set split (synthesis plan step 4): an interior-parented
dynamic may ride DynamicLast ONLY when its parent cell is in THE
WALK''S OWN ROOT FLOOD (oracle-trace-conformant; retail draws look-in
occupants inside the landscape stage through the composed portal
chain, and unreachable cells'' occupants not at all). The frame
product''s build input gains RootFloodCells (the driver''s
InteriorFloodCells as a per-frame set); non-walk/diagnostic frames and
the comparison wrapper keep the legacy drawableCells meaning. The
[dyn-route] probe logs the new rootflood-excluded state.
Hermetic 6,762/0; InstalledDat walk conformance 40/1.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The owner''s through-wall remote-player report (standing in 0xF4180101,
a player parented at 0xF4180112 - the south hall, geometrically
unseeable through the cathedral - renders through opaque walls; from
0xF4180104 he is correctly hidden). The DynamicLast admission chain
has three gates (indoor / old-apparatus look-in exclusion /
SphereVisibleInCell against old-assembly cell planes), and gate 3
carries a known trapdoor: a zero-plane scissor-fallback slice is
PASS-ALL. This trace logs, per entity ON CHANGE: parent cell, look-in
exclusion hits, the viewcone verdict, and the cell''s lifted-plane
shape, so one 0104<->0101 crossing with the remote player in place
pins the admitting gate. Rain gate 75eab42f is owner-PASSED.
Hermetic 6,762/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The owner''s seam report (rain in the 0xF4180104/0xF4180101 crossing
strip where retail has none) led straight to retail''s actual rain
confinement, which is neither depth nor view clipping:
GameSky::Draw @0x00506ff0 gates its WEATHER pass (arg2==1) on
SmartBox::is_player_outside @0x00451e80 - Ghidra-arbitrated (BN''s
body was flag-idiom mush): (player objcell_id & 0xFFFF) < 0x100. The
sky pass always draws; rain draws ONLY while the PLAYER is in an
outdoor cell. One boolean - rain on the ledges, none the instant the
player crosses into an interior cell. Retail also runs the sky/weather
draw at DEPTHTEST_ALWAYS write-off (pc 0x00507063), confirming our
depth-disabled weather port; the missing piece was only this gate,
now applied at the executor''s weather site from the frame''s
PlayerCellId.
Hermetic 6,762/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports the user-verified #132 invariant (e102fb36 on the old pipeline)
walk-natively, on the owner''s direction: retail''s falls containment
is POSITIONAL - an outdoor emitter''s polys join the ONE alpha list
during its owner cell''s DrawObjCell in the far-to-near landscape walk
(DrawSortCell @0x005a17c0), so every nearer building''s pre-punch
barrier (DrawBuilding @0x0059f2a0''s FlushAlphaList @0x0059f30b)
drains the already-queued FARTHER content against still-true depth
BEFORE its punch stamps far-Z into the aperture. The walk path had
kept the per-building AlphaBarrier events but batched ALL landscape
static-owner submission into one lump at the pre-clear closure - after
every punch had run: the barriers fired over an empty queue and the
falls drained against punched-far aperture pixels (phase=pre in every
probe line, which is why six rounds of phase-staging repairs could
never see it - the phase was right, the position within the phase was
wrong).
New WalkFrameEventKind.StaticParticles: each landscape cell''s and
each building shell''s emitter owners now submit AT THAT TURN during
Replay (marked so the owner''s meshes flush first - retail''s
per-object order); the batched SubmitWalkLandscapeStaticParticles and
its closure/post-replay call sites are deleted for both root kinds.
Two driver sequence pins adjudicated to the new turn order.
Hermetic 6,762/0; InstalledDat walk conformance 40/1.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Implements the synthesis plan''s Phase I (instrument-first, no rendering
edits): the [falls] watch printing EVERY particle submission carrying a
real falls owner (the outdoor landblock emitters 0xCF418000-13 the six
fix rounds never traced) with route + phase; [falls-adm] admission
verdicts for F418 emitters at the retail ShouldDrawParticles port
(owner, cell, distance, in-set, eligibility); the continuous
[walk-root] line now separating the TRUE root flood
(InteriorFloodCells) from the visited union (root + look-ins - the
conflation the review corpus indicted) and printing the walk''s own
exit-view count; [walk-cam] replayable camera dumps; and the restored
[walk-portal] per-portal side/clip decisions. All under the existing
ACDREAM_PROBE_WALK_ROOT flag; the depth-checkpoint readback is
deferred until these answers narrow the question (mid-pass Vulkan
depth reads need render-pass splitting).
Hermetic 6,762/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Files the independent review corpus (fable/opus/external + audit,
DAT-format, F418 DAT-geometry, retail decomp reconstruction) and the
synthesis that adjudicates their disagreements: retail roots INTERIOR
at the posed terrace defect pose with a ONE-CELL flood and ov=1 (the
free captures rooted outdoor - both were real); the falls are outdoor
landblock emitters 0xCF418000-13; the "thin seam bands" claim is
DAT-refuted (full-size exits; the seam is a coincident double
exit-to-outside plane at y=48); clear+seals live inside retail''s ov>0
block with a one-frame seal latch. Carries the instrument-first plan
(falls-owner trace, depth checkpoints, pose conformance) and the
decomp-pinned repair sequence toward FW4''s single-owner goal.
Also sweeps in the probe scaffolding slice 5''s path-limited add had
missed (RenderingDiagnostics field + the launch-options row wording).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reverts 0d6cd5c0 (slice 5) and f3a03efc (slice 4). All three
independent cathedral reviews (fable, opus, external) plus the DAT
geometry ground truth condemned both:
- Slice 5 misidentified its targets: owners 0x4F418012-15 are cell
0xF4180106''s TORCHES + a prop + a plant (InteriorEntityIdAllocator
namespace), not the falls - the real waterfall emitters are outdoor
landblock objects in the 0xC namespace (0xCF418000-13). Moving torch
flames pre-clear is the owner-reported in-cathedral particle
regression.
- Slice 4''s straddle rule is invented (retail stages by actual
shadow-cell membership), and its "emit once" contradicts retail''s
deliberate mid-frame m_nFrameStamp re-arm @0x005a4886 (a part
overlapping both scopes legitimately draws twice).
The synthesis of all seven review reports and the adjudicated fix plan
live in docs/research/2026-08-30-cathedral-synthesis.md (next commit).
Hermetic 6,762/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Five ordering repairs later the cathedral falls still bled, and the
final probe round proved why no ordering fix could ever land it: the
falls now submit pre-clear with depth test LESS - and STILL pass,
because the depth they test against is EMPTY. DrawWalkTerrainSlice
scissored + hardware-clipped the terrain to the walk''s exit-view
polygons, and at the #456 cathedral seam those authored portal polys
are thin BANDS far narrower than the real opening: most of the vista
never received terrain color or depth that frame (the visible scene
there was stale color), so unclipped alpha painted straight across.
Retail''s rule, per the PV campaign''s proven model and LScape::draw:
landscape content is view-CULLED, never view-CLIPPED - terrain blocks
draw whole, once per landscape turn (the views feed only CheckBlocks''
block visibility), and aperture exactness comes from the depth clear +
exit seals + interior repaint that follow in the walk''s own order.
This slice ports that: the driver fans exactly ONE terrain turn
(correcting slice 1''s per-view fan), and an interior root''s terrain
and sky draw unclipped/unscissored; the outdoor root keeps its single
full-screen slice (equivalent by construction). The walk''s views
still own the punch fans and dynamics apertures.
Hermetic 6,762/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cathedral falls'' true identity, pinned by the emitter/owner dumps
and the owner''s retail-vs-ACE oracle (retail renders them perfectly):
they are EnvCell STAB-LIST statics (interior-cell dat objects, ids
minted by InteriorEntityIdAllocator) whose geometry hangs out over the
lake. Our cell-statics route submitted every interior flood cell''s
static particle owners POST-clear ("walls own depth") - true for
content that stays inside, but a straddler''s outside half meets
seal/cleared depth and splats across the vista.
Retail''s mechanism is the outdoor shadow-cell draw: an object
overlapping outdoor landcells draws during LScape::draw (DrawBlock
pc:430056-430064, once per overlapped shadow cell), so its particles
submit in the landscape scope and drain at the pre-clear boundary
flush over true terrain depth; the cell''s own turn skips them
(drawn-once). This slice ports that rule for particles: after Collect,
the interior flood cells'' static records are classified by the shared
exit-plane straddle test (extracted as SphereStraddlesExitPlane from
the #118 dynamic split); straddlers'' owners submit in the pre-clear
closure and the post-replay cell-owners union subtracts them, so every
owner emits exactly once. Also adds the [walk-emit] probe dump that
falsified the unattached-route theory.
Hermetic 6,762/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cathedral falls survived slices 2 and 3; the [walk-dyn] dump then
pinned the real gate: the falls emitters are interior-parented
exit-plane STRADDLERS that pass BOTH the outside-stage predicate and
the viewcone (outside=1 cone=1) - they were in the pre-clear union all
along, and the deliberate ExceptRoute(DynamicLast) stripped them so
they emitted in the post-clear last pass instead ("straddlers emit
HERE"). That placement protects an indoor flame from interior repaint,
but a straddling emitter whose particles hang OUTSIDE the exit portal
has no depth left to occlude them after the clear - they splat across
terrain and water.
Retail submits an emitter''s polys at its object''s FIRST draw - the
landscape stage for anything overlapping outdoor shadow cells - and
drains them at the pre-clear boundary flush over true landscape depth.
Under an interior root the late-union now keeps the outside-stage
owners (straddlers included), records them, and BOTH last-pass arms
subtract the recorded set so every owner emits exactly once. Outdoor
roots keep the old except-at-union placement: both stages drain at the
same final flush there, so the last-pass emission is already correct
and a pre-emission would double-composite.
Hermetic 6,762/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cathedral falls persisted through the slice-2 seal fix; the probe
already held the tell: the same two emitter entities (f4243/f4285) draw
phase=pre on good frames and phase=post on bad ones. They are
interior-parented, so DynamicDrawsInOutsideStage takes the indoor arm,
whose first gate is flood membership - and that still read the OLD
apparatus flood, which drops cells at the #456 seam band. On those
frames the falls fell to the post-clear last pass and splatted across
the cleared depth (terrain and water alike).
Both predicate call sites (the frame product's BuildOutsideDynamicRoutes
via BuildAndBorrow's input, and the renderer's own outside-stage
classification) now receive the walk's VisitedCells on walk frames -
root flood plus look-in floods, all of whose objects retail draws inside
LScape::draw, pre-clear. drawableCells keeps its other roles. Also adds
the probe-gated [walk-dyn] per-entity classification dump (parent cell,
outside/cone verdicts) so a surviving repro pins the failing gate
directly.
Hermetic 6,762/0, Walk lane 213/1.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cathedral falls shine-through (owner report at the #456 terrace
seam, toggling with the camera''s side of the seam): the probe''s new
phase tags pinned the falls emitters to the cell-owners route
submitting POST-depth-clear on interior roots - retail''s own timing,
safe only because seals own the aperture depth by the end-of-frame
alpha drain. Our seal SET still came from the old apparatus''s flood,
which misses exit portals at the #456 seam band (its never-drawn panel
family), so the drain z-passed across the unsealed opening.
DrawWalkExitPortalMasks now stamps the walk''s own ordered interior
flood (WalkFrameDriver.InteriorFloodCells, captured at
OnInteriorFloodDrawTurn - retail PView::DrawCells pc:432785-432786),
keeping the old assembly''s per-cell slice clips where present and
sealing unclipped where the old apparatus had no entry (benign: the
exact dat aperture polygon, z-tested). The legacy path keeps the old
seal draw. Also: ACDREAM_PROBE_WALK_ROOT gains [walk-part]/[walk-alpha]
phase-tagged submission/drain lines (the apparatus that pinned this).
Hermetic 6,762/0, Walk lane 213/1, InstalledDat walk conformance 40/1.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The FW3 visual gate's stairwell/grass transition flash (grass briefly
covering floor openings at doorway crossings - the #119 family) was the
FW3 dual path leaking: the walk decided WHETHER terrain draws while the
old PortalVisibilityBuilder assembly decided WHERE (slice planes, count,
scissor), and punch fans indexed the old slice array with walk view
indices. The new ACDREAM_PROBE_WALK_ROOT apparatus pinned the boundary
frames: fat/degenerate old-apparatus exit views splash terrain over
interior pixels, the interior depth-clear preserves color, and cells
absent from the walk's flood never repaint. Retail has ONE visibility
structure and cannot produce this.
ClipFrameAssembler.ReassembleOutsideViewFromWalk now materializes the
walk's own outside_view (pixel screen points -> standard NDC -> the
existing ClipPlaneSet machinery) into the assembly's outside-view block
after Collect, ahead of the single PrepareClipFrame publication (moved
below the walk block). The Landscape event carries the walk's active
view count on the record's existing OutsideViewCount field (trace
mapping compares kind only - zero oracle-fixture churn) and the driver
fans exactly that many terrain slices; activeTerrainSliceCount is
deleted end to end. Outdoor roots keep the assembler's single
full-screen slice, asserted ==1.
Hermetic 6,762/0 (4 new materializer tests pin the y-flip and
plane-sign conventions), Walk lane 209/1, InstalledDat walk conformance
40/1. Seals/cell slices/look-in seeding stay on the old per-cell views
for the rest of FW4 (identical dat polygons; only the visible set can
differ).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The total-fallback assertion pinned ViewerCellId == 0 - the pre-fix
adaptation. Retail set_viewer copies the whole player Position,
objcell_id included, so the fallback inherits the player cell; the
re-extend-from-the-player property the test exists for is unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner report: floor openings (stairs down) briefly covered by outside
terrain at camera in/out crossings - the historic #119 family
transition arm. Root cause: at a doorway graze the camera collision
sweep can transiently fail; retail total-failure fallback
set_viewer(&player->m_position, 1) (update_viewer @0x00453fad, and the
cell==0 bail @0x00453d1d) copies the WHOLE player Position - objcell_id
included - so retail roots those frames on the player interior cell.
Our fallback left ViewerCellId = 0, which the walk reads as an OUTDOOR
root while the eye is inside: full-screen terrain with the look-in
gates correctly refusing from the interior side - grass over the
stairwell for exactly the failing frames. The fallback now inherits
the pivot/player cell, matching retail byte-for-byte.
Suites: full Release build 0 warnings; hermetic 6,758/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Second owner report at the same gate: candle-flame particles still
invisible looking out. Flame emitters attach to STATIC owners (lamp
and candle statics), and the walk path submitted the landscape-stage
static-owner particle union AFTER the driver replay - post-clear, so
the pre-clear drain never carried them and a later flush z-failed
them at the sealed aperture. For an interior root the submission now
runs at the walk pre-clear boundary (retail inserts each emitter
during its cell landscape walk turn, before the clear+seals);
outdoor roots keep the post-replay frame-end placement (#132).
Interior cells own emitters stay in the final world scope where the
walls already own depth.
Suites: full Release build 0 warnings; hermetic 6,758/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner gate report (Holtburg, looking out from a house): no doors on
buildings, no candle particles, the character vanishing for a frame
when crossing out. One family: the cutover moved the interior depth
clear + exit seals into the walk turn, but the dynamics phase
(outside dynamics, look-in dynamics, outdoor particles, weather)
still ran AFTER the whole walk - everything beyond the door plane
z-failed against the seals stamp, the exact #118 house-exit
clip+vanish class the old code documented.
Retail draws the outside world's objects INSIDE LScape::draw,
strictly before the clear+seals. The driver's clearInteriorDepth
closure now invokes the dynamics phase at that pre-clear boundary for
interior roots (_walkPreClearDynamics, assigned around the Replay,
cleared in finally); outdoor roots keep the post-driver order (no
clear exists there). Packed route consumption order is unchanged
(LookInObject -> LandscapeOutsideDynamic -> DynamicLast).
Suites: full Release build 0 warnings; hermetic 6,758/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The dense-Arwic re-measure crashed with VK_ERROR_DEVICE_LOST: between
ordered ranges the walk leaf draws (terrain, shells, sky, punch fans)
and RetailAlphaQueue flushes rebind the SAME set-0 storage slots to
their own sections, so the bind-once latch made the next range draw
against foreign buffers - out-of-bounds instance reads and a GPU
fault. Sections now re-bind on every DrawOrderedRange call, exactly
like the proven DrawPreparedAlphaBatchRhi; the once-per-frame ring
WRITES in PrepareOrderedStream (the actual measured cost) are
unchanged. The bind-once referee test flips to assert per-range
rebinds with unchanged draw coverage.
Suites: full Release build 0 warnings; hermetic 6,758/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The FW3.4 dense-Arwic pair triggered the +/-20% stop rule (+33.5% CPU
p50, 14x frame allocation). This slice removes the three measured
costs without changing GPU command order (the referee suites assert
identical recorded call sequences):
- WalkFrameDriver: Collect (ONE walk per frame - no GPU work; leaf
calls and flush points become a recorded event list; the driver
absorbed the renderer collection pass and exposes the visited sets)
+ Replay (prepare the whole stream once, then replay events,
interleaving DrawOrderedRange with leaf calls in the exact recorded
order). RunFrame = Collect+Replay for existing callers.
- WbDrawDispatcher: SubmitOrderedStream split into PrepareOrderedStream
(all sections + commands + merge runs uploaded once per frame) and
DrawOrderedRange (bind-once latch; per-run pipeline + DrawIdOffset +
DrawIndirectRangeRhi). Load-bearing correctness catch from the
implementation round: merge runs take FORCED BREAKS at the recorded
event marks - whole-stream merging must not fuse two segments that
retail separates with a leaf GPU call (shell, punch); the straddle
assert stays as a dead-code safety net.
- WalkProductionWorldData: WalkFrameStaticRecords carries an
ArraySegment into a per-frame grow-only arena; the per-cell
fresh-array copies (the 1.9 MB/frame alloc p50) are gone - zero
steady-state allocation after warmup.
Suites (lead-verified): full Release build 0 warnings; hermetic
6,758/0; Walk lane 209/1; InstalledDat Walk conformance 40/1
untouched. Next: the dense-Arwic re-measure against the same-session
baseline.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Retail draws cell geometry at the dat EnvCell origin verbatim; the
0.02 m lift was our z-fight stand-in (register row AP-32, deleted in
this commit). With the walk owning retail draw ORDER under
WorldDepthContract Less (first-drawn-wins: DrawBlock terrain-then-
objects per cell, DrawCells shells-then-contents), the coplanar
tie-breaks the lift compensated for are now resolved the way retail
resolves them.
Deleted at every site: the PortalVisibilityBuilder const + the
drawLiftZ Build parameter and its lifted exit-portal projection branch
(gate and drawn geometry now share ONE space); the seal/punch fan
lifts (DrawPortalDepthWrite + the walk's DrawWalkPunchFan); the
LandblockBuildFactory drawn-cell-transform lift (render and physics
share the one verbatim transform).
The #130 proof flipped exactly as its own doc predicted:
UnliftedGate_LeavesTheStripAtTheDrawnTopEdge is deleted (its premise -
gate space != drawn space - no longer exists), and the renamed
ExitDoorTopEdge_GateCoversTheDrawnApertureWithinPixelTolerance sweep
(147 eye/gaze combos at the Holtburg corner door) passes with both in
the same unlifted space (worst plane gap <= 1.2 px, scissor <= 0.15 px
- unchanged tolerances). Ten more replay-test call sites swept to the
new Build signature.
Suites: full Release build 0 warnings; hermetic 6,750/0; the 21
affected InstalledDat replay tests green; Walk conformance 40/1
untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The owner watched the first passing lifecycle run and reported most
outdoor scenery not rendering (terrain/buildings/interiors fine, no
seams). Root cause: retained-scene record positions are RENDER-ORIGIN-
RELATIVE (each landblock carries (lbX - CenterX)*192 offsets), but the
walk world data bucketed outdoor statics by treating them as absolute -
garbage landblock bytes, so the walk's landscape-cell turns read empty
buckets and trees/rocks/fences never drew. LandscapeCellId now adds the
frame's RenderCenterLbX/Y back to the relative block index, producing
the TRUE cell ids the walk's OnLandscapeCellTurn emits. Buildings and
cell statics were unaffected (id-keyed, not position-bucketed).
The same run confirmed the campaign thesis live: NO SEAMS at the
doorway class under walk order + retail depth, with the lift hack
still present (its retirement is FW3.3).
Suites: hermetic 6,750/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The first connected gate run of the static cutover crashed at
Aerlinthe: WalkProductionWorldData grew its scratch by probing with an
undersized span, but ArchRenderScene validates destination size UP
FRONT and throws (5,040 outdoor statics vs the 1,024-record probe; the
sanctuary shadow run never had enough outdoor statics to trip it).
Presize from the query's own counts instead - IndexCounts.For for the
outdoor sweep, GetCellStaticCount for per-cell copies.
Suites: full Release build 0 warnings; hermetic 6,750/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The retail frame walk now drives every production static draw. In
RetailPViewRenderer.DrawInside, when the concrete executor + the
packed product + the FW3.1 walk registries are all wired (all
production compositions - anything less throws):
- A pre-walk events-only collection pass (the shadow sink generalized
to WalkVisitedSetCollector) gathers the frame's visited cells,
buildings, and landscape-cell turns; the visited cells union into
prepareCells so EnvCellRenderer prepares every shell the driver
draws.
- DrawWalkDrivenStatics runs the WalkFrameDriver over the production
world data (WalkProductionWorldData over RenderSceneQuery + the
building registry): sky, terrain slices, outdoor statics at their
landscape-cell turns, buildings (alpha barrier -> punch/look-in
passes -> shell) in retail order, interior clear+seals as leaf
closures (the old tail block's drain reasoning moves with them),
flood cells shell-then-contents. Landscape/cell-stage particle
owners re-source from the walk's visited sets - retail gates
particles per cell turn (ShouldDrawParticles @0x0050FE60), which
this is; the old sphere filter was the approximation.
- DrawLandscapeDynamicsPhase + DrawBuildingLookInDynamics carry the
dynamics-only remainder (LookInObject now dynamic-classified,
late outside-dynamics + weather, particle unions); DrawDynamicsLast
and the outdoor flush are unchanged.
- The product builder stops emitting LandscapeOutdoorStatic /
LandscapeBuildingShell / CellStatic (methods deleted, dead index
tracking removed); LookInObject loads cells with
includeStatics: false.
The old static path survives ONLY behind !walkActive for the
standalone/diagnostic executor-fake path that keeps 15 retail-ordering
regression tests exercising the barrier/punch/seal machinery; no
production composition can reach it. Its deletion is FW4 scope (the
plan's "deleting the patch apparatus") - recorded in the plan.
Transitional risks recorded in code/report: the two-pass walk cost
(FW3.4 measures), the interior slice-count reconciliation between the
old clip assembly and the walk's own exit-view survival, and the
outdoor merged-flood punch coverage now riding the walk's own
building-BSP punches (retail-faithful per FW1; the owner visual gate
verifies).
Suites (lead-verified): full Release build 0 warnings; hermetic
6,750/0 (baseline minus the three deleted route tests); Walk lane
201/1; InstalledDat Walk conformance 40/1 untouched. The two
IL-branch tests the implementation round reported failing pass in
every lead run - the recurring parallel-load flake pair.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ACDREAM_PROBE_WALK_SHADOW=1 (documented row; throwaway - dies with the
flip commit) runs the PRODUCTION retail frame walk per frame in shadow
over the FW3.1 registries - WalkProductionFrameContext from the live
camera, SetViewer recentring, interior rooting via LoadedCell.Walk -
and prints one [walk-shadow] divergence line per frame whose visited
cell set differs from the old path (main flood + look-ins), plus a
loud PROBE FAULT line on any exception. No draws change. This is the
I5 dual-shadow pattern applied to the FW3 static cutover: it proves
the production walk world data live and quantifies old-vs-walk
divergence before any pixel moves. CellVisibility joins the renderer
plumbing as the walk cell registry.
Suites: full Release build 0 warnings; hermetic 6,753/0;
LaunchOptionsDocumentationTests green (both directions).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
LandblockPresentationPipeline exposes its render publisher;
FrameRootComposition hands the publisher's WalkBuildings/WalkLandscape
registries (FW3.1, published/retired per landblock) into
RetailPViewRenderer via two additive constructor parameters. Nothing
reads them yet - the static cutover flip is the next commit, executing
the plan section FW3.2b-2 design with the carve points now surveyed:
the EARLY per-slice sky/terrain/static loop, the look-in barrier +
DrawBuildingLookIns, the LATE dynamics phase, and the shells/cell-
statics passes.
Suites: full Release build 0 warnings; hermetic 6,753/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Additive, nothing invokes it yet (the cutover flip is step 2):
- WalkProductionLeafRenderer + RetailPViewPassExecutor.WalkLeaf: the
walk driver's leaf turns over the SAME executor renderers the packed
path uses today - DrawWalkSky (the per-slice sky block looped under
one driver turn), DrawWalkTerrainSlice (the terrain block of
DrawLandscapeSlice), per-cell shells via EnvCellRenderer,
DrawWalkPunchFan (PortalDepthMaskRenderer far-Z, +ShellDrawLiftZ
matching today's DrawPortalDepthWrite until FW3.3 retires it), the
alpha barrier via FlushLandscapeAlphaFartherThan, and caller-supplied
clear/seal actions (the renderer owns the pass scope). The cutover
changes ORDER, never leaf mechanics.
- Punch fans now carry the ACTIVE VIEW INDEX end to end (retail pins
building_view = Render::portal_view_num @0x0059f3bf for the whole
two-pass walk; the fan clips by that view's slice planes):
PortalPassSink.ActiveViewIndex -> IWalkEventSink.OnPunchGeometry ->
IWalkFrameLeafRenderer.DrawPunchFan.
- The FW3.2b-2 rooting design is recorded in the plan (dual-compute
split, LookInObject route filtered to dynamics, consumer
re-pointing, gate list).
Suites: full Release build 0 warnings; Walk lane green; hermetic green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The oracle trace order DI|DC|LS is breakpoint-ENTRY order; retail's
actual DRAW order inside PView::DrawCells @0x005a4840 for an interior
root is LScape::draw FIRST (pc:432719, only when exit views survive),
then the depth clear (pc:432731-432732), the exit-portal seals
(pc:432785-432786), THEN the flood's own cells far-to-near. The
driver drew flood cells before the landscape - inverted.
RetailFrameWalk.DrawInside gains the additive
OnInteriorFloodDrawTurn(cells) hook firing after the conditional
landscape turn; the DC EVENT stays at its original point (conformance
untouched - 40/1 InstalledDat green). WalkFrameDriver records the
interior flood at the DC turn and draws it at the new turn:
flush -> ClearInteriorDepth -> flush -> DrawExitSeals -> per-cell
shell-then-contents. Building look-in floods still draw immediately at
their building turn (retail's reentrant DrawCells with no clear/seal).
Two new leaf members map to IWorldPassScope.ClearInteriorDepth and the
seal-fan machinery at FW3.2b-2. Reconciliation note recorded: the
driver clears unconditionally for interior roots while production
stages the clear on OutsideViewSlices>0 - observably equivalent at
ov=0, awaiting a firmer decomp read of the clear's gate.
Suites: full Release build 0 warnings; Walk lane 201/1 skip;
hermetic 6,753/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WalkFrameDriver executes one full static-content frame from the walk's
turns so GPU command-buffer order equals retail's walk order. One rule
does the interleaving: the accumulated OrderedDrawStream flushes
through SubmitOrderedStream immediately before EVERY non-stream draw
(sky, terrain slice, cell shell, punch fan, alpha barrier).
Turn script, all decomp-cited and two of them corrected in review:
- Interior flood: per cell IN FLOOD ORDER, shell first then contents
(PView::DrawCells @0x005a4840: DrawEnvCell @0x005a4abe precedes
DrawObjCellForDummies @0x005a4b0d).
- Landscape: sky once, terrain per active slice, then blocks
far-to-near; per cell the building turn precedes the cell's outdoor
statics (DrawSortCell @0x0059f140).
- Building (DrawBuilding @0x0059f2a0): the BLD probe event stays at
entry, but the ENTIRE body - alpha barrier, portal passes, shell -
sits inside retail's gfxobj[deg_level]!=0 gate @0x0059f2d3, and the
order is FlushAlphaList @0x0059f30b -> the two-pass punch/look-in
walk -> THEN the shell draw @0x0059f345. The driver review caught
both the missing gate and a shell-before-punch inversion; fixed
with the addresses cited.
Walk seam: three additive default-implemented IWalkEventSink hooks
(OnLandscapeCellTurn / OnBuildingTurn / OnBuildingShellTurn /
OnPunchGeometry) - every existing sink and all FW1 conformance
fixtures unchanged. WalkLandBlock gains LandblockId for the cell-id
encoding. Leaf draws go through IWalkFrameLeafRenderer so FW3.2b-2
wires the real renderers and the referee suite runs on fakes +
RecordingGpuDevice.
Flagged for FW3.2b-2/FW4 adjudication (documented in code):
FlushFartherThan(building distance) vs retail flush-all
FlushAlphaList(0f); terrain-before-statics within the landscape turn.
Suites: full Release build 0 warnings; Walk lane 200/1 skip;
InstalledDat Walk conformance 40/1 untouched; hermetic 6,752/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The piece that turns walk-visited static content into draws, with no
production frame wiring (FW3.2b roots the frame):
- TryClassifyBatch: ONE shared per-batch classify core (the #426
untextured gate, #188 opacity promotion, texture resolve, foliage
classification, in the exact original order) extracted from
ClassifyBatches; the classic and packed classifiers now call it -
behavior-identical, proven by the full hermetic + InstalledDat +
Core Wb suites.
- ClassifyEntityForWalk / WalkClassifiedBatch: the per-entity seam
yielding per-batch keys + instance data WITHOUT InstanceGroup
bucketing, plus the per-part selection data (picking stays alive on
the walk path - the survey's unlisted-consumer fix).
- WalkStaticStreamPopulator: per-entity walk-ordered opaque appends
(under depth Less, opaque order is pixel-relevant only for coplanar
surfaces, which retail resolves first-drawn-wins in ITS order -
never material-grouped), translucent instances to the SAME
RetailAlphaQueue via SubmitWalkAlphaInstance (identical viewer
distances; walk-order submission improves retail's tie fidelity),
selection parts published per entity.
- SubmitOrderedStream now owns _orderedDrawCullModes, retiring the
FW2-recorded alpha-scope interleaving constraint;
DrawIndirectRangeRhi takes an optional cull array (all existing
call sites unchanged). The referee test was verified to FAIL
against the old shared-scratch behavior.
- WalkDrawStage.OutdoorStatic added for the landscape turn.
Suites: full Release build 0 warnings; Walk lane 195/1 skip;
hermetic 6,747/0 (the two failures the implementation round reported
were transient - both pass in isolation and in the full run).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
FW2 gate adjudication recorded (RecordingGpuDevice referees are the
automated gate; the pixel A/B rides FW3's cutover toggle). FW3 sliced
from the verified surface survey: FW3.1 production walk world data
(the Building record drops every walk field today - the biggest gap),
FW3.2 walk-driven static routes (stop EMITTING the three static routes;
ClipFrameAssembler/ViewconeCuller survive for the dynamic routes;
walk-path selection publication - picking is an unlisted consumer of
the static draw path), FW3.3 ShellDrawLiftZ retirement (THREE sites -
AP-32 lists only two), FW3.4 perf checkpoint with the baseline
correction (519.7 fps is the Aerlinthe ordinary profile, not dense
Arwic - capture a fresh pre-cutover dense-Arwic pair first).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The walk-order submission layer over the existing RHI (plan section FW2):
- OrderedDrawStream: append-only walk-ordered draw commands
(GroupKey + transform + per-instance data + WalkDrawStage + cell
provenance), struct-of-arrays with one lockstep Reset (#193 shape).
The PortalPunch stage exists but has no FW2 submission path - the
submitter throws on it; punch emission lands with FW3 wiring.
- WbDrawDispatcher.OrderedStream partial: per-instance-first emission
(the deferred-alpha shape - command i owns instance i, walk order
survives into the indirect array), each SSBO section written once,
then one DrawIndirectRangeRhi call per maximal merge run. Runs are
built by pure-CPU BuildOrderedMergeRuns and may never span a stage,
pipeline-bucket, or cull boundary; ValidateMergeRun re-checks every
emitted run and throws (the campaign fail-loud rule). Nothing is
sorted, reordered, or dropped: N commands in, N indirect commands
out, covered exactly once.
- WorldDepthContract: retail world depth verified verbatim from the
decomp - Render::zfuncVal @0x00820e1c = 0x2, SetDepthBufferMode
@0x005a2d10 writes the enum directly as D3DRS_ZFUNC so the value IS
D3DCMP_LESS, applied by the surface-state applier @0x0059c80a with
Z-write toggled by blend; the LESSEQUAL sites are GameSky::Draw-local.
Seven world pipeline sites now cite the named constant (no value
changes).
- Plan updated: FW1 status block + gate amendment (the ten pose-stamped
retail traces supersede re-expressing the old-builder replay
fixtures; those retire with the old builder at FW4 and their
scenario classes re-verify at the FW3/FW4 connected gates).
Known FW2 scope notes recorded in the code: the building-detail
overlay replay is production wiring (FW3); the _drawCullModes scratch
may not interleave with a mid-flight RetailAlphaQueue scope (FW3
sequencing constraint). The pixel A/B equivalence proof rides FW3's
cutover toggle where a walk-driven scene first exists.
Suites: full Release build 0 warnings; Walk lane 154/1 skip;
hermetic 6,714/0 (+27 new).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Render::deg_mul is auto-tuned by frame load and SWUNG between oracle
captures: doorway-still ran right after the heavy terrace-edge capture
with the multiplier depressed (mul <= 0 puts thresholds at/below ideal,
so 001e/0026/002f select the portless level 1 - retail's zero look-in
floods, reproduced exactly at mul = 0), while every other fixture pins
~ +0.99 (thresholds at max). The recon session's "-0.99" live dump was
real - taken under the same cdb load. RetailFrameWalk now exposes the
multiplier; the doorway test pins 0, the rest use the default.
foundry-entry: frames 1-66 reproduce exactly; the F67-F79 standing
segment diverges ONLY in building 0036's intra-building DC order
(retail 116,118,11d vs replay 11d,116,118). The BSP-traversal microscope
pins the flip to 0036's ROOT plane (N=(0,0,-1) D=2.8): replay eye z
2.33 (d=+0.47, NEG-first) vs retail behaving as d<0 (POS-first) - a
structural ~0.5 m frame question (positionPush(2)/part-scale), only
adjudicable live. Turnkey probe:
tools/walk-oracle/fw1-f67-viewpoint-probe.cdb.
Fixture status: nine of ten fully conformant; foundry-entry exact
through F66 with the 13-frame order segment parked on the probe.
Suites: Walk 127/1 skip; hermetic 6,687/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The moving-fixture divergence was the building degrade ladder:
GfxObjDegradeInfo::get_degrade @0x0051e4b0 (Ghidra-verified - BN's
FPU-flag pseudo-C misread BOTH arm selection and one formula) slides
each level's threshold from ideal toward MAX as the multiplier
approaches 1, and the live client runs the positive arm at ~0.99, so
level 0's portal-bearing BSP survives to ~max_dist (48 for the Holtburg
cottages), not ideal (24). The recon note's "deg_mul = -0.99" was a
sign misread; the negative arm's threshold slides toward MIN and
contradicts the fixtures from both directions. With the two-arm port,
holtburg-walkout, holtburg-transitions, and holtburg-walkabout pass
every pairable frame - the walkout-F2 microscope's prediction
(103,100 | 100x3 | 124 through the cottage exit views) landed exactly.
Also this round, falsified and reverted: a BN-driven swap of the
portal walker's negative/in-plane arms (Ghidra shows side 1 = negative
EMITS, side 2 = in-plane does not - the original port was correct; the
swap broke four fixtures). The walker docs and unit tests now pin the
Ghidra-verified truth table.
Parked with findings: foundry-entry F67 (right flood set, one
plane-side classification at the +/-eps boundary orders 11d before
116/118) and doorway-still (retail shows zero floods at a pose one
meter from walkout-F2's flooding pose; multi-portal clip boundary).
Suites: Walk 124/3 skips; hermetic 6,687/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The moving driver gains adjacent-pose tolerance (the marker-lag capture
artifact) and stays parked: the four moving fixtures diverge at
punch-edge frames under BOTH adjacent poses. FALSIFIED this round and
reverted: the raw-decode + flipped-gates convention (it broke three
still fixtures - the inverted-decode convention stands, six still
fixtures frame-exact). Remaining instruments in the Skip note: znear,
per-view punch ordering inside DrawMesh, exit-view precision.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Three pinned corrections close the outdoor frame: (1) the camera basis
RE-pinned to +Y-forward - the terrace-edge fixture EXTERNAL ground
truth (the ledge faces the F518 vista, east) overrules the walkabout
motion sweep, whose camera was mouse-turned off the run line; (2)
alwaysDrawObjects (.data default 1 @0x00820ed4) drawn into the
DrawSortCell gate - cell contents draw for every cell of an in-view
block; (3) the building portal side decode data-pinned as the INVERSE
of the cell 0x2 bit (the sweep winning arm). Street result: all 13
buildings in retail exact order (a9b3003c in, aab50002 correctly
absent), punches at exactly 001a and 0022 opening the exact first
cells 16e/164. SOLE remaining delta: look-in flood depth (mine 1 cell,
retail 3-4) - the doorway-still fixture adjudicates the interior flood
in isolation next.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per-portal dump for the street fixture (archived beside the fixtures):
retail punched exactly the buildings whose portal polygons MY camera
model clips to NOTHING (001a/0022: clipN=0, doorways ~75 deg off my
north-facing axis) and skipped the ones mine puts on-screen (001e/0026:
clipN=4-6) - a clean inversion isolating the final look-in delta to
either the camera FACING decode (re-check the terrace-edge fixture
against its known vista direction; the motion sweep's 20-degree
residual is now suspect) or a portal-pass clip mechanism that does not
gate on the active view (cdb ConstructView(CBldPortal) trace next
retail session). All layers above are retail-pinned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
UpdateViewerDistance @0x0050e030 + get_degrade @0x0051e4b0 ported with
live-pinned globals: distance measured to the part SCALED SORT CENTER,
effective = max(0, dist - s_rDegradeDistance [live 100]), level = first
with effective < IdealDist (the live auto_update_deg_mul<=0 arm), else
the last level. WalkBuildingDegradeLevel carries the full authored
bands; the adapter fills sort centers; the replay context measures to
the transformed sort center. Sweep state after the rule: the level-0
building set is now correct; the residual divergence is the per-portal
side/clip gate (my arms punch a near-complement of retail two) - the
sweep driver carries the next instrument in its Skip note.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The offline degrade probe proved the mechanism: every Holtburg building
carries PORT nodes ONLY in its level-0 GfxObj (out to ~24-48 m); every
degraded level has zero. Retail walks the CURRENT degrade level BSP
(part->gfxobj[deg_level]) - that is what limits look-in punches to the
nearest buildings. WalkBuilding gains the degrade ladder +
SelectDrawingBsp (band pick; UpdateViewerDistance hysteresis is a port
TODO), the walk selects per viewer distance, the adapter builds
per-level BSPs, and the stab-list load rule (CLandBlock::init_buildings
@0052fd80: a full-res block loads exactly its buildings portal stab
cells) replaces load-everything in the landscape builder. The sweep now
shows clean rosters with all far-building punches gone; remaining
deltas: the near buildings 001a/0022 (50 m/28 m center distance vs the
48 m band edge - sphere-adjusted distance/hysteresis to port) and the
one ring-1 frustum boundary pair (aab50002/a9b3003c).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The per-building join diagnostic PASSES (001a/0022 portal tables lead
exactly to the traced a9b4016x punch cells; every BSP PortalRef indexes
validly), and the eight-arm gate-decode sweep proves NO plane-sign x
side-flag combination reproduces retail. Together they pin the missing
mechanism: CEnvCell::GetVisible gates punches by the LOADED interior
cell set around the player - retail punched only the two buildings
nearest the player cell; the replay loads every interior so geometry
alone over-punches. Next port piece: the interior load radius (the
landcell stab-list pull). Both diagnostics stay in the suite (the sweep
Skip-parked with the verdict).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The moving-fixture sweep pinned the pose decode (quat storage w,x,y,z;
facing = rotated +X; the consistent triple right=-rot(Y), fwd=rot(X),
up=rot(Z) - mean 20.8 deg vs motion, alternatives >=52). With it the
street-outdoor BLD roster and order match retail EXACTLY except one
ring-1 boundary pair (aab50002 extra / a9b3003c missing). Look-in
punches fire at the wrong buildings under BOTH GfxObj plane-winding
conventions (retail punched only 001a and 0022 into the a9b4016x
cells) - the next adjudication targets the PortalRef.PortalIndex join
and the BuildingPortal side-flag decode via a per-building dump. The
driving diff test carries the state in its Skip note; the flip toggle
stays for the next arm.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WalkLandscapeDatBuilder assembles the replay grid with the LIVE-dumped
retail landscape model (LScape mid_radius=25 -> 51x51; the resolution
pyramid observed on the capture client: side_cell_count 8 in the 3x3
core, 4 at ring 2, 2 at rings 3-4, 1 beyond; buildings attach only to
full-res blocks - matching the traces roster), retail z-slabs
(heightTable[max]+200 / [min]-1 per CLandBlock unpack @0052f297), and
camera-block-local coordinates. The replay context gains the building
half (placements, active-view install, building-polygon clip). The
street-outdoor conformance diff now reaches real adjudication: the walk
over-culls six traced buildings (jagged boundary - not a clean frustum
edge) and the look-in floods differ; the driving test is parked Skip
while the visibility map is instrumented.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Live-dumped from the capture client (Render::bw/bh 1024x720,
xinvscale/yinvscale 0.00025, tx 0.127875, ty 0.089875, vdst 0.1330767):
the replay context now uses retail unproject formula verbatim for the
ray caster and the exact frustum (fovY = 2*atan(ty/vdst), aspect =
tx/ty) for projection - no guessed camera constants remain.
foundry-deep conformance stays green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>