From fba07e7712d0075a471c7b1885400ea6989d038e Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 1 Sep 2026 18:05:40 +0200 Subject: [PATCH] docs(render): establish Campaign OVERHAUL baseline --- .../2026-08-30-campaign-fw-frame-walk.md | 21 +- ...-09-01-campaign-overhaul-world-solidity.md | 1576 +++++++++++++++++ .../2026-09-01-overhaul/oh0-baseline.md | 362 ++++ 3 files changed, 1953 insertions(+), 6 deletions(-) create mode 100644 docs/plans/2026-09-01-campaign-overhaul-world-solidity.md create mode 100644 docs/research/2026-09-01-overhaul/oh0-baseline.md diff --git a/docs/plans/2026-08-30-campaign-fw-frame-walk.md b/docs/plans/2026-08-30-campaign-fw-frame-walk.md index 4df1e6a8..63917ae3 100644 --- a/docs/plans/2026-08-30-campaign-fw-frame-walk.md +++ b/docs/plans/2026-08-30-campaign-fw-frame-walk.md @@ -1,6 +1,10 @@ # Campaign FW — the retail frame walk (implementation plan) **Status:** ACTIVE (opened 2026-08-30; spec approved by owner 2026-08-30). +**Successor execution ledger (owner-requested 2026-09-01):** +[`docs/plans/2026-09-01-campaign-overhaul-world-solidity.md`](2026-09-01-campaign-overhaul-world-solidity.md). +Campaign OVERHAUL preserves FW as evidence/history but owns all further +world-construction and render-solidity implementation work. **Spec (approved):** [`docs/superpowers/specs/2026-08-30-campaign-w-retail-frame-walk-design.md`](../superpowers/specs/2026-08-30-campaign-w-retail-frame-walk-design.md) — note: the campaign letter is **FW** (frame walk); the spec predates the @@ -452,12 +456,17 @@ Post-refactor dense Arwic uncapped vs the SAME baseline: CPU p50 is now FASTER than the old static path. The refactor's own crash round (VK_ERROR_DEVICE_LOST) taught the binding contract: leaf draws and alpha flushes rebind set-0 between ranges, so DrawOrderedRange -rebinds per call; only the ring WRITES are once-per-frame. FOLLOW-UP -FILED: alloc p50 still ~1.5 MB/frame on the walk path (baseline -133 KB) - the per-frame driver/leaf/populator object graph in -DrawWalkDrivenStatics; hoist to renderer fields with per-frame -Reset (FW3.4 closeout or FW6 polish; CPU-neutral today, GC-hitch -hygiene). +rebinds per call; only the ring WRITES are once-per-frame. +**FW6 ALLOCATION CLOSEOUT (`b8befded`).** The ~1.5 MiB/frame follow-up is +closed: `RetailPViewRenderer` now owns one retained `WalkFrameDriver`, +`WalkProductionFrameContext`, and `WalkProductionLeafRenderer`; `RebindFrame`/ +`Reset` replace per-frame reconstruction, and abort/reset paths preserve the +terminal ledger. The exact-binary nine-stop closeout route reports steady +allocation p50 between 138.6 and 204.5 KiB/frame across its stops (the old +dense-town tail was ~1,500 KiB/frame; the pre-walk baseline was 133 KiB/frame). +The connected route is not the original dense-Arwic perf vehicle, so this is +mechanism + bounded-live evidence rather than a fabricated same-scene A/B; the +campaign's CPU stop rule was already cleared by the exact dense-Arwic pair. - **FW3.4 — perf checkpoint + gates.** BASELINE CORRECTION: the 519.7 fps / 1.869 / 1.096 ms numbers are the Aerlinthe diff --git a/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md b/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md new file mode 100644 index 00000000..a737e512 --- /dev/null +++ b/docs/plans/2026-09-01-campaign-overhaul-world-solidity.md @@ -0,0 +1,1576 @@ +# Campaign OVERHAUL — retail world construction and render solidity + +**Status:** READY TO EXECUTE (plan requested by owner 2026-09-01; +implementation has not started). + +**Campaign code:** `OH`. + +**Worktree (binding):** +`C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0` + +**Branch (binding):** `claude/campaign-w-retail-frame-walk`. + +**Plan-start HEAD:** `e8808602` (`fix(render): restore landscape objects and +walk alpha order`), 27 commits ahead of the remote when this plan was written. + +**Known accepted historical anchor:** `b8befded` (`checkpoint: preserve +user-gated FW closeout fixes`). This is a rollback reference, not permission to +discard the work after it. + +**Dirty-tree rule:** the worktree already contains a large, valuable set of +uncommitted rendering, geometry, physics-shadow, lighting, diagnostics, test, +and prepared-package changes. Nothing may reset, overwrite, clean, stash-pop, +or wholesale replace that state. OH0 must classify and preserve it before the +first behavioral edit. + +**Predecessor evidence:** Campaign FW and the cathedral review corpus remain +authoritative evidence, but Campaign OVERHAUL supersedes FW as the execution +ledger for world-construction and world-render solidity work. + +**One-sentence goal:** recreate retail's single coherent world-cell graph and +its exact per-frame world walk up to a narrow Vulkan translation boundary, so +walls, terrain, buildings, objects, particles, transparency, and portal +transitions remain stable at every camera position without scene-specific +suppression, guessed tolerances, or corrective overdraw. + +--- + +## 1. Why this campaign exists + +Campaign FW successfully replaced the legacy production visibility product +with a retail-derived frame walk, fixed the original cathedral through-wall +actor defect, restored outdoor particles, and corrected several object and +terrain lifetime regressions. It did **not** make the complete world pipeline +retail-identical. + +The current client still reconstructs relationships that retail owns directly: + +- prepared cell meshes are separate from portal topology; +- building shells are separate from building portal ownership; +- render projections are separate from physics `CELLARRAY` membership; +- static visual membership is rebuilt from visual bounds; +- terrain is submitted as a complete slice before per-cell object turns; +- alpha uses a modern scope-global queue rather than retail's exact cell/list + ownership; +- the interior depth clear is emitted unconditionally even though the retail + decomp establishes an outside-view block and a previous-frame + `portalsDrawnCount` latch; +- CellStruct face selection still uses the registered AP-234 `NoPos` proxy + rather than the surface-type decision retail actually makes; +- some accepted object parts are duplicated through Vulkan clip slots, a + translation whose exact correspondence to the built-mesh retail leaf has not + been proved for every content category. + +These differences explain why local fixes oscillate between opposite failure +modes: prevent one leak and walls disappear; restore a wall and a portal-view +artifact returns; cull one cell and a valid stair or ramp vanishes. The campaign +therefore changes the unit of work from "fix this visible triangle" to "port +and prove this retail-owned world invariant." + +--- + +## 2. Definition of success + +Campaign OVERHAUL is complete only when all of the following are true. + +1. One authoritative, generation-scoped cell graph supplies portal topology, + building ownership, drawable CellStruct identity, and render/physics + cross-cell part membership. No production consumer rebuilds a competing + answer. +2. CellStruct mesh extraction selects sides and subsets from the same authored + data retail uses, including exact surface-type handling. AP-234 is retired. +3. The per-frame transcript matches retail for the same root and camera pose: + landscape visits, portal views, building calls, cell order, object-list + turns, frame-stamp boundaries, depth events, and alpha flushes. +4. Every leaf category has a proven retail contract: EnvCell shell, building + shell, landblock static, indoor static, dynamic object, particle, terrain, + punch, seal, and transparent subset. +5. Vulkan receives an ordered list of already-decided retail draw operations. + Vulkan may encode and batch adjacent compatible work, but it does not decide + visibility, ownership, ordering, clipping, or depth-phase membership. +6. Scene-specific suppression, shell lifts, bias values, fallback floods, + corrective redraws, and behavior-changing diagnostic flags do not remain in + production. +7. The owner acceptance matrix passes in the cathedral, Facility Hub, Nanto, + Tusker Island, Holtburg, ordinary dungeons, and ordinary outdoor terrain. +8. The complete Release suite, installed-DAT conformance lane, connected + lifecycle route, R6 route, and performance checkpoint pass on the exact + owner-gated binary. +9. Architecture, inventory, divergence register, launch options, campaign + memory, and milestone ledgers describe the code that actually ships. No + document may claim a conditional clear while production emits an + unconditional one, or claim exact cell extraction while AP-234 remains. + +"Looks fixed at one camera angle" is never a completion condition. + +--- + +## 3. Scope and non-goals + +### In scope + +- CellStruct/EnvCell render-geometry construction. +- The canonical cell/building/portal/part-membership graph. +- Static and dynamic cross-cell render membership. +- Retail `PView` portal-view ownership and draw-leaf contracts. +- Landscape, building, cell-shell, object, particle, depth, and alpha ordering. +- Portal punch and exit-seal lifecycle/state. +- Retail landscape `in_view` production and its particle/light/shadow + consumers. +- Material behavior necessary for solid world composition, including the + transparent-detail AP-232 residual. +- Exact instrumentation and retail/acdream transcript comparison. +- Deletion of the superseded reconstruction and diagnostic apparatus. +- Documentation and regression coverage for the finished pipeline. + +### Explicitly out of scope + +- Replacing Vulkan with retail's graphics API. +- Recreating C++ pointer layouts, allocator behavior, or COM objects. +- Changing the asynchronous streaming strategy, publication budgets, reveal + radii, prepared-package mmap model, or GPU resource lifetime—except for a + schema/version migration strictly required by exact prepared geometry. +- Increasing draw distance or hiding defects with additional residency. +- A general lighting redesign. Lighting must remain stable through the + overhaul; independent lighting findings enter only if they prove a + world-ownership or draw-order dependency. +- Physics behavior not required to produce exact cell/part membership. +- New graphics features, visual enhancements, or non-retail occlusion systems. +- Removing the user-requested Extended particle-range option. The Retail + option must be exact; a deliberate user-selected range multiplier remains a + documented preference rather than being confused with visibility parity. + +--- + +## 4. Binding engineering rules + +1. **Retail makes every world decision.** Modern code may represent a result + differently, but may not invent an additional visibility, membership, + ordering, clipping, or depth decision. +2. **Evidence before code.** Every behavioral slice begins with a written + retail contract containing named functions, addresses, inputs, state writes, + branch senses, call order, and observable output. No implementation starts + from a screenshot theory. +3. **Named retail first.** Search + `docs/research/named-retail/acclient_2013_pseudo_c.txt` and `acclient.h` + before fresh decompilation. +4. **Ghidra arbitrates branch sense.** Binary Ninja pseudo-C is a navigation + aid. Any condition whose polarity affects admission, clipping, depth, + ordering, or lifetime must be cross-checked in Ghidra before implementation. +5. **DAT identity is exact.** Aggregate owner IDs do not identify rendered + content. A trace must reach landblock/static/server owner → Setup → part → + GfxObj → polygon/surface before assigning a visual carrier. +6. **No symptom-site fixes.** A cell ID, building ID, GfxObj ID, camera pose, + cathedral-only branch, extra shell draw, or suppression flag may be used for + diagnosis only. It cannot ship as behavior. +7. **No silent drop.** During a slice, every rejected cell/view/part/mesh must + have a diagnostic reason available. Production diagnostics are removed or + made strictly print-only at slice close. +8. **No competing production owner.** A cutover slice deletes the route it + replaces. A temporary comparator may live within one slice but cannot cross + the slice boundary as a second authority. +9. **Whole-mechanism fixes.** Do not change a downstream draw call when retail + owns the decision upstream in graph construction, portal traversal, shadow + registration, or stage ordering. +10. **Build before launch.** Every launched candidate is a green Release build + produced from a recorded commit/worktree state. `dotnet run` without a + successful build is forbidden. +11. **Exact binary for gates.** The commit/hash, package schema, environment + flags, and log path are recorded before every owner gate. +12. **Client process safety.** Never kill the client. Use graceful in-client + closure only when the owner has authorized control; otherwise wait for the + owner to close it. +13. **Preserve unrelated work.** No destructive git command, broad checkout, + reset, or clean. Every rollback is a normal revert of a named campaign + commit or a return to a recorded checkpoint. +14. **Register discipline.** A newly discovered deliberate deviation is filed + in the same commit. A retired deviation is removed in the same commit as + the exact port and its tests. +15. **Docs are tested truth.** If the architecture text and production code + disagree, the slice is not closed until one is corrected with evidence. + +--- + +## 5. The required Plan → Implement → Review loop + +Every numbered slice follows the same state machine: + +```text +PLANNED + → EVIDENCE COMPLETE + → IMPLEMENTED + → REVIEWED (architecture + retail fidelity) + → FINDINGS FIXED + → NARROW RE-REVIEW + → AUTOMATED GATE GREEN + → OWNER GATE, only when assigned + → CLOSED + rollback recorded +``` + +### 5.1 Plan packet required before implementation + +Each slice receives a short research packet under +`docs/research/2026-09-01-overhaul/` containing: + +- the exact question being answered; +- named retail functions and addresses; +- struct fields and offsets used; +- caller/callee order; +- all branch senses that change behavior; +- retail state before and after the call; +- current acdream source locations; +- a retail-vs-acdream difference table; +- the smallest production ownership change that closes the difference; +- tests that fail before and pass after; +- performance/allocation risk; +- rollback boundary; +- whether an owner gate is required and why automation cannot settle it. + +No packet may say "probably," "roughly," or "retail-shaped" at the behavior +being implemented. Unresolved facts block only that sub-slice; they do not +license an approximation. + +### 5.2 Implementation discipline + +- Implement one retail invariant at a time. +- Keep the diff local to the named ownership boundary. +- Add the deterministic failing test or comparator before changing production + behavior whenever practicable. +- Preserve retail ordering even if it temporarily produces more draw calls. + Adjacent-run batching is a later, separately reviewed optimization. +- Do not mix diagnostic experiments with the final implementation commit. +- Remove the replaced production route and its tests in the cutover commit. +- Build focused projects after every meaningful edit; build the full solution + before review. + +### 5.3 Two mandatory review lenses + +**Architecture review** asks: + +- Is there exactly one owner for this fact? +- Did a render cache or projection become a second world model? +- Do graphical and physics consumers borrow the same generation/identity? +- Are publication and teardown atomic at the existing boundary? +- Is fallback behavior explicit, bounded, and retail-supported? +- Did the change leak App/Vulkan types into Core/Content/Runtime? +- Can a retry, cancellation, recenter, or late upload create mixed generations? + +**Retail-fidelity review** asks: + +- Is every behavioral branch tied to a named retail function? +- Were ambiguous conditions Ghidra-arbitrated? +- Are list order, iteration direction, stamps, latches, and flush sites exact? +- Are built-mesh and non-built-mesh retail branches distinguished? +- Are polygon sides and Surface types interpreted from the correct owner? +- Does the implementation preserve retail quirks rather than normalize them? +- Does the test assert the retail mechanism, not merely the desired screenshot? + +Review findings are recorded as Blocker/Major/Minor. Blocker and Major findings +must be fixed before the slice gate. The changed surface receives a narrow +re-review; a review is not closed by author explanation alone. + +### 5.4 Commit shape + +Prefer this sequence for each slice: + +1. `docs(render): define OHx retail contract` — evidence packet and fixtures. +2. `fix(render): port OHx ` or + `refactor(render): cut over OHx ` — behavior and focused tests. +3. `docs(render): close OHx review` — review disposition, measured gates, + register/doc reconciliation. + +A very small slice may combine 1 and 2, but the evidence must still predate the +behavioral decision in the diff history. Every closed slice records its commit +and `git revert ` anchor in this file. + +--- + +## 6. Evidence hierarchy and oracle products + +When sources disagree, use this order: + +1. Installed retail binary behavior captured at named functions. +2. Named retail PDB/header identity and Ghidra-arbitrated decompilation. +3. Byte-exact installed DAT structure and geometry. +4. Existing retail cdb/oracle traces in + `docs/research/2026-08-30-fw-walk-oracle/posed/`. +5. Deterministic acdream replay of the same input. +6. Render/API captures for confirming submitted geometry and state. +7. acdream diagnostic logs. +8. Visual observation, used to discover symptoms and accept final pixels—not + to infer object identity or branch logic. + +### 6.1 Canonical frame transcript + +OH1 defines a versioned, line-oriented transcript. At minimum it records: + +- frame number, frame stamp, previous/current `portalsDrawnCount`; +- camera pose, resolved camera root, player cell, outdoor/interior root kind; +- PView identity (`root` versus building look-in), `draw_landscape`, and + outside-view count; +- each portal-view polygon after every clip, including exact ordered vertices; +- todo insertion/pop order and cell draw-list append order; +- landscape landcell order and `in_view` result; +- building entry, degrade gate, look-in portal pass, alpha barrier, punch, and + shell draw; +- EnvCell shell draw stamp and mesh identity; +- object-list cell turn and every admitted part, with membership source; +- particle owner turn and degradation decision; +- alpha enqueue list, insertion key, queue identity, and flush site; +- full-depth clear, far-Z punch, and true-depth seal state; +- exact final draw-leaf sequence. + +Retail and acdream use the same semantic schema. Pointer values, Vulkan handles, +and allocation addresses are excluded from equality. + +### 6.2 Canonical geometry manifest + +For every audited CellStruct polygon: + +```text +cellStructId +polygonIndex +sides_type / CullMode +NoPos / NoNeg +positiveSurfaceId / negativeSurfaceId +positiveSurface.Type / negativeSurface.Type +selected side(s) +subset classification +emitted/skipped reason +vertex IDs and final winding +``` + +The manifest is required for cathedral cells `0xF4180100`, `0101`, `0104`, +`0106`, `0107`, `0112`, `0113`, and `0114`, plus the Facility Hub stair cells +around `0x8A02015E/015F`. Installed-DAT catalog tests sample additional ordinary +dungeons so the solution cannot overfit those two buildings. + +### 6.3 Canonical part-membership manifest + +For each static/dynamic object part: + +```text +owner identity and owner kind +Setup ID / part index / GfxObj ID +root transform and part transform +retail drawing sphere and/or part bounds +resident cell +every crossed shadow cell, in retail insertion order +parent/child inheritance source +render membership +physics membership +fallback reason, if any +``` + +The production invariant is that one canonical registration transaction +produces retail's typed outputs: per-part render-shadow cells and object-level +physics `CELLARRAY`/broadphase cells. Those outputs may differ where retail's +algorithms differ, but no consumer may recalculate either one independently. + +--- + +## 7. Target architecture + +The final design keeps modern immutable storage but restores retail ownership. +Names below are descriptive; OH1 may refine names without weakening the +contract. + +```text +Prepared DAT assets + ├─ exact CellStruct mesh/subset records + ├─ exact portal/topology records + ├─ exact building shell/portal ownership + └─ exact Setup/GfxObj part records + │ + ▼ +WorldCellGraphSnapshot (one generation, one authority) + ├─ CellNode[] + │ ├─ drawable shell identity + │ ├─ ordered portals/neighbours + │ ├─ owning building + │ ├─ ordered static part shadows + │ └─ ordered dynamic part shadows + ├─ BuildingNode[] + ├─ PartRenderShadowMembership[] + ├─ ObjectPhysicsCellMembership[] + └─ exact stable indices/identities + │ + ├─────────────► physics adapter (borrowed) + ├─────────────► render preparation adapter (borrowed) + └─────────────► RetailFrameWalk (borrowed topology) + │ + ▼ + Retail semantic draw transcript + │ + ▼ + Vulkan encoder / adjacent batching +``` + +### Required properties + +- Core/shared records are BCL-only and contain no Vulkan handles. +- Mesh payloads remain Content/App resources referenced by stable IDs/ranges. +- The existing generation/publication transaction remains the publication + boundary; this campaign does not invent a second streamer. +- A complete graph snapshot becomes visible atomically. +- Render and physics adapters never mutate canonical topology/membership. +- Dynamic membership updates replace one object's membership transactionally + and preserve exact object incarnation/generation identity. +- Child objects inherit the retail root object's `CELLARRAY` through one + canonical rule. +- The walk owns temporary per-frame portal views, todo lists, draw lists, + stamps, and latches. These are not persisted in render projections. +- The Vulkan encoder receives clip/depth/order data but cannot enlarge the + visible set or reorder across a semantic boundary. + +--- + +## 8. Stage overview and owner-gate budget + +| Stage | Purpose | Owner gate | +|---|---|---| +| OH0 | Preserve/classify the current state and establish baseline evidence | No | +| OH1 | Define the exact retail world contract and upgrade the oracle | Only if a missing retail capture requires owner action | +| OH2 | Exact CellStruct geometry and prepared-package representation | **Gate G1** after automated world-geometry checks | +| OH3 | One canonical cell graph and exact part-shadow membership | Fold into G1 if no second launch is needed; otherwise a short G1b | +| OH4 | Exact PView views and leaf admission/clipping contracts | No standalone owner gate | +| OH5 | Exact landscape/building/cell/object interleave | No standalone owner gate | +| OH6 | Exact depth epoch, clear latch, punches, seals, and frame stamps | **Gate G2** for opaque-world solidity | +| OH7 | Exact alpha ownership, ordering, and flushes | No standalone owner gate | +| OH8 | Exact landscape `in_view` and particle/light/shadow consumers | **Gate G3** together with OH7/OH9 | +| OH9 | Building/material/degrade leaf fidelity required for composition | Fold into G3 | +| OH10 | Delete duplicate owners, fallbacks, experiments, and stale claims | No | +| OH11 | Full regression, performance, connected routes, docs, final acceptance | **Gate G4** final matrix | + +The owner should normally see four builds during the campaign, not one build per +code slice. A new owner gate is added only when the automated oracle cannot +settle a real visual/feel question or a prior gate exposes a regression. + +--- + +## 9. Detailed stages + +### OH0 — safety baseline and dirty-tree classification + +**Goal:** make the current state recoverable and comprehensible before any +overhaul behavior changes. + +#### Plan + +1. Record HEAD, upstream, status, staged/unstaged/untracked files, submodules, + package schema, shader manifest hash, and installed-DAT identity. +2. Classify every current dirty file into: + - accepted prior fix; + - current cathedral/facility investigation; + - exact retail depth-state port; + - diagnostic-only apparatus; + - tests for one of those changes; + - unrelated/user-owned change. +3. Record the runtime flags that change behavior, especially every + `ACDREAM_PROBE_CATHEDRAL_*` switch, and prove they are unset in normal + launch state. +4. Build the current state in Release and run the focused walk/geometry/depth + tests. Record failures honestly; do not edit production to make OH0 green. +5. Write `docs/research/2026-09-01-overhaul/oh0-baseline.md` with the complete + inventory and the exact recovery procedure. +6. Create a normal checkpoint commit containing only classified campaign work + after confirming no unrelated user change is swept into it. If unrelated + changes cannot be separated safely, leave them dirty and record hashes; + never force a checkpoint by overwriting them. + +#### Implement + +OH0 changes documentation, evidence tooling, and checkpoint history only. It +does not change draw behavior. + +#### Review + +- Confirm every pre-existing dirty file is accounted for. +- Confirm the accepted `b8befded` anchor and current HEAD are both recorded. +- Confirm no behavioral probe is silently enabled by a default. +- Confirm the checkpoint can be reverted without reverting user-owned work. + +#### Automated gate + +- Release solution build result recorded. +- Focused walk/depth/geometry test results recorded. +- `git diff --check` clean for new OH files. +- Recovery recipe reviewed from a fresh `git status` snapshot. + +#### Owner gate + +None. OH0 should not consume owner time. + +#### Exit artifacts + +- `oh0-baseline.md` +- first entry in the execution ledger +- checkpoint/recovery anchor + +--- + +### OH1 — retail world contract and oracle completion + +**Goal:** replace prose such as "retail-shaped" with an executable contract for +world construction and every frame leaf. + +#### Plan + +Produce focused, Ghidra-arbitrated notes for these symbol families: + +1. **Construction/ownership** + - `CEnvCell::init_static_objects` + - `CPhysicsObj::calc_cross_cells_static` + - `CPartArray::AddPartsShadow` + - `CPhysicsObj::add_shadows_to_cells` + - child-list propagation and cell removal counterparts +2. **Portal traversal** + - `PView::InitCell` + - `PView::InsCellTodoList` + - `PView::ClipPortals` + - `PView::AddViewToPortals` + - `PView::ConstructView` + - `Render::copy_view`, `Render::set_view`, `Render::obj_view_set` + - `Render::viewconeCheck` +3. **Landscape/building order** + - `LScape::draw_check_blocks` + - `LScape::landcell_check` + - `LScape::grab_visible_cells` + - `LScape::draw` + - `RenderDeviceD3D::DrawBuilding` +4. **Cell/object leaves** + - `PView::DrawCells` + - `RenderDeviceD3D::DrawEnvCell` + - `RenderDeviceD3D::DrawObjCellForDummies` + - `CPhysicsPart::Draw` and its built/non-built branches +5. **Geometry/material/alpha** + - `D3DPolyRender::ConstructMesh` + - `D3DPolyRender::DrawMesh` + - `D3DPolyRender::AddMeshToAlphaList` + - `D3DPolyRender::FlushAlphaList` + - `CShadowPart::insertion_sort` +6. **Depth lifecycle** + - the complete `PView::DrawCells` outside-view block; + - the source, reset, and previous-frame consumption of + `portalsDrawnCount`; + - the mid-frame frame-stamp increment; + - far-Z portal punches and true-depth exit seals. + +The result must explicitly answer: + +- Which built meshes are submitted whole after a Boolean sphere test? +- Which geometry is actually polygon-clipped by the installed portal view? +- Does a surviving object view cause multiple built-mesh draws or only repeated + admission tests before a draw stamp suppresses duplicates? +- Which frame stamp applies to landscape look-ins versus the interior root? +- Which list owns transparent EnvCell subsets? +- What exactly increments `portalsDrawnCount`, and when is it cleared? +- What is the exact relationship between cell traversal order and part-shadow + insertion order? + +#### Implement + +1. Define the canonical transcript schema and serializers in test/tooling code. +2. Extend retail capture templates only for missing fields. +3. Add acdream transcript emission behind one print/file diagnostic that does + not alter behavior. +4. Convert the existing posed FW oracle into semantic fixtures consumable by + equality tests. +5. Add geometry and membership manifest generation to `A8CellAudit` or a + narrowly named successor tool; do not add DAT parsing to App. + +#### Review + +- Retail review verifies every transcript field is observable at the cited + retail site. +- Architecture review verifies tooling does not become a second production + visibility owner. +- A fixture review verifies pointers/addresses are normalized while ordering, + float bits, IDs, and branch outcomes remain exact. + +#### Automated gate + +- Existing posed traces parse without loss. +- Round-trip transcript serialization is byte-stable. +- Synthetic ordering/latch fixtures detect deliberate one-event mutations. +- Installed-DAT manifests are deterministic across two runs. +- No production draw result changes. + +#### Owner gate + +Only if a retail capture lacks a fact that cannot be recovered statically. The +request must name the exact location, pose, action, capture duration, and +expected output; no open-ended "run around and report" gate. + +#### Exit artifacts + +- `oh1-retail-world-contract.md` +- versioned transcript schema +- versioned geometry/membership manifest schema +- retail/acdream replay fixtures + +--- + +### OH2 — exact CellStruct geometry and subset construction + +**Goal:** retire AP-234 and make cell-wall geometry a byte/data-derived fact. + +#### Plan + +1. Trace `DrawEnvCell → DrawMesh(arg4=1)` and + `ConstructMesh` through Surface lookup and subset creation. +2. Pin the meaning of `sides_type`, `NoPos`, `NoNeg`, positive/negative + surface IDs, untextured surfaces, clip maps, and reversed winding. +3. Produce before-state manifests for all canonical cathedral and Facility Hub + cells and a statistically useful installed-DAT sample. +4. Identify every prepared-package record affected by adding exact surface + identity/type to the extraction decision. +5. Define package version/migration behavior before changing the codec. + +#### Implement + +1. Thread the real positive/negative `Surface.Type` into + `PrepareCellStructMeshData` before emit/skip selection. +2. Apply retail's exact side/subset rule; remove the `NoPos` approximation and + its explanatory exception. +3. Preserve original polygon/vertex order and float bits. +4. Update the prepared payload schema and strict codec if necessary. +5. Update bake equivalence, migration catalog, launcher package validation, and + corruption tests together. +6. Rebuild only the required prepared package through the supported bake flow; + never patch the package by hand. +7. Delete AP-234 in the same behavior commit. + +#### Tests + +- Unit matrices for all `sides_type × NoPos × NoNeg × Surface.Type` + combinations. +- Positive/negative side winding and material identity tests. +- CellStruct manifest goldens for canonical scenes. +- Installed-DAT comparison over all available CellStruct records, reporting + every changed polygon and why. +- Prepared-package encode/decode/corruption/version tests. +- Render-batch tests proving an untextured subset is skipped and a textured + `NoPos` edge case follows retail rather than the old proxy. + +#### Review + +- Retail reviewer checks the exact subset decision against the decomp. +- Data reviewer checks no ordinary GfxObj rule was accidentally applied to + CellStructs or vice versa. +- Architecture reviewer checks the Surface lookup remains in Content/bake, + not a render-thread DAT read. + +#### Automated gate + +- Content, Bake, Launcher.Core, and focused App suites green in Release. +- Installed-DAT manifest produces no unexplained difference. +- Full solution Release build green. +- No per-frame allocation or DAT lookup added. + +#### Owner gate G1a — geometry integrity + +One exact build, normal settings, all behavior-changing probes unset: + +- cathedral exterior ramp and all floating stair slabs; +- cathedral walls at the known `0x104/0106` and `0x107/0112` seams; +- Facility Hub bottom/top stairs and doorway walls; +- two ordinary dungeons with solid-color and textured cell surfaces; +- Holtburg/Nanto building shells. + +Pass means no missing/new wall faces, no invisible ramp/slab, and no gross +material substitution. Camera-dependent occlusion is not adjudicated until +OH6. + +#### Rollback + +One normal revert of the OH2 behavior/schema commit plus restoration of the +previous prepared package version through the supported launcher migration. + +--- + +### OH3 — canonical world-cell graph and exact part-shadow membership + +**Goal:** one graph owns the relationships retail stores on `CEnvCell`, +`CBuildingObj`, `CPhysicsObj`, `CPartArray`, and `CShadowPart`. + +#### OH3a — graph contract and read-only construction + +**Plan:** map every existing source of cell topology, building ownership, +static membership, dynamic membership, and child inheritance. Define stable +keys and generation lifetime. + +**Implement:** build `WorldCellGraphSnapshot` alongside existing owners from +the same accepted publication input. It is initially read-only and diagnostic; +no consumer changes behavior. + +**Review:** reject any field that is a renderer cache rather than world truth; +verify Core/shared layering and atomic lifetime. + +**Gate:** exhaustive equality between graph topology and source publication; +zero production pixel change. + +#### OH3b — static `AddPartsShadow` parity + +**Plan:** port exact part bounds/shape, cell-crossing, insertion order, and +removal rules for indoor statics, building parts, landblock statics, scenery, +and non-colliding decorations. + +**Implement:** populate one ordered membership vector per visual part. Retain +the old render index as a comparator only inside OH3b. Cut render lookup to the +canonical membership after exact comparison is green. + +**Tests:** cathedral ramp/stairs/walls, Facility stairs, a large outdoor object +crossing a 24 m cell edge, a landblock-edge object, a non-colliding decoration, +and a multi-part Setup whose individual parts cross different cells. + +**Delete:** the superseded visual-AABB index builder and duplicate cell buckets +after cutover. + +#### OH3c — dynamic and child membership parity + +**Plan:** port `add_shadows_to_cells`, removal, movement update, and child-list +inheritance as one transaction tied to exact runtime entity incarnation. + +**Implement:** one dynamic registration transaction produces the distinct +retail render-shadow and physics-cell outputs, and the corresponding adapters +borrow those typed results. Visual-only effects use a separately named, +retail-supported owner rule rather than silently falling back to root position. + +**Tests:** local player, remote player, NPC, projectile, spell worldobject, +equipped child, contained child, crossing an indoor portal, crossing outdoors, +and teardown/reconnect. + +#### OH3d — consumer cutover and deletion + +Cut the following consumers to the canonical graph in one controlled series: + +1. indoor static render lookup; +2. outdoor static render lookup; +3. dynamic render lookup; +4. physics broadphase projection; +5. particle owner-cell lookup; +6. point-light owner-cell lookup; +7. directional-shadow caster reachability. + +After every consumer agrees, delete duplicate dictionaries, origin-cell +fallbacks for prepared content, and independent render membership builders. + +#### Review + +- Architecture: exactly one membership authority; retry/recenter/reset safe. +- Retail: crossed cells and insertion order match `AddPartsShadow` family. +- Lifecycle: no stale incarnation or old generation can retain membership. +- Performance: no per-frame graph rebuild; updates are proportional to changed + objects. + +#### Automated gate + +- Exact membership comparator reports zero mismatch across the installed-DAT + canonical routes. +- Render-shadow and physics-cell projections each match their typed expected + output from the same canonical registration transaction; any intentional + difference between the two is explicit and fixture-covered. +- Cancellation, generation replacement, landblock retirement, reconnect, and + child detach converge to zero retained rows. +- Full Release solution and connected headless lifecycle route green. + +#### Owner gate G1b — membership stability + +Use G1a's same binary if practical; otherwise launch once after OH3d: + +- stand on and move around cathedral floating stairs/ramp; +- move/rotate at Facility Hub stairs; +- circle dense Tusker groups while turning the camera; +- observe remote player and NPC across the cathedral wall cells; +- cast and complete several spells, confirming no lingering visual owners. + +Pass means static geometry never disappears merely because its origin cell or +camera-facing cell changes, dynamics do not vanish at membership transitions, +and retired effects leave no render rows. + +--- + +### OH4 — exact PView state and draw-leaf contract + +**Goal:** prove and port what each installed portal view does to each content +category. This stage resolves the current GPU clip-slot uncertainty. + +#### Plan + +For EnvCell shells, building shells, indoor statics, outdoor statics, dynamic +objects, and particles, record separately: + +- number of `portal_view` iterations; +- `viewconeCheck` inputs/result; +- draw-stamp read/write; +- `Render::set_view`/`obj_view_set` calls; +- built versus immediate polygon path; +- whether the final mesh is whole, CPU clipped, or later raster clipped; +- whether multiple surviving views cause multiple submissions; +- which view remains installed at the draw call. + +The already-proved EnvCell rule is binding: the built cell shell is stamped and +submitted whole once. The old "first view clips the shell" hypothesis is +retired and may not return without contradictory binary evidence. + +#### Implement + +1. Make `WalkPView` own the exact mutable per-frame state retail owns: + portal-view lists, view/update counts, todo ordering, draw list, and stamps. +2. Retain exact screen/homogeneous portal polygons as the semantic view. +3. Apply the retail leaf contract per content category: + - whole mesh once where retail does so; + - Boolean drawing-sphere admission where retail does so; + - exact polygon clipping only where retail does so; + - repeated submission only where retail does so. +4. Remove Vulkan clip slots from any category for which they add clipping not + present in retail. +5. Where a retail polygon clip genuinely must reach Vulkan, translate the + already-decided clipped polygon/planes exactly once and pin conventions with + CPU/GPU equivalence tests. +6. Delete comments/tests asserting the disproved generic rule that every + accepted cell/static/dynamic mesh must render through the same clip slot. + +#### Review + +- One table row per content category with a retail call chain. +- Ghidra verification of every stamp/view loop branch. +- Shader review of clip-space sign, y inversion, W plane, max plane count, and + scissor interaction for the remaining translated categories. +- Ensure clip slots cannot become a second admission mechanism. + +#### Automated gate + +- Retail/acdream leaf transcript equality for posed cathedral frames. +- Tests distinguish whole-shell once, Boolean part admission, and actual + polygon clipping. +- Camera pan/zoom replay does not change membership or draw count except at the + same retail view boundary. +- No unexplained duplicate draw of a stamped part. + +#### Owner gate + +Deferred to G2 after frame ordering and depth lifecycle are exact. Testing OH4 +alone would produce ambiguous pixels and waste an owner round. + +--- + +### OH5 — exact landscape, building, cell, and object interleave + +**Goal:** make the frame event sequence equal to retail rather than drawing +terrain as a preliminary block. + +#### Plan + +1. Recover the exact `LScape::draw`/`grab_visible_cells` iteration direction, + sorting keys, and per-landcell call order. +2. Define the exact relationship between: + - terrain cell draw; + - building draw; + - landcell object list; + - building look-in flood; + - outdoor statics and particles; + - pre-clear alpha drain; + - interior root cell-shell/object-list passes. +3. Record all degrade gates and their location relative to alpha barriers. +4. Design terrain draw ranges that allow per-landcell turns without changing + terrain geometry or texture blending. + +#### Implement + +1. Replace `DrawTerrainSlice` as a whole-stage event with ordered landcell + terrain events. +2. Give `TerrainModernRenderer` stable per-landcell ranges/commands. +3. Emit terrain, buildings, and object lists in retail far-to-near order. +4. Reproduce `DrawBuilding` as one semantic sequence: + degrade gate → full alpha barrier → portal/look-in work → punch → own shell. +5. Preserve the separate interior `DrawCells` two-pass order: all shells in + reverse draw-list order, then all object lists in reverse draw-list order. +6. Permit Vulkan to merge only adjacent compatible terrain/draw commands with + no intervening semantic event. +7. Remove the source comment and implementation that acknowledge "all terrain + first" simplification. + +#### Tests + +- Synthetic three-landcell scene with buildings/objects between terrain + cells; exact event-string golden. +- Equal-distance tie ordering. +- Building with and without drawable degrade slot. +- Look-in building embedded between two outdoor cells. +- Interior root with landscape views and without them. +- Outdoor root with no interior clear. +- Renderer command-buffer test proving an alpha/depth boundary prevents an + otherwise legal adjacent merge. + +#### Review + +- Retail call-order audit against trace and decomp. +- Performance review ensures command count increase is measured, not hidden by + reordering. +- Architecture review ensures terrain does not acquire a competing visibility + list. + +#### Automated gate + +- Frame transcript order exact for all posed fixtures. +- Terrain pixels/mesh counts unchanged when no building/object interleave is + present. +- Dense outdoor CPU/GPU p50/p99 captured as an informational checkpoint; no + optimization is permitted to alter order. + +#### Owner gate + +Deferred to G2. + +--- + +### OH6 — exact depth epoch, clear latch, portal punches, seals, and stamps + +**Goal:** reproduce retail's complete depth lifecycle, not merely the punch +pipeline state. + +#### Plan + +1. Reconstruct the full `PView::DrawCells` control flow around + `outside_view.view_count`, the landscape block, alpha flush, frame-stamp + increment, conditional clear, and exit seals. +2. Identify the sole producers/reset sites of `portalsDrawnCount` and prove + whether the clear consumes the previous frame's value before or after reset. +3. Confirm look-in PViews (`draw_landscape=0`) never execute the root landscape + clear/seal block. +4. Confirm which 0xFFFF portals are sealed, their iteration order, installed + view, polygon orientation, and true-depth draw. +5. Retain the already-ported exact Vulkan state: + depth test ALWAYS, depth write ON, color write OFF, no stencil; far-Z for + punch, true clip-space depth for seal. + +#### Implement + +1. Add one explicit frame-persistent latch owner corresponding to retail's + `portalsDrawnCount`; no renderer-local heuristic. +2. Gate the complete landscape→flush→stamp→clear→seal block exactly as retail. +3. Remove `WalkFrameDriver`'s unconditional interior clear. +4. Place the mid-frame stamp transition exactly; allow straddling parts to draw + in both retail scopes when retail re-arms them. +5. Generate exit seals from the exact current walk views and retail cell order. +6. Ensure building look-ins cannot advance or consume the root latch. +7. Delete obsolete stencil/bias tests and any diagnostic skip path once the + causal assertions are covered. + +#### Tests + +- Truth table over root kind, `draw_landscape`, outside-view count, + previous/current portal count, and expected clear/seal/stamp events. +- Two consecutive frames proving the latch is genuinely cross-frame. +- Multiple building look-ins proving isolation from the root PView. +- Coincident cathedral exits at y≈24, y=48, and y=72. +- Recording GPU tests for exact punch/seal pipeline and draw count. +- Negative tests: outdoor root never clears interior depth; zero-view interior + root does not execute a fabricated landscape block. + +#### Review + +- Retail reviewer traces every state write from producer to next-frame + consumer. +- GPU reviewer checks pipeline state and clip-depth calculation only after the + scheduling transcript is exact. +- Architecture reviewer checks the latch has one frame owner and deterministic + reset on session/world generation changes. + +#### Automated gate + +- Exact depth-event transcript equality for posed fixtures. +- Focused walk/depth suites green. +- Full Release build and hermetic App suite green. +- Cathedral replay contains no behavior-changing probe. + +#### Owner gate G2 — opaque-world solidity + +The owner receives one exact binary with a short prescribed route: + +1. Cathedral `0xF4180106 ↔ 0xF4180104`: move both directions, zoom, rotate; + player remains whole and walls remain opaque. +2. Cathedral `0xF4180107 ↔ 0xF4180112` floating stairs: ascend/descend, pan, + zoom, stand at top and bottom; no wall-textured beam, missing slab, exterior + terrain bleed, or chopped player. +3. Cathedral exterior ramp: visible from all meaningful exterior angles. +4. Remote player parked at `0xF4180112`: hidden from `0x104`, `0x101`, and + outdoors wherever retail has no sightline; visible only through valid + openings. +5. Facility Hub stairs at `0x8A02015E/015F`: stairs and player remain whole at + bottom, side, ascent, top, and all retail zoom extents. +6. Tusker/Nanto/Holtburg: rotate in place; terrain, buildings, and opaque + objects remain stable. + +Any failure reopens the owning OH4/OH5/OH6 slice based on transcript evidence. +No new camera-specific suppression is allowed. + +--- + +### OH7 — exact alpha lists, per-cell order, and flush boundaries + +**Goal:** retire AP-34 by reproducing retail's alpha ownership and order. + +#### Plan + +1. Map the two retail alpha lists, their owners, insertion sites, insertion + keys, equal-key behavior, and flush/reset lifecycle. +2. Recover `CShadowPart::insertion_sort` exactly, including direction and ties. +3. Pin every full flush: + - `DrawBuilding(... FlushAlphaList(0f))`; + - `DrawCells` pre-clear; + - final normal-mode flush. +4. Pin `DrawBlock`'s 0.75 pressure-valve semantics and prove it does not become + a global distance sort. +5. Determine the queue ownership of transparent EnvCell shell subsets. + +#### Implement + +1. Replace the scope-global CYpt sort with explicit retail queue/list records. +2. Enqueue transparent parts at their cell/object turn after retail per-cell + insertion ordering. +3. Route transparent EnvCell subsets through the correct queue/flush behavior. +4. Preserve FIFO at flush; do not sort the finished list globally. +5. Preserve blend-mode boundaries without reordering entries. Adjacent + compatible entries may batch only if their FIFO positions remain adjacent. +6. Implement the 0.75 pressure valve exactly. +7. Retire AP-34 in the behavior commit. + +#### Tests + +- Multiple translucent objects in one cell with reversed distance/insertion + orders. +- Equal CYpt stable tie. +- Two cells whose global distance sort would disagree with retail traversal. +- Particle, translucent object, and transparent EnvCell overlap. +- DrawBuilding 0f full flush. +- Pre-clear flush and final flush. +- 0.75 partial flush/pressure valve. +- Alternating blend modes prove order retention across Vulkan batches. + +#### Review + +- Retail list/order review from insertion to flush. +- Vulkan review for blend/depth state without semantic reorder. +- Allocation review: queue storage is retained/reused, with no per-entry boxes. + +#### Automated gate + +- Alpha transcript exact on synthetic and posed fixtures. +- AP-34 deleted. +- Particle/mesh shared-alpha tests green. +- Dense particle field performance captured. + +#### Owner gate + +Fold into G3 after OH8/OH9 so particles, `in_view`, and material combine are +tested together. + +--- + +### OH8 — exact landscape `in_view` and visibility consumers + +**Goal:** make terrain visibility, outdoor particle updating, light admission, +and shadow reachability consume retail state instead of a modern approximation. + +#### Plan + +1. Port and fixture `LScape::draw_check_blocks`, `landcell_check`, + `get_clip_height`, and `block_check` from named retail/Ghidra. +2. Establish exact grid pitch, interval math, corner order, view union, + previous-frame stamping, and outside/inside enum meanings. +3. Pin `CLandCell::IsInView` previous-frame behavior and + `CEnvCell::IsInView`'s constant `PARTIALLY_INSIDE` behavior. +4. Map the update-time and draw-time particle gates separately. +5. Define the complete visibility answer as typed products, not one ambiguous + set: visited EnvCells, in-view landscape cells, drawable object parts, and + particle-update cells. + +#### Implement + +1. Produce the exact retail landcell `in_view` set during the landscape walk. +2. Replace frustum/AABB reconstruction for retail `IsInView` consumers. +3. Feed exact state to particle update/degrade, point-light snapshots, and + directional-shadow selection. +4. Keep EnvCell preparation scoped to visited EnvCells; do not union unrelated + outdoor cells into shell preparation. +5. Preserve the explicit user-selectable Extended particle range after the + exact retail visibility gate. Retail mode applies no multiplier. +6. Retire or narrow AP-117 based on the exact port. + +#### Tests + +- Landcell boundary grazing and multiple portal-view union. +- Previous-frame `CLandCell::IsInView` timing. +- Constant interior EnvCell particle cell test plus distance gate. +- Nanto waterfalls turning at `0xE43D001E`. +- Cathedral waterfall owner range `0xCF418000..13`. +- Tusker scenery/creature visibility while rotating. +- Point light and shadow consumer equality with canonical typed sets. + +#### Review + +- Retail math and one-frame timing review. +- Consumer audit proves no remaining frustum/AABB visibility reconstruction. +- Settings review isolates Extended range as a deliberate post-retail option. + +#### Automated gate + +- Installed-DAT terrain visibility comparisons green. +- Particles/lights/shadows report no independent cell-set decisions. +- Full Core/App focused suites green. + +--- + +### OH9 — building/material/degrade leaf fidelity + +**Goal:** close remaining composition differences that can look like missing or +bleeding world geometry even when traversal is correct. + +#### Plan + +1. Audit `DrawBuilding` degrade selection and no-geometry behavior. +2. Audit building/EnvCell detail texture setup and transparent subset combine. +3. Resolve AP-232 by pinning retail's single fixed-function stage result, + including output alpha. +4. Confirm cull mode, negative-side rendering, clip-map discard, fog, depth + write, and blend state per world subset class. +5. Separate material defects from lighting differences; this stage changes + lighting only when named retail material state requires it. + +#### Implement + +1. Make building degrade selection and complete body gate exact. +2. Reproduce retail's single-result detail combine for translucent subsets, + either in one Vulkan shader path or a mathematically proven equivalent that + produces the same framebuffer result. +3. Preserve exact opaque detail behavior. +4. Normalize world subset state through one audited policy table so building, + EnvCell, and ordinary GfxObj paths cannot silently disagree. +5. Retire AP-232 when pixel-equivalence tests cover translucent detail. + +#### Tests + +- Opaque, clip-map, alpha, inverse-alpha, additive, luminous, and detail-bearing + world subsets. +- Translucent detail over dark and bright backgrounds. +- Building degrade slot absent/present. +- Positive/negative side and cull-state matrix. +- Fogged transparent detail identity. + +#### Review + +- Retail material-stage review. +- Shader algebra review with framebuffer-equivalence fixtures. +- Pipeline-state review for depth/cull/blend consistency. + +#### Automated gate + +- AP-232 deleted. +- Offscreen framebuffer tests match the retail formula. +- World material suites and full Release build green. + +#### Owner gate G3 — transparency, particles, and material composition + +One combined route: + +- cathedral waterfalls, lake mist, torches, floating stairs, walls, exterior + ramp, lifestone/portal effects, and remote actors; +- Nanto waterfalls while rotating at the recorded position; +- Holtburg lifestone behind houses and NPCs; +- Tusker spell casting, projectile completion, corpses, dense creatures, and + scenery; +- Facility Hub point lights and transparent/magenta-lit surfaces at multiple + zoom levels; +- at least one ordinary dungeon with transparent/detail-bearing material. + +Pass means correct occlusion, no lingering effects, no particle disappearance, +no transparency exchange across cells, and no camera-dependent material bleed. + +--- + +### OH10 — delete reconstruction residue and enforce the architecture + +**Goal:** ensure the exact path is the only path that can ship. + +#### Plan + +Inventory every class/field/flag made obsolete by OH2–OH9. Search by type, +constructor, interface, environment variable, log prefix, test name, and docs. + +#### Implement + +Delete or retire: + +- competing cell/part membership dictionaries; +- origin-cell and visual-AABB fallbacks for prepared world content; +- generic per-view GPU clip rules disproved by OH4; +- whole-stage terrain events superseded by per-landcell interleave; +- unconditional clear code and stale comments; +- scope-global alpha ordering superseded by retail queues; +- behavior-changing cathedral skip flags and carrier-discriminator code; +- obsolete shell lift, bias, stencil, corrective redraw, or suppression tests; +- `PortalVisibilityBuilder` research code if no test/research owner still needs + it; otherwise move it out of production assemblies and mark it non-authority; +- stale launch-option rows and retired diagnostics; +- architecture claims contradicted by the final code. + +Add architectural guards: + +- production call graph has one `WalkPView`/world-cell graph owner; +- renderer cannot query DAT directly; +- consumers cannot construct independent visibility sets; +- Vulkan submitter cannot sort across semantic event boundaries; +- no production reference to behavior-changing OH diagnostic symbols; +- divergence rows retired in their owning commits. + +#### Review + +- Dead-code/call-graph review. +- Architecture dependency review. +- Retail review of every deletion to ensure no real mechanism was mistaken for + patch apparatus. +- Documentation consistency review. + +#### Automated gate + +- `rg` guards and dependency tests green. +- No OH behavior-changing probe remains. +- Full Release build and hermetic suites green. +- `git diff --check` clean. + +#### Owner gate + +None; pixels must be unchanged from the accepted G3 binary. If cleanup changes +pixels, it is a failed deletion and the owning slice reopens. + +--- + +### OH11 — performance, regression, final owner acceptance, and closeout + +**Goal:** prove the exact architecture survives ordinary play and becomes the +documented shipping state. + +#### Automated closeout + +1. Full Release solution build. +2. Focused suites: + - App Walk/PView/frame-driver/depth/alpha/render tests; + - Content CellStruct/Surface/prepared-package tests; + - Core cell-transit/shadow/membership tests; + - Runtime lifetime/placement tests touched by shared membership; + - Launcher package migration tests. +3. Hermetic solution lane: + `Lane!=InstalledDat&Lane!=Linux&Lane!=Manual&Lane!=Timing&Lane!=Live&Lane!=PreparedPackage`. +4. Supported installed-DAT lane, with unsupported/known exclusions listed + rather than hidden. +5. Two clean deterministic geometry and membership manifest runs with equal + hashes. +6. Retail/acdream frame transcript equality over all canonical fixtures. +7. Capped and uncapped lifecycle/reconnect routes. +8. R6 nine-stop route. +9. Portal-in and portal-out presentation route, including long destination + preparation. +10. Graceful shutdown with zero retained graph/membership/alpha rows. + +#### Performance checkpoint + +Measure the exact final candidate in Release: + +- dense Arwic capped and uncapped; +- Tusker dense-creature scene; +- cathedral interior/floating stairs; +- Facility Hub interior; +- CPU/GPU p50 and p99, FPS, draw/dispatch counts, managed allocation/frame, + working/private memory, graph/membership retained bytes, and alpha queue high + water. + +Correctness comes first, but a regression greater than 20% against the recorded +pre-OH baseline triggers an explicit optimization slice before final gate. +Optimization may merge adjacent compatible commands or reuse storage; it may +not reorder, cull, or weaken the retail transcript. Every optimization must +pass transcript equality before performance is remeasured. + +#### Owner gate G4 — final acceptance matrix + +The final user gate repeats G1–G3 on one clean exact binary and adds ordinary +travel: + +- cathedral complete route and two-client wall occlusion; +- Facility Hub stair circuit; +- Nanto waterfalls and town buildings; +- Tusker Island combat/casting/camera rotation; +- Holtburg town/building/lifestone route; +- at least two ordinary dungeons selected without code changes; +- portal to/from each world type; +- zoom/pan/rotation at seams; +- ten minutes of free movement looking for spontaneous terrain/object loss. + +The owner verdict is recorded per row as PASS/FAIL with location and symptom. +A failure reopens the responsible slice. The final binary is not rebuilt after +owner acceptance except for documentation-only changes; if code or shader bytes +change, the affected gate repeats. + +#### Documentation closeout + +- Update `docs/architecture/acdream-architecture.md` with the actual canonical + graph and frame pipeline. +- Update `docs/architecture/worldbuilder-inventory.md` with the exact boundary: + asset extraction/preparation only, never world visibility ownership. +- Reconcile `docs/architecture/retail-divergence-register.md`. +- Update `docs/launch-options.md` after probe deletion. +- Close/supersede the relevant FW ledger sections without deleting history. +- Update roadmap, milestones, and `project_frame_walk_campaign.md` or its + successor memory with current truth at the top. +- Record final commits, package version, test counts, connected artifacts, + performance numbers, user verdict, and reverts. + +#### Campaign close condition + +Only after G4 passes and docs match code does Status change to +`CLOSED — USER ACCEPTED`. + +--- + +## 10. Canonical scene and symptom matrix + +| Scene | Fixed coordinates/state | Required invariant | Primary stages | +|---|---|---|---| +| Cathedral south transition | `0xF4180106 [37.181568 46.790077 169.804993]` ↔ `0xF4180104 [37.310383 48.895710 169.804993]` | Player and walls remain whole; no wand/body depth inversion | OH4–OH6 | +| Cathedral wall actor | Observer `0x104`, `0x101`, outdoors; remote in `0xF4180112 [36.299465 18.594580 169.804993]` | Actor visible only through a retail-valid sightline | OH3–OH6 | +| Cathedral floating stairs | `0xF4180107 [38.311169 24.270454 177.423584]` ↔ `0xF4180112 [38.333950 23.704699 177.868729]` | Every slab stable; no moving wall-textured triangles/rays | OH2–OH6 | +| Cathedral exterior ramp | Stand directly on the formerly invisible ramp | Exact authored shell/member always renders | OH2–OH5 | +| Facility Hub stairs | `0x8A02015E [60.971485 -42.752495 -4.121752]`, `0x8A02015F [58.815380 -49.425373 -0.857726]` | Stairs/player stable at bottom, side, ascent, top, zoom | OH2–OH6 | +| Nanto waterfalls | `0xE43D001E [93.826614 126.522484 120.005005]` | Falls do not vanish while rotating; houses occlude effects/NPCs | OH7–OH9 | +| Tusker Island | Owner's dense combat route | Terrain/scenery/actors stable; completed spell objects retire | OH3, OH5, OH8 | +| Holtburg | Town route | Buildings intact; particles/lifestone obey opaque depth | OH5–OH9 | +| Ordinary dungeons | At least two selected before code changes | No cathedral-specific overfit; stairs/walls/portals stable | All | + +The matrix is append-only during the campaign. New symptoms receive a row and +are assigned to an existing invariant before any fix is attempted. + +--- + +## 11. Test and command policy + +### Standard build + +```powershell +dotnet build AcDream.slnx -c Release +``` + +### Focused project families + +```powershell +dotnet test tests\AcDream.Content.Tests\AcDream.Content.Tests.csproj -c Release --no-build +dotnet test tests\AcDream.Core.Tests\AcDream.Core.Tests.csproj -c Release --no-build +dotnet test tests\AcDream.Runtime.Tests\AcDream.Runtime.Tests.csproj -c Release --no-build +dotnet test tests\AcDream.App.Tests\AcDream.App.Tests.csproj -c Release --no-build +dotnet test tests\AcDream.Launcher.Core.Tests\AcDream.Launcher.Core.Tests.csproj -c Release --no-build +``` + +Use focused `--filter` expressions during implementation, but a stage cannot +close on focused tests alone. Record exact commands and counts in the ledger. + +### Launch discipline + +Normal owner-gate launch, from the binding worktree after a green Release build: + +```powershell +$env:ACDREAM_DAT_DIR="$env:USERPROFILE\Documents\Asheron's Call" +$env:ACDREAM_LIVE="1" +$env:ACDREAM_TEST_HOST="127.0.0.1" +$env:ACDREAM_TEST_PORT="9000" +$env:ACDREAM_TEST_USER="testaccount" +$env:ACDREAM_TEST_PASS="testpassword" +dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Release +``` + +All behavior-changing probes remain unset for acceptance. A trace gate lists +its print-only flags explicitly. Never reuse an old running client after a +rebuild; record the launched binary hash and process start time. + +--- + +## 12. Instrumentation lifecycle + +Every new probe is declared in the owning research packet before code: + +- question it answers; +- exact emission site; +- fields and identity chain; +- print-only versus behavior-changing; +- expected maximum volume; +- environment flag; +- deletion stage. + +Rules: + +- Prefer deterministic file transcripts to console tail interpretation. +- Print only on state change or bounded frame windows unless a capture + explicitly requires every event. +- Never use aggregate owner IDs as geometry identity. +- Behavior-changing probes may exist only inside the active investigation and + must be visibly announced at startup. +- A behavior-changing probe can identify a mechanism; it cannot become the + mechanism. +- OH10 removes all Campaign OVERHAUL behavior-changing probes. + +--- + +## 13. Rollback and recovery policy + +1. No history rewrite. +2. Every closed behavior slice records a normal `git revert` anchor. +3. Schema migrations record both code revert and package restoration steps. +4. A failed owner gate reverts only the candidate slice if the cause is known; + otherwise preserve logs/artifacts and return to the latest accepted campaign + checkpoint. +5. Never revert the entire dirty starting tree to `b8befded`; that commit is a + historical baseline, not a substitute for OH0 classification. +6. Failed experiments are either reverted immediately or committed on an + explicitly quarantined branch. They do not remain mixed into the next + candidate. +7. The owner must always be told which exact client binary is running. + +### Rollback ledger + +| Slice | Implementation commit(s) | Last accepted gate | Revert command/notes | +|---|---|---|---| +| Starting history | `b8befded`, `4808d4d1`, `4683ac6f`, `e8808602` | FW/Tusker gates recorded in predecessor plan | Historical anchors only; OH0 classifies dirty successor work | +| OH0 | `b3b7d922` | n/a | Recovery checkpoint only; `git revert b3b7d922` removes the preserved investigation state. This commit is not a retail/visual acceptance claim. | +| OH1 | — | n/a | Fill during execution | +| OH2 | — | G1a | Fill during execution | +| OH3 | — | G1b | Fill during execution | +| OH4 | — | G2 combined | Fill during execution | +| OH5 | — | G2 combined | Fill during execution | +| OH6 | — | G2 | Fill during execution | +| OH7 | — | G3 combined | Fill during execution | +| OH8 | — | G3 combined | Fill during execution | +| OH9 | — | G3 | Fill during execution | +| OH10 | — | pixels unchanged | Fill during execution | +| OH11 | — | G4 | Fill during execution | + +--- + +## 14. Risk register + +### R1 — rebuilding retail's object graph as a second scene graph + +**Risk:** `WorldCellGraphSnapshot` becomes a mirror that can drift from Runtime +or publication state. + +**Control:** graph records own only canonical topology/membership facts; mesh +and entity state remain borrowed by stable identity. Atomic generation tests and +consumer deletion are part of OH3, not deferred cleanup. + +### R2 — over-porting mutable C++ mechanics + +**Risk:** copying retail pointer/list implementation creates unnecessary +allocation and lifetime hazards. + +**Control:** port observable ordering, ownership, stamps, and state transitions; +represent them with retained arrays/indexes. Equality is judged by semantic +transcript, not pointer layout. + +### R3 — Vulkan batching changes semantic order + +**Risk:** performance optimization regroups cells/materials after the exact +walk is built. + +**Control:** ordered stream is immutable; only adjacent compatible runs merge. +Tests deliberately place merge-compatible draws around alpha/depth boundaries. + +### R4 — prepared-package schema churn + +**Risk:** exact CellStruct surface data invalidates existing packages or creates +launcher/client skew. + +**Control:** OH2 owns one explicit version bump, strict rejection/migration, +rollback, corruption tests, and launcher coverage. + +### R5 — retail oracle incompleteness + +**Risk:** an unobserved built-mesh branch causes another confident but wrong +generic clipping rule. + +**Control:** OH1 explicitly separates each leaf category and blocks OH4 until +the built/non-built behavior is settled. No approximation is allowed to bridge +the gap. + +### R6 — scene overfitting + +**Risk:** cathedral IDs leak into production logic or tests validate only one +DAT structure. + +**Control:** production guards reject scene IDs; installed-DAT sampling and +ordinary-dungeon gates are mandatory. + +### R7 — performance collapse from per-cell commands + +**Risk:** exact interleave increases draw calls and CPU overhead. + +**Control:** correctness-first transcript; then adjacent-run merging and +retained storage only. The 20% stop rule requires an explicit optimization +slice, never a semantic shortcut. + +### R8 — stale documentation drives the next wrong fix + +**Risk:** architecture/plan claims remain inconsistent with code. + +**Control:** OH10 includes grep/document consistency checks; OH11 cannot close +until the architecture description is reviewed against production call sites. + +### R9 — too many owner gates + +**Risk:** implementation degenerates into repeated manual trial-and-error. + +**Control:** four planned gate builds only. Every build arrives after evidence, +implementation, two-lens review, fixes, and automated gates. + +--- + +## 15. Execution ledger + +Update this table immediately when a slice changes state. Do not keep the real +status only in chat. + +| Slice | Status | Evidence packet | Implementation | Reviews | Automated gate | Owner gate | Notes | +|---|---|---|---|---|---|---|---| +| OH0 | CLOSED | `docs/research/2026-09-01-overhaul/oh0-baseline.md` | `b3b7d922` recovery checkpoint | Read-only dirty-tree classification; every path accounted for | Release build green; focused gates 319 passed / 1 skipped; OH docs pass `git diff --check` | n/a | No production behavior changed by OH0; no unrelated semantic files found; candidate state is explicitly unaccepted | +| OH1 | PLANNED | — | — | — | — | conditional | Oracle and exact contracts only | +| OH2 | PLANNED | — | — | — | — | G1a | Retire AP-234 | +| OH3a | PLANNED | — | — | — | — | folded | Read-only canonical graph | +| OH3b | PLANNED | — | — | — | — | folded | Static membership | +| OH3c | PLANNED | — | — | — | — | folded | Dynamic/child membership | +| OH3d | PLANNED | — | — | — | — | G1b if needed | Consumer cutover/deletion | +| OH4 | PLANNED | — | — | — | — | folded into G2 | Per-leaf portal-view contract | +| OH5 | PLANNED | — | — | — | — | folded into G2 | Full landscape interleave | +| OH6 | PLANNED | — | — | — | — | G2 | Exact depth lifecycle | +| OH7 | PLANNED | — | — | — | — | folded into G3 | Retire AP-34 | +| OH8 | PLANNED | — | — | — | — | folded into G3 | Retire/narrow AP-117 | +| OH9 | PLANNED | — | — | — | — | G3 | Retire AP-232 | +| OH10 | PLANNED | — | — | — | — | n/a | Deletions and guards | +| OH11 | PLANNED | — | — | — | — | G4 | Final closeout | + +--- + +## 16. First execution actions + +When the owner says to begin execution, do exactly this: + +1. Start OH0; do not edit rendering behavior. +2. Produce the dirty-tree classification and recovery anchor. +3. Build and record the current baseline. +4. Start OH1's retail contract with the two facts most likely to invalidate + current code: + - object built-mesh behavior under `set_view`/`obj_view_set`; + - complete `portalsDrawnCount` producer/consumer/reset lifecycle. +5. In parallel only after OH0 safety is complete, prepare OH2's CellStruct + surface manifest; it is independent of frame scheduling. +6. Review the OH1/OH2 evidence before the first behavior change. +7. Implement OH2, review it, fix findings, and run G1a. + +No new cathedral visual discriminator is the first action of this campaign. diff --git a/docs/research/2026-09-01-overhaul/oh0-baseline.md b/docs/research/2026-09-01-overhaul/oh0-baseline.md new file mode 100644 index 00000000..e74e3f1c --- /dev/null +++ b/docs/research/2026-09-01-overhaul/oh0-baseline.md @@ -0,0 +1,362 @@ +# Campaign OVERHAUL OH0 baseline + +Date: 2026-09-01 +Worktree: `C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0` +Branch: `claude/campaign-w-retail-frame-walk` +Purpose: preserve and classify the exact pre-overhaul state before any OH +production behavior is changed. + +## Outcome + +OH0 found a green but heavily modified renderer state. It is recoverable, but +it is not one accepted fix. The dirty tree consists of several coherent +candidate mechanisms, diagnostic experiments, tests, and documentation. No +unrelated/user-owned semantic change was found. No dirty behavioral hunk is +repository-proven user-accepted, so this baseline deliberately calls them +**candidates** or **investigation state**. + +The accepted history anchors remain: + +- `b8befded` — accepted pre-overhaul rendering anchor named by the campaign. +- `e880860291a79e0cb20454710567d86ad8731675` — OH0 parent HEAD. + +Checkpoint `b3b7d922` (`checkpoint(render): preserve pre-overhaul +investigation state`) is the recovery anchor for the classified semantic +state. It is not a visual or retail-fidelity acceptance claim. + +## Repository state + +| Field | Value | +|---|---| +| Branch | `claude/campaign-w-retail-frame-walk` | +| Parent HEAD | `e880860291a79e0cb20454710567d86ad8731675` | +| Upstream | `origin/claude/campaign-w-retail-frame-walk` | +| Upstream relation | behind `0`, ahead `27` | +| Staged paths | `0` | +| Dirty paths before this document | `53` | +| Dirty-path composition | `45` tracked semantic/intentional diffs, `5` CRLF-normalization-only entries, `3` untracked | +| Submodule | `references/WorldBuilder` at `34460c44d7fb921afa50ee30288a53236f50f451`, clean | +| Tracked diff size | 2,945 insertions, 626 deletions across 45 semantic tracked paths | + +Five status entries have no filtered semantic diff and differ only by working +tree line endings: + +- `src/AcDream.App/Rendering/Scene/RenderProjectionRecordFactory.cs` +- `src/AcDream.App/Rendering/Scene/RenderSceneContracts.cs` +- `src/AcDream.Core/Physics/ShadowPartBox.cs` +- `src/AcDream.Core/World/MeshRef.cs` +- `src/AcDream.Core/World/WorldEntity.cs` + +`src/AcDream.App/Streaming/LandblockBuildFactory.cs` removes one blank line +only. Those six paths are excluded from the semantic checkpoint and left +untouched. + +## Complete semantic classification + +### Plan and documentation + +- `docs/plans/2026-09-01-campaign-overhaul-world-solidity.md` is the new OH + execution plan. +- `docs/plans/2026-08-30-campaign-fw-frame-walk.md` records the accepted + `b8befded` allocation closeout and links to OH. +- `docs/architecture/worldbuilder-inventory.md` mixes candidate assertions + about recipe 7, whole-mesh leaves, and reconstructed render-shadow + membership. Those statements are evidence to review, not closed truth. +- `docs/launch-options.md` documents cathedral probes, but the dirty version + omits `ACDREAM_PROBE_FACILITY_STAIRS` and the behavior-changing + `ACDREAM_PROBE_CATHEDRAL_SKIP_PUNCH`. It stays with diagnostic quarantine. + +### Prepared-content recipe 7 candidate + +This coherent candidate carries the authored DrawingBSP root sphere into +prepared GfxObj records and requires one explicit full rebuild from bake +recipe 6 to 7: + +- `src/AcDream.Content/MeshExtractor.cs` +- `src/AcDream.Content/Pak/PakFormat.cs` +- `src/AcDream.Launcher.Core/Installation/ContentMigrationCatalog.cs` +- `src/AcDream.Launcher.Core/Installation/LauncherInstallRecordStore.cs` +- `tests/AcDream.Content.Tests/MeshExtractorSolidFaceExtractionTests.cs` +- `tests/AcDream.Content.Tests/InstalledPreparedCollisionCatalogTests.cs` +- `tests/AcDream.Launcher.Core.Tests/Installation/ContentMigrationCatalogTests.cs` + +This is not yet an accepted OH mechanism. OH2/OH3 must decide which authored +bounds and graph owner retail actually uses. + +### Independent lighting-review candidate + +This group removes last-frame drawable-cell filtering and selects from every +resident light: + +- `src/AcDream.Core/Lighting/LightManager.cs` +- `src/AcDream.App/Rendering/WorldRenderFrameBuilder.cs` +- `tests/AcDream.Core.Tests/Lighting/LightManagerTests.cs` +- `tests/AcDream.App.Tests/Rendering/WorldRenderFrameBuilderTests.cs` + +It is independent of OH0 and is not acceptance-proven. The parallel retail +review found that retail separates a seven-light dynamic pool from a separate +static bake, inserts the viewer light first, and derives candidates from the +current EnvCell plus authored `VisibleCells`/`stab_list`. OH must keep this +group quarantined unless a later world-ownership slice proves a dependency. + +### Exact portal depth-state port candidate + +This atomic group replaces stencil mark/write plus bias with one +ALWAYS/write/no-stencil pass and removes the bias shader/tests: + +- `src/AcDream.App/Rendering/Gpu/GpuPipelineDescription.cs` +- `src/AcDream.App/Rendering/PortalDepthMaskRenderer.cs` +- `src/AcDream.App/Rendering/PortalDepthMaskRenderer.Rhi.cs` +- `src/AcDream.App/Rendering/Shaders/portal_depth.vert` +- `src/AcDream.App/Rendering/Shaders/spv/portal_depth.vert.spv` +- `src/AcDream.App/Rendering/Shaders/spv/shaders.manifest.json` +- deleted `tests/AcDream.App.Tests/Rendering/Issue129PunchBiasTests.cs` +- untracked `tests/AcDream.App.Tests/Rendering/PortalDepthMaskRetailStateTests.cs` + +The GPU state may match the isolated retail call, but activating it before +the exact painter interleave exists removes the accepted #117 safeguard. +Therefore this is preserved as an indivisible candidate, not accepted output. + +### Walk-owned exit-seal view candidate + +The following changes borrow planes from exact walk clip slots and stamp exit +seals per captured flood view rather than the legacy assembly/no-clip +fallback: + +- `src/AcDream.App/Rendering/ClipFrame.cs` +- portions of `src/AcDream.App/Rendering/RetailPViewPassExecutor.cs` +- portions of `src/AcDream.App/Rendering/RetailPViewRenderer.cs` +- portions of `src/AcDream.App/Rendering/Walk/WalkFrameDriver.cs` +- `tests/AcDream.App.Tests/Rendering/ClipFrameLayoutTests.cs` +- portions of `tests/AcDream.App.Tests/Rendering/Walk/WalkFrameDriverTests.cs` + +Several of those files also contain unrelated behavior and diagnostics, so +future OH work must split by hunk rather than treating the files as one owner. + +### Reconstructed static/dynamic membership candidate + +This group rebuilds static render-cell membership from visual bounds, buckets +dynamics by physics CELLARRAY, inherits equipped-child root cells, and removes +the static outdoor prune: + +- `src/AcDream.App/Composition/FrameRootComposition.cs` +- portions of `src/AcDream.App/Rendering/Walk/WalkProductionWorldData.cs` +- `src/AcDream.Core/Physics/CellTransit.cs` +- `src/AcDream.Core/Physics/ShadowObjectRegistry.cs` +- `src/AcDream.Core/Physics/ShadowShapeBuilder.cs` +- `tests/AcDream.App.Tests/Rendering/Issue177StairDescentCameraFloodTests.cs` +- `tests/AcDream.Core.Tests/Physics/CellTransitFindTransitCellsBoxTests.cs` +- portions of `tests/AcDream.App.Tests/Rendering/Walk/WalkProductionWorldDataTests.cs` + +This is explicitly reconstruction evidence rather than the intended OH3 +architecture: `WalkProductionWorldData` is a competing App-owned world model, +and the `CellTransit` prune removal also changes collision membership. The +portal-less building-shell fallback from anchor cell to landscape-position +cell is a distinct behavior inside the same production/test files and must be +reviewed separately. + +### Built-mesh, part-stamp, and shell-stamp candidate + +This group changes admitted portal-view meshes to coarse sphere admission plus +whole-mesh slot 0, adds per-part stamps and a local-player bypass, and rearms +shell/part stamps at a mid-frame boundary: + +- portions of `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.WalkClassify.cs` +- portions of `src/AcDream.App/Rendering/Walk/WalkFrameDriver.cs` +- portions of `src/AcDream.App/Rendering/RetailPViewPassExecutor.WalkLeaf.cs` +- `tests/AcDream.App.Tests/Rendering/Walk/WalkProductionWorldConformanceTests.cs` +- portions of `tests/AcDream.App.Tests/Rendering/Walk/WalkStaticStreamPopulatorTests.cs` +- portions of `tests/AcDream.App.Tests/Rendering/Walk/WalkFrameDriverTests.cs` + +This reverses the mechanism in accepted commit `11e68aad`; it is high-risk +until OH1 arbitrates retail's built-mesh versus non-built-mesh branches and +the retail oracle proves the leaf order. + +### Diagnostic-only apparatus + +- `src/AcDream.App/Rendering/Walk/WalkPView.cs` +- `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.OrderedStream.cs` +- `src/AcDream.App/Rendering/Walk/WalkStaticStreamPopulator.cs` +- untracked `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.FacilityStairProbe.cs` +- `tools/A8CellAudit/Program.cs` + +The Facility probe partial is a compile dependency of calls in the other +three App files and must travel with them. `A8CellAudit` mixes DrawingBSP +audits with cell/setup diagnostics; it remains evidence tooling. + +`src/AcDream.Core/Rendering/RenderingDiagnostics.cs` and portions of +`WalkFrameDriver`, both pass executors, `RetailPViewRenderer`, +`WalkProductionWorldData`, and `WbDrawDispatcher.WalkClassify` mix print-only +traces with hard-coded cathedral carrier suppressions and skip switches. They +are preserved only as quarantined investigation apparatus and are scheduled +for removal in OH10. + +## High-risk facts carried into OH1 + +1. No dirty behavioral change is acceptance-proven. +2. Whole-mesh slot-0 behavior reverses accepted `11e68aad`. +3. The one-pass far-Z punch removes #117's guard before exact painter + interleave is present. +4. Static membership is reconstructed from AABBs in App, matching the + duplicate-owner problem OH3 is meant to eliminate. +5. The `CellTransit` outdoor-prune change affects collision as well as render + registration. +6. Dirty architecture documentation overstates unreviewed candidates as + shipped truth. + +## Behavior-changing diagnostic flags + +The following variables were checked at Process, User, and Machine scopes. +All were absent at OH0, and every implementation tests for the exact string +`"1"` or defaults a requested cell ID to zero. Therefore no probe is enabled +in a normal launch from this environment. + +| Variable | Kind | OH0 value | +|---|---|---| +| `ACDREAM_PROBE_CATHEDRAL_SKIP_PUNCH` | suppresses punch behavior | unset | +| `ACDREAM_PROBE_CATHEDRAL_SKIP_SEALS` | suppresses exit seals | unset | +| `ACDREAM_PROBE_CATHEDRAL_SKIP_CELL_SHELLS` | suppresses cell shells | unset | +| `ACDREAM_PROBE_CATHEDRAL_SKIP_SOUTH_LOOKIN_SHELLS` | scene-specific shell suppression | unset | +| `ACDREAM_PROBE_CATHEDRAL_SKIP_LOOKIN_SHELL` | requested-cell shell suppression | unset | +| `ACDREAM_PROBE_CATHEDRAL_SKIP_SOUTH_BUILDING_SHELL` | scene-specific building suppression | unset | +| `ACDREAM_PROBE_CATHEDRAL_SHELL_ORDER` | print-only shell-order trace | unset | + +Additional Facility trace variables are diagnostic output controls. They do +not alter the accepted draw path, but they remain quarantined with the +behavior probes until OH10 cleanup. + +## Build and focused automated baseline + +All commands ran from the binding worktree against the uncommitted state +classified above. + +| Gate | Result | +|---|---| +| `dotnet build AcDream.slnx -c Release --nologo` | PASS — 0 warnings, 0 errors, 23.29 s | +| App walk/depth/frame focused filter | PASS — 272 passed, 1 skipped, 0 failed | +| Content geometry focused filter | PASS — 12 passed, 0 skipped, 0 failed | +| Core membership/light focused filter | PASS — 33 passed, 0 skipped, 0 failed | +| Launcher migration focused filter | PASS — 2 passed, 0 skipped, 0 failed | + +The App filter included `Rendering.Walk`, `PortalDepthMask`, +`Issue177StairDescentCameraFloodTests`, `ClipFrameLayoutTests`, and +`WorldRenderFrameBuilderTests`. Green tests prove the current candidates are +internally consistent; they do not prove retail parity or visual acceptance. + +## Installed source and prepared-package identity + +Source directory: `C:\Users\erikn\Documents\Asheron's Call` + +| Artifact | Bytes | SHA-256 | +|---|---:|---| +| `client_portal.dat` | 926,941,184 | `DC6E500BA22E6B186DB7171E3F3345238B6444C85D798ADC85E550973B8D12E4` | +| `client_cell_1.dat` | 348,127,232 | `6DB0ABF00FBCEED62C3F1EE842EE7C1F423D732BED77A5B7C102EE89A52AB99E` | +| `client_highres.dat` | 133,169,152 | `503E0828D14F2F9CCBC31431E1055AC188464BF4B499DE37F4C3D5B2D9F3E727` | +| `client_local_English.dat` | 1,048,576 | `E85C820280C88FAC7DF6C8043F5E24596E9C8774193AF4123D756546F78FB2BB` | +| `acdream.pak` | 597,144,496 | `0AD2A24C00579FC40E93E5C73FF800FCE587665D831AACD11DEACBCC59A84D6D` | +| `acdream.recipe6.pak` | 597,229,424 | `37BC0EA1778F899AF9E3B2397937D373F69D615B15D3E32041BF389D93B624BF` | + +Active `acdream.pak` header: + +| Field | Value | +|---|---:| +| Magic | `0x4B504341` | +| Format | `2` | +| Portal iteration | `2072` | +| Cell iteration | `982` | +| HighRes iteration | `497` | +| Language iteration | `994` | +| TOC offset | `543435712` | +| TOC count | `2237866` | +| Bake tool version | `7` | + +Compiled shader manifest SHA-256: +`65AE59DA995B9FBAA997F50A12B07FEEBB6CDA4121C881C5921BFF9ACE752CCF`. + +## Pre-overhaul file hash manifest + +These hashes capture every status path before OH0 added this document. A +deleted path is represented by the parent commit plus the explicit deletion. + +| Path | Status | Bytes | SHA-256 | +|---|---|---:|---| +| `docs/architecture/worldbuilder-inventory.md` | ` M` | 40809 | `275EACBB7AF5C6837558DE95ED0C973038E83E89A2EA1B4B10FCCD11AAC7378B` | +| `docs/launch-options.md` | ` M` | 89617 | `1DEF166EF74A82A9FF4151FF3AB95A46DB03F951BDE44CBCF0415F3D06DE85ED` | +| `docs/plans/2026-08-30-campaign-fw-frame-walk.md` | ` M` | 43730 | `988DACAC01E2367DBBCFD49DC1F146E8EDE2CE96892BCB9C25874D6A752B50F6` | +| `src/AcDream.App/Composition/FrameRootComposition.cs` | ` M` | 40619 | `55BB45148909191BBF4B5EDACAB6273330BCD2AE37B60F4370426A3C14138146` | +| `src/AcDream.App/Rendering/ClipFrame.cs` | ` M` | 14769 | `EA3C52E7FCFA51E4F9C21CDC33D89215F9E9768332DD88E831265E738E06BB01` | +| `src/AcDream.App/Rendering/Gpu/GpuPipelineDescription.cs` | ` M` | 16982 | `108661215FE9DFF414ABFDB050985C3A0946A38EFA509ABB2A93443F8CB06A30` | +| `src/AcDream.App/Rendering/PortalDepthMaskRenderer.Rhi.cs` | ` M` | 8820 | `93B559C8D30773ABB9E7DCA0884A0E6A37A9E16BA9AE13FDA1D4354E68D91022` | +| `src/AcDream.App/Rendering/PortalDepthMaskRenderer.cs` | ` M` | 5070 | `D9C8D245C5CC7CFC96762AAEA28F7D74B3F1B0CFF7C7BA661C5FEF8806CBC62D` | +| `src/AcDream.App/Rendering/RetailPViewPassExecutor.WalkLeaf.cs` | ` M` | 12773 | `81DE87E5687DD79901DC72714BBF21FE5295AEE1E0A4093BCF5A3B91AAAA95DB` | +| `src/AcDream.App/Rendering/RetailPViewPassExecutor.cs` | ` M` | 19048 | `91B688E4ADE207FF016441979537B71C0B4AE6D5C4BF055EC0E0B0E6A6961CCA` | +| `src/AcDream.App/Rendering/RetailPViewRenderer.cs` | ` M` | 41456 | `30193DE518BF3BF1312AC2E1A34CA9AF76FF38E0B9A0E848F15A6628C2A95920` | +| `src/AcDream.App/Rendering/Scene/RenderProjectionRecordFactory.cs` | ` M` | 5342 | `A0C28300F80528BBD63FF034139DB7E353146B27E5782AEAFAF882AA244DD880` | +| `src/AcDream.App/Rendering/Scene/RenderSceneContracts.cs` | ` M` | 21927 | `2D043913905BB45F1E3E24290CEDA96678AAF6EEE89FED17FA8586DFBAA27D8A` | +| `src/AcDream.App/Rendering/Shaders/portal_depth.vert` | ` M` | 2632 | `004B91F8891EF63C3E9051E098F7FD5251537A8FB756FE647C22F5A729561EAE` | +| `src/AcDream.App/Rendering/Shaders/spv/portal_depth.vert.spv` | ` M` | 1900 | `4AC1C452E7AC0D08A32F67FB03F21229AF2D1605BAA81F407240A3626251DFD7` | +| `src/AcDream.App/Rendering/Shaders/spv/shaders.manifest.json` | ` M` | 11066 | `65AE59DA995B9FBAA997F50A12B07FEEBB6CDA4121C881C5921BFF9ACE752CCF` | +| `src/AcDream.App/Rendering/Walk/WalkFrameDriver.cs` | ` M` | 80236 | `9E82A07B0CA77947657221566625ABB6305E476D3EA436E95F8F5006AD6C6F3C` | +| `src/AcDream.App/Rendering/Walk/WalkPView.cs` | ` M` | 26293 | `565FC89767A6910EAB4E81785EB5CCF1D2F272FA37FD77BDB885F9D8135446B7` | +| `src/AcDream.App/Rendering/Walk/WalkProductionWorldData.cs` | ` M` | 34723 | `86F2A43657E884BAE32D166A5C70084559C6D6A900810FD0DD2C76F1D7AC4CF1` | +| `src/AcDream.App/Rendering/Walk/WalkStaticStreamPopulator.cs` | ` M` | 8896 | `FEA240901A82FCBE6B9B2DAED19DCDC985BF460E771F7820D8601F1136043F82` | +| `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.OrderedStream.cs` | ` M` | 31069 | `355FE62DBAA8988E69BD2A468DE44D7A5AE799D0E0649559C885900C7F6F0824` | +| `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.WalkClassify.cs` | ` M` | 41357 | `13A669521266D49396A8C8F3D34DA2064EDBE2BD0613F5112C0D4BCCDE404D87` | +| `src/AcDream.App/Rendering/WorldRenderFrameBuilder.cs` | ` M` | 27021 | `A34C66BEBFF07538EC55BCC65454BEC61811FB5F7E724C749D8351A25741E585` | +| `src/AcDream.App/Streaming/LandblockBuildFactory.cs` | ` M` | 37350 | `8BDDB5A07C32BB083475836A8C3F782F980E30E2D532F214A8A9AA5E80735C48` | +| `src/AcDream.Content/MeshExtractor.cs` | ` M` | 72211 | `5453D06062416A2B04FFC900715C76BDA3E22CD36B68F30514D28FA5E0364C99` | +| `src/AcDream.Content/Pak/PakFormat.cs` | ` M` | 8334 | `F260AB6742A576DDB84AF11A75089AD7645C9CF180456B341C9ECA6B07489757` | +| `src/AcDream.Core/Lighting/LightManager.cs` | ` M` | 29182 | `F58998E7AAE1CC7C2E4D0E8EA76F23E3CBFCE9CE71B55104BD7D6671DCA60A26` | +| `src/AcDream.Core/Physics/CellTransit.cs` | ` M` | 76728 | `74A4DE885A309AA5060DB130B0C13706C93A8B1A51C4C0675D91A777EA85ED91` | +| `src/AcDream.Core/Physics/ShadowObjectRegistry.cs` | ` M` | 115614 | `D297D2CE83EF2341A438E2F697C63A0C27A1C6E4FAE62E18A904D9CB88CA57E7` | +| `src/AcDream.Core/Physics/ShadowPartBox.cs` | ` M` | 8694 | `49F7A142CE8A1AE5EEBCB33E31B81421F84539D2CAD212D75ED5E36829190DF3` | +| `src/AcDream.Core/Physics/ShadowShapeBuilder.cs` | ` M` | 23478 | `9FA4EE057C09B0BF0BBEFA618F1A9768F22A7EE99FF55596B334E32C55EA966F` | +| `src/AcDream.Core/Rendering/RenderingDiagnostics.cs` | ` M` | 37557 | `9A251F8785F7F4256E5D30408178A7B4365B240FF01196E0F3E62C22AC76EAE5` | +| `src/AcDream.Core/World/MeshRef.cs` | ` M` | 1778 | `9349926D73AEDC97A95726FAC154B84FC6D4EBF2DB6DD64BE50014291428A221` | +| `src/AcDream.Core/World/WorldEntity.cs` | ` M` | 14597 | `81922AAA930B336ECC4167B7B342D9B65336EEB39ECBF61C1607ED530423CF57` | +| `src/AcDream.Launcher.Core/Installation/ContentMigrationCatalog.cs` | ` M` | 4883 | `5C2CC4B1D6BF3BD6D3BE837E405E969C27235EC3845A449D97C50784E9AB21F4` | +| `src/AcDream.Launcher.Core/Installation/LauncherInstallRecordStore.cs` | ` M` | 24440 | `787360E3D426DE24BB1CFE00CD6FBC69B9AFD86E18E161412EEBFB14861C6990` | +| `tests/AcDream.App.Tests/Rendering/ClipFrameLayoutTests.cs` | ` M` | 8033 | `9C340D45BB703D1107B34C9BE40162D9E6C69C209E326DEA3744C2F870C2B040` | +| `tests/AcDream.App.Tests/Rendering/Issue129PunchBiasTests.cs` | ` D` | deleted | n/a | +| `tests/AcDream.App.Tests/Rendering/Issue177StairDescentCameraFloodTests.cs` | ` M` | 36493 | `21AC79E23320F73E377368AB63D2701E05C31708223AFF29D9DCF2C504A99EB9` | +| `tests/AcDream.App.Tests/Rendering/Walk/WalkFrameDriverTests.cs` | ` M` | 55621 | `A68994C420D5F1099C5F86D9FDB2F194B5665A39874179B137CD6AA8504903FF` | +| `tests/AcDream.App.Tests/Rendering/Walk/WalkProductionWorldConformanceTests.cs` | ` M` | 19850 | `F73CC8F494E568133E1C1354D52EE85252C575B26C98948F65BAF5FF522CA57C` | +| `tests/AcDream.App.Tests/Rendering/Walk/WalkProductionWorldDataTests.cs` | ` M` | 9231 | `1FA6B591865C551619FC392F3B8FCD710299094529A8109355484EA3271A5457` | +| `tests/AcDream.App.Tests/Rendering/Walk/WalkStaticStreamPopulatorTests.cs` | ` M` | 36223 | `4A08C37591C1F65A1142B6F8D9361EA2BC70FBE7C77519F17F758418694DF01B` | +| `tests/AcDream.App.Tests/Rendering/WorldRenderFrameBuilderTests.cs` | ` M` | 22735 | `450BF823EAD6D825CDA3AD584634C704F721564F139C08B5EEB96A2228965ED7` | +| `tests/AcDream.Content.Tests/InstalledPreparedCollisionCatalogTests.cs` | ` M` | 4208 | `0549B7C75651B4E3DF1469ED5B451DDA16B71710950A1EC252052419E3723903` | +| `tests/AcDream.Content.Tests/MeshExtractorSolidFaceExtractionTests.cs` | ` M` | 20309 | `48D45135ACED92EFA57982E432CECE7B9ADE6AA50E1B12F0E36DFF347E2EDC35` | +| `tests/AcDream.Core.Tests/Lighting/LightManagerTests.cs` | ` M` | 26623 | `DB009E9DE99AA471C1C8425C3056ED02DEB606B54109A2E76761C5F5A684BD24` | +| `tests/AcDream.Core.Tests/Physics/CellTransitFindTransitCellsBoxTests.cs` | ` M` | 25854 | `09D32BDC9C3AE6F6235D32C560AEE3CA93734AB1D92597D4BD067E84AB5A86DD` | +| `tests/AcDream.Launcher.Core.Tests/Installation/ContentMigrationCatalogTests.cs` | ` M` | 1112 | `69D38F40488702EBD2A6AB87A2B72D992CB07819A9125F13FEEEA31385D34964` | +| `tools/A8CellAudit/Program.cs` | ` M` | 39282 | `D453EFBB7F1D70A3A7D866EDD7AEB166AEA00506AAAD4DB290A431A0BD13CC02` | +| `docs/plans/2026-09-01-campaign-overhaul-world-solidity.md` | `??` | 66337 | `EDFB74CB3600B2DFE00FA789636674A1553C183FFA113115B16D72195B0CDB6D` | +| `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.FacilityStairProbe.cs` | `??` | 6536 | `5D12468429869A07606B3FB9AFE258C4007F85AFB3481C16D0F4882984A29552` | +| `tests/AcDream.App.Tests/Rendering/PortalDepthMaskRetailStateTests.cs` | `??` | 2537 | `2175E30A42F856DD9AE77C8308120386633A0357654F37E56B0DB7E106DD0C9A` | + +## Recovery procedure + +1. Never use `reset --hard`, `checkout --`, or `clean` against this worktree. +2. To inspect the historical accepted state, use detached/read-only inspection + of `b8befded` or `e880860291a79e0cb20454710567d86ad8731675` in a separate + worktree; do not overwrite this checkout. +3. To restore the complete pre-overhaul investigation state, revert later OH + commits in reverse order, stopping at checkpoint `b3b7d922`. +4. To undo the checkpoint itself while retaining history, use + `git revert b3b7d922`; do not rewrite history. +5. The six excluded normalization/blank-line paths may remain dirty. Compare + them with `git diff --ignore-space-at-eol -- ` before treating them as + content. +6. Validate any restored state with the DAT/package/shader identities above, + then rerun the Release build and the four focused gate groups. + +## OH0 review disposition + +- Every pre-existing status path is accounted for. +- Both required history anchors are recorded. +- No behavior probe is silently enabled by its default or current + environment. +- No unrelated/user-owned semantic change was found. +- Production behavior was not edited during OH0. +- The classified state is safe to preserve as an explicitly unaccepted + recovery checkpoint.