699 lines
40 KiB
Markdown
699 lines
40 KiB
Markdown
# Campaign OVERHAUL — retail world construction and render solidity
|
||
|
||
**Status:** ACTIVE — **v2 rescope 2026-09-02.** Five production slices replace
|
||
the twelve-stage v1 plan. S1 is the current slice. See §13 for the ledger and
|
||
§15 for what v2 changed and why.
|
||
|
||
**Campaign code:** `OH`.
|
||
|
||
**Worktree (binding):**
|
||
`C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-blackburn-5333f0`
|
||
|
||
**Branch (binding):** `claude/campaign-w-retail-frame-walk`. This is the
|
||
long-lived renderer integration branch. It carries all of Campaign FW (101
|
||
commits over `origin/main` at `e102fb36`). **Nothing merges to `main` until
|
||
the final gate passes**; `origin/main` is merged INTO this branch at every
|
||
slice boundary so it never drifts.
|
||
|
||
**v2 base:** `5d907ae9` (`docs(render): define OH1 retail world contract`),
|
||
tree clean. The uncommitted OH1/T3 evidence grammar (~32K lines) is parked
|
||
verbatim on `quarantine/oh1-evidence-grammar-2026-09-02` (see its
|
||
`QUARANTINE-README.md`). Do not merge that branch.
|
||
|
||
**Recovery anchors:** `b3b7d922` is the checkpoint that committed the
|
||
pre-overhaul investigation candidates, including the Facility Hub stair fix
|
||
(recipe 7 authored drawing sphere, static render-shadow membership, per-part
|
||
stamps). `b8befded` is the user-gated FW closeout. Both are history, not
|
||
permission to discard later work. No history rewrite, ever.
|
||
|
||
**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 replaced the legacy visibility product with a retail-derived frame
|
||
walk and fixed several defects. It did not make the world pipeline
|
||
retail-identical. The client still reconstructs relationships 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 in an App-owned model
|
||
that competes with the physics registry;
|
||
- 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 unconditional although retail latches it on the
|
||
previous frame's `portalsDrawnCount`;
|
||
- CellStruct face selection uses the AP-234 `NoPos` proxy rather than the
|
||
surface-type decision retail makes;
|
||
- some accepted object parts are duplicated through Vulkan clip slots without
|
||
proof that retail clips them.
|
||
|
||
These explain why local fixes oscillate between opposite failure modes. The
|
||
precedent is physics: incremental collision patching never converged; the
|
||
faithful retail port did. The renderer gets the same treatment.
|
||
|
||
Owner-observed symptom family: cathedral walls/wall-textured triangles over
|
||
floating stairs; stair slabs appearing/disappearing by camera angle; the
|
||
cathedral exterior ramp absent; textures bleeding through opaque surfaces; the
|
||
local character chopped at cathedral and Facility Hub seams; remote actors and
|
||
particles through walls; waterfalls vanishing by angle; outdoor groups
|
||
disappearing after small turns; landscape draw-range regressions; spell
|
||
effects lingering.
|
||
|
||
---
|
||
|
||
## 2. Definition of success
|
||
|
||
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's captured transcript for the same
|
||
root and camera pose at the depth the capture records: landscape/building
|
||
order, portal views, cell order, object-list turns, shell/part draws,
|
||
depth events, alpha inserts and flushes.
|
||
4. Every leaf category has a proven retail contract: EnvCell shell, building
|
||
shell, landblock static, indoor static, dynamic object, particle, terrain,
|
||
punch, seal, transparent subset.
|
||
5. Vulkan receives an ordered list of already-decided retail draw operations.
|
||
It may batch adjacent compatible work; it decides nothing.
|
||
6. No scene-specific suppression, shell lift, bias, fallback flood, corrective
|
||
redraw, or behavior-changing diagnostic flag remains in production.
|
||
7. The owner acceptance matrix (§10) passes.
|
||
8. The complete Release suite, installed-DAT lane, connected lifecycle route,
|
||
R6 route, and performance checkpoint pass on the exact gated binary.
|
||
9. Architecture, inventory, divergence register, launch options, memory, and
|
||
milestone ledgers describe the code that ships.
|
||
|
||
"Looks fixed at one camera angle" is never a completion condition.
|
||
|
||
---
|
||
|
||
## 3. Scope and non-goals
|
||
|
||
**In scope:** CellStruct/EnvCell geometry construction; the canonical
|
||
cell/building/portal/part-membership graph; static and dynamic cross-cell
|
||
render membership; retail `PView` view ownership and leaf contracts; landscape,
|
||
building, cell-shell, object, particle, depth, and alpha ordering; portal punch
|
||
and exit-seal lifecycle; retail landscape `in_view` and its particle/light/
|
||
shadow consumers; material behavior needed for solid composition (AP-232
|
||
residual); minimal per-slice instrumentation; deletion of superseded
|
||
reconstruction and diagnostic apparatus; docs and regression coverage.
|
||
|
||
**Out of scope:** replacing Vulkan; recreating C++ pointer layouts; changing
|
||
streaming strategy, budgets, reveal radii, the mmap package model, or GPU
|
||
resource lifetime except the S1 recipe bump; increasing draw distance; a
|
||
lighting redesign; physics not required for exact membership; new graphics
|
||
features; removing the user-requested Extended particle-range option.
|
||
|
||
---
|
||
|
||
## 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. **A slice ships a production behavior change or it is not a slice.**
|
||
Evidence tooling is built inside the slice that consumes it, to the depth
|
||
that slice needs, never as its own stage.
|
||
3. **Evidence before code, contract already written.** The OH1 research
|
||
contracts (§6) and the retail capture (§7) are the evidence. No slice
|
||
starts from a screenshot theory; no slice builds a new evidence language.
|
||
4. **Named retail first; Ghidra arbitrates branch sense.** Any condition whose
|
||
polarity affects admission, clipping, depth, ordering, or lifetime is
|
||
cross-checked in Ghidra (`patchmem`, port 8081) before implementation.
|
||
5. **DAT identity is exact.** A trace reaches owner → Setup → part → GfxObj →
|
||
polygon/surface before assigning a visual carrier. Aggregate owner IDs do
|
||
not identify content.
|
||
6. **No symptom-site fixes.** Cell/building/GfxObj IDs and camera poses are
|
||
for diagnosis only.
|
||
7. **No silent drop.** Every rejected cell/view/part/mesh has a diagnostic
|
||
reason available during a slice; production diagnostics are removed or made
|
||
print-only at slice close.
|
||
8. **No competing production owner.** A cutover slice deletes the route it
|
||
replaces within the slice.
|
||
9. **Whole-mechanism fixes.** Never patch a downstream draw when retail owns the
|
||
decision upstream.
|
||
10. **Build before launch; exact binary for gates.** Commit hash, package
|
||
recipe, flags, and log path are recorded before every owner gate.
|
||
11. **Client process safety.** Never kill the client.
|
||
12. **Preserve unrelated work.** No `reset --hard`, `checkout --`, `clean`, or
|
||
bare `stash`. Rollback is a normal revert of a named commit.
|
||
13. **Register discipline.** Deviations filed/retired in the same commit.
|
||
14. **Docs are tested truth.** Architecture text and code agree at slice close.
|
||
15. **Time-box.** A chunk that needs a third fix round stops and goes to the
|
||
user with its evidence. No agent decides it needs more infrastructure.
|
||
|
||
---
|
||
|
||
## 5. Working model
|
||
|
||
The v1 failure was one agent given the whole campaign for eighteen hours. v2
|
||
keeps the lead in the loop at every chunk.
|
||
|
||
| Role | Who | Does | Never |
|
||
|---|---|---|---|
|
||
| Lead / architect | the main session (Fable) | writes each chunk contract (files, retail functions + addresses, acceptance tests); dispatches one bounded chunk; verifies every claim against source; runs gates; commits; merges main in at slice boundaries | hands off "complete the slice" |
|
||
| Implementer | Sonnet, one dispatch per chunk | one file cluster + its tests; build and test green is the return condition; returns a diff summary and open questions | commits; adds evidence infrastructure; starts a third fix round; touches files outside its contract |
|
||
| Retail reviewer | Opus, one pass per slice on the production port | checks each ported branch against the named decomp with addresses; findings as file:line + decomp citation | reviews tooling |
|
||
| Architecture reviewer | Opus, only at the two cutover slices (S2, S5) | one owner per fact; layering; lifetime; performance shape | |
|
||
| Finding verification | the lead, against the source | each reviewer finding is checked by the lead against the decomp/contract/code before it is acted on; at most one Opus skeptic, and only for a blocking finding the lead cannot settle | spawns a skeptic per finding (the S1 review fanned out to ~30 agents this way on 2026-09-02; never again) |
|
||
|
||
**Agent budget per slice:** implementers as needed (one per chunk, serial for
|
||
coupled files); reviewers two (retail lens, and the architecture lens only at
|
||
S2/S5); skeptics at most one per blocking finding. Anything that would spawn
|
||
more than five agents in one step is wrong and stops.
|
||
|
||
Chunk contracts state explicit stop conditions: build red after two attempts →
|
||
return; contract ambiguity → return with the question; any need for a third
|
||
round → return. Coupled files go to one agent serially against a pinned
|
||
contract; only genuinely independent chunks run in parallel worktrees.
|
||
Agents write incremental output to disk; a silent agent is stopped and
|
||
inspected, not waited on.
|
||
|
||
---
|
||
|
||
## 6. Evidence hierarchy and products
|
||
|
||
When sources disagree, in this order:
|
||
|
||
1. Live retail binary behavior captured at named functions (§7).
|
||
2. Named retail PDB/header identity and Ghidra-arbitrated decompilation.
|
||
3. Byte-exact installed DAT structure and geometry.
|
||
4. Existing FW0 cdb traces in `docs/research/2026-08-30-fw-walk-oracle/`.
|
||
5. Deterministic acdream replay of the same input.
|
||
6. Render/API captures.
|
||
7. acdream diagnostic logs.
|
||
8. Visual observation — to discover symptoms and accept final pixels, never to
|
||
infer identity or branch logic.
|
||
|
||
**Research contracts already written (committed at `5d907ae9`, binding):**
|
||
`oh1-retail-world-contract.md`, `oh1-construction-landscape-contract.md`,
|
||
`oh1-built-mesh-view-contract.md`, `oh1-alpha-list-contract.md`,
|
||
`oh1-depth-lifecycle.md`, `oh2-cellstruct-surface-contract.md`, and the
|
||
corrected `2026-08-30-fw-flood-pseudocode-appendix.md`. The retail facts the
|
||
v1 T3 reviews established are carried in
|
||
`2026-09-02-campaign-overhaul-handoff.md` §5.3 and are binding inputs to S3/S4.
|
||
|
||
**Evidence products, minimal by design:**
|
||
|
||
| Product | Form | Used by |
|
||
|---|---|---|
|
||
| Geometry conformance | installed-DAT scans + synthetic fixtures + a two-run SHA-256 over the emitted CellStruct subset records | S1 |
|
||
| Membership conformance | typed expected cell lists per fixture object + installed-DAT comparator between the canonical graph and the old builders (comparator lives and dies inside S2) | S2 |
|
||
| Frame transcript | the FW0 line format (`F/P/LS/BLD/DI/DC`) extended with the OH line kinds the capture scripts emit; parsed by the existing test-side `WalkOracleTrace` parser, extended in place; acdream emits the same lines behind ONE print-only flag inside the slice that needs it | S3, S4 |
|
||
| Framebuffer equivalence | offscreen fixture renders compared to the retail formula | S5 |
|
||
|
||
Pointer values, Vulkan handles, and allocation addresses are excluded from
|
||
equality. No canonical JSONL, no semantic validator: structure is checked in
|
||
the parser, semantics in the port and in the compare against retail.
|
||
|
||
---
|
||
|
||
## 7. Retail capture session (owner action, before S3)
|
||
|
||
The one owner action in the campaign apart from gates. Scripts live in
|
||
`tools/walk-oracle/oh/` (recon, three capture templates, runner, README).
|
||
|
||
| Pose | Root | Why |
|
||
|---|---|---|
|
||
| holtburg-doorway-still | interior `a9b4013f` | the flap scene; three consecutive look-in punches of one cell |
|
||
| terrace-edge | outdoor | the #456 pose; far building drawn and depth-covered |
|
||
| cathedral-arrival | interior `f4180106` | interior root, landscape through the exit view, culled roster |
|
||
| foundry-deep | interior `a9b40176` | deep chain with `ov=1`; landscape and 12 buildings drawn from the basement |
|
||
|
||
Per pose, three short attaches in order, each auto-detaching after its frame
|
||
budget: **walk** (cell granularity: FW0 lines plus `DrawEnvCell` and object-cell
|
||
turns, 5 frames), **parts** (`CPhysicsPart::Draw` candidates and
|
||
`DrawMeshInternal` actual draws with GfxObj ids, 3 frames), **alpha/depth**
|
||
(`AddMeshToAlphaList`, `FlushAlphaList` with site, depth-clear latch and
|
||
`portalsDrawnCount`, 5 frames). Still poses repeat bit-for-bit per frame
|
||
(FW0 finding 6), so few frames suffice and the ACE-timeout risk from
|
||
per-hit `.printf` stays bounded. Budget: one hour.
|
||
|
||
Procedure: recon attach first (no breakpoints; `dt`/`x` dumps verify every
|
||
offset the templates assume); PDB pairing check before every attach; `qd` only
|
||
at top level after the terminal-hit fall-through. Logs land in
|
||
`docs/research/<date>-oh-walk-oracle/` and become S3/S4 fixtures.
|
||
|
||
If a static fact is later found unrecoverable from these captures, request one
|
||
more exact capture with pose, action, duration, and expected trace. Never an
|
||
open-ended "run around and report".
|
||
|
||
---
|
||
|
||
## 8. Target architecture (unchanged from v1)
|
||
|
||
```text
|
||
DAT + prepared package
|
||
└─ S1 CellStruct subset construction (surface-index owned, recipe 8)
|
||
World-cell graph (generation-scoped, S2)
|
||
├─ portal topology, building ownership, drawable cell identity
|
||
├─ static part-shadow membership (init_static_objects/AddPartsShadow)
|
||
└─ dynamic/child membership (add_shadows_to_cells, one transaction)
|
||
Frame walk (per frame, S3)
|
||
├─ LScape::draw order → DrawBuilding sequence → look-ins
|
||
├─ PView views/todo/draw-list/stamps → DrawCells two-pass
|
||
└─ leaf admission per category (whole-once / Boolean sphere / real clip)
|
||
Depth + alpha (S4)
|
||
├─ portalsDrawnCount latch, conditional clear, punches, seals, mid-frame stamp
|
||
└─ retail alpha lists, per-cell insertion, FIFO flush sites, 0.75 valve
|
||
Consumers (S5)
|
||
└─ landcell in_view → particles/lights/shadows; material/degrade policy
|
||
Vulkan encoder: ordered immutable stream; merges adjacent compatible runs only
|
||
```
|
||
|
||
Required properties: render and physics adapters never mutate canonical
|
||
topology/membership; dynamic updates replace one object's membership
|
||
transactionally with exact incarnation identity; children inherit the root's
|
||
`CELLARRAY` by one rule; the walk owns per-frame views/todo/draw lists/stamps/
|
||
latches and never persists them in projections; the encoder cannot enlarge the
|
||
visible set or reorder across a semantic boundary.
|
||
|
||
---
|
||
|
||
## 9. The five slices
|
||
|
||
Each slice: plan packet (already written or one short note) → implementation
|
||
in bounded chunks → retail review (+ architecture review at S2/S5) → fix →
|
||
automated gate → owner gate where listed → ledger update → merge `origin/main`
|
||
in.
|
||
|
||
### S1 — Geometry: exact CellStruct construction (was OH2)
|
||
|
||
**Spec:** `oh2-cellstruct-surface-contract.md`, sections 3, 8, 9, 10, 12 are
|
||
the implementation contract verbatim. Retail anchors: `CEnvCell::UnPack`
|
||
`0x0052D470`, `CPolygon::UnPack` `0x00538650`, `copyVert` `0x0059C080`,
|
||
`D3DPolyRender::ConstructMesh` `0x0059DFA0`, `D3DPolyRender::DrawMesh`
|
||
`0x0059D4A0`, `RenderDeviceD3D::DrawEnvCell` `0x0059F170`.
|
||
|
||
**Behavior change:** side candidates come only from `sides_type`; `NoPos`/
|
||
`NoNeg` mean UV absence only; subsets are owned and ordered by source surface
|
||
index; built-EnvCell admission is `(Surface.Type & 6) != 0` after surface
|
||
resolution; authored `sides_type` is not GPU cull. AP-234 retired.
|
||
|
||
**Chunks:**
|
||
1. Core side-candidate descriptor (pure, allocation-free) + `MeshExtractor.
|
||
PrepareCellStructMeshData` rewrite against it + §10.1/§10.2 tests.
|
||
2. Prepared subset record fields (source surface index, raw type, retail mask,
|
||
fixed cell-shell cull) + `ObjectMeshDataSerializer` round-trip +
|
||
`PakFormat.CurrentBakeToolVersion = 8`, launcher recipe 8, `7 → 8`
|
||
FullRebuild step + §10.5 tests. Container format stays 2, with a test
|
||
saying so.
|
||
3. `CellMesh.Build` routed through the same descriptor or its render role
|
||
deleted; full installed-DAT scan with every admission delta explained by
|
||
`Surface.Type & 6`; two-run deterministic hash; §10.3 canonical pins
|
||
(`0xF4180104`: eight `ST_DOUBLE` clip-map polygons, 44 drawable side
|
||
calls); AP-234 row deleted with addresses; inventory/architecture text.
|
||
|
||
**Review:** retail lens on the descriptor, mask, winding, and admission; data
|
||
lens that no ordinary-GfxObj rule leaked into cells or vice versa; Surface
|
||
lookup stays in Content/bake.
|
||
|
||
**Automated gate:** Content, Bake, Core, Launcher.Core, focused App suites
|
||
green in Release; installed-DAT scan reports zero unexplained deltas; full
|
||
solution build green; no per-frame allocation or DAT lookup added.
|
||
|
||
**Package:** rebuild the dev pak (`Documents\Asheron's Call\acdream.pak`) to
|
||
recipe 8 through the supported bake flow; keep the recipe-7 file beside it as
|
||
`acdream.recipe7.pak`. Note the launcher-installed pak under
|
||
`%LOCALAPPDATA%\acdream\pak` is still recipe 6; it is not the gate binary's
|
||
pak.
|
||
|
||
**Owner gate G1 — geometry integrity.** One exact build: cathedral exterior
|
||
ramp and every floating stair slab; cathedral walls at the `0x104/0106` and
|
||
`0x107/0112` seams; Facility Hub bottom/top stairs and doorway walls; two
|
||
ordinary dungeons with solid-color and textured surfaces; Holtburg/Nanto
|
||
shells. Pass = no missing/new wall faces, no invisible ramp/slab, no gross
|
||
material substitution. Camera-dependent occlusion is not adjudicated here.
|
||
|
||
**Rollback:** revert the S1 behavior/schema commits; restore
|
||
`acdream.recipe7.pak`.
|
||
|
||
### S2 — World graph: one membership owner (was OH3)
|
||
|
||
**Spec:** `oh1-construction-landscape-contract.md` §construction/ownership;
|
||
retail: `CEnvCell::init_static_objects`, `CPhysicsObj::calc_cross_cells_static`,
|
||
`CPartArray::AddPartsShadow`, `CPhysicsObj::add_shadows_to_cells`,
|
||
`find_bbox_cell_list`, child-list propagation and removal counterparts.
|
||
Starting point: the `b3b7d922` candidates (`WalkProductionWorldData` render
|
||
index, `ShadowShapeBuilder.FromStaticRenderParts`,
|
||
`ShadowObjectRegistry.ComputeStaticRenderCells`, the Facility stair pin
|
||
`FacilityStairAssembly_RegisterAcross015FTo015EWithoutCollisionRows`). They
|
||
use retail's mechanism in the wrong owner; S2 moves them, it does not delete
|
||
the mechanism.
|
||
|
||
**Behavior change:** one generation-scoped `WorldCellGraphSnapshot` owns
|
||
portal topology, building ownership, drawable cell identity, and typed
|
||
per-part render-shadow plus object-level physics `CELLARRAY` outputs from one
|
||
registration transaction. Every consumer borrows it; the App-owned render
|
||
index, visual-AABB fallbacks, origin-cell fallbacks, and duplicate cell buckets
|
||
are deleted.
|
||
|
||
**Chunks:**
|
||
1. Read-only graph snapshot beside existing owners from the same accepted
|
||
publication; equality test against source publication; zero pixel change.
|
||
2. Static `AddPartsShadow` parity: ordered membership vector per visual part;
|
||
old index retained as comparator only inside this chunk; cut render lookup
|
||
after the installed-DAT comparator is zero-mismatch. Fixtures: cathedral
|
||
ramp/stairs/walls, Facility stairs, a 24 m cell-edge crosser, a
|
||
landblock-edge object, a non-colliding decoration, a multi-part Setup whose
|
||
parts cross different cells.
|
||
3. Dynamic/child parity: `add_shadows_to_cells`, removal, movement update,
|
||
child inheritance as one transaction keyed by exact incarnation. Fixtures:
|
||
local/remote player, NPC, projectile, spell world object, equipped child,
|
||
contained child, indoor portal crossing, outdoor crossing, teardown/
|
||
reconnect.
|
||
4. Consumer cutover in order: indoor static render lookup, outdoor static
|
||
render lookup, dynamic render lookup, physics broadphase projection,
|
||
particle owner-cell lookup, point-light owner-cell lookup, directional-shadow
|
||
reachability. Delete the superseded builders.
|
||
|
||
**Review:** architecture (one authority; retry/recenter/reset safe; no
|
||
per-frame rebuild) and retail (crossed cells and insertion order match the
|
||
`AddPartsShadow` family; `CellTransit` prune change affects collision too and
|
||
is reviewed as such).
|
||
|
||
**Automated gate:** comparator zero mismatch on installed-DAT canonical routes;
|
||
render-shadow and physics projections each match typed expectations from the
|
||
same transaction; cancellation, generation replacement, landblock retirement,
|
||
reconnect, child detach converge to zero rows; full Release solution and
|
||
connected headless lifecycle route green.
|
||
|
||
**Owner gate G2 — membership stability.** Cathedral floating stairs/ramp;
|
||
move/rotate at Facility Hub stairs; circle dense Tusker groups while turning;
|
||
remote player and NPC across cathedral wall cells; cast several spells. Pass =
|
||
static geometry never vanishes because its origin or camera-facing cell
|
||
changes; dynamics do not vanish at transitions; retired effects leave no rows.
|
||
|
||
### S3 — Walk: exact PView views, leaf admission, and interleave (was OH4 + OH5)
|
||
|
||
**Spec:** `oh1-built-mesh-view-contract.md`, `oh1-retail-world-contract.md`,
|
||
the flood appendix, handoff §5.3 facts, and the §7 capture fixtures.
|
||
Retail: `PView::InitCell`, `InsCellTodoList`, `ClipPortals`,
|
||
`AddViewToPortals`, `ConstructView`, `DrawCells`, `Render::copy_view`,
|
||
`set_view`, `obj_view_set`, `viewconeCheck`; `LScape::draw_check_blocks`,
|
||
`landcell_check`, `grab_visible_cells`, `draw`, `calc_draw_order`;
|
||
`RenderDeviceD3D::DrawBuilding`, `DrawEnvCell`, `DrawObjCellForDummies`,
|
||
`CShadowPart::insertion_sort`, `CPhysicsPart::Draw`, `DrawMesh`,
|
||
`DrawMeshInternal`.
|
||
|
||
**Binding already-proved facts:** the built cell shell is stamped and
|
||
submitted whole once after Boolean admission; portal polygons, not built
|
||
meshes, are polygon-clipped; `DrawCells` draws all shells then all object
|
||
lists, both in reverse draw-list order, views ascending; device, cell-shell,
|
||
and part stamps persist with the local-player bypass. The "first view clips
|
||
the shell" hypothesis is retired.
|
||
|
||
**Behavior change:** `WalkPView` owns retail's exact per-frame state
|
||
(portal-view lists, view/update counts, todo order, draw list, stamps); each
|
||
content category follows its retail leaf rule (whole-once / Boolean sphere /
|
||
actual polygon clip / repeated submission) and Vulkan clip slots are removed
|
||
from categories where retail does not clip; terrain is emitted as ordered
|
||
landcell events interleaved with buildings and object lists in retail
|
||
far-to-near order; `DrawBuilding` is one semantic sequence (degrade gate → full
|
||
alpha barrier → look-in work → punch → own shell); the "all terrain first"
|
||
simplification is deleted.
|
||
|
||
**Chunks:** (1) transcript emitter for the OH line kinds behind one print-only
|
||
flag + parser extension + fixture import of the §7 logs; (2) exact PView
|
||
state and per-category leaf contract with CPU/GPU equivalence pins for any
|
||
category that still translates a clip to Vulkan; (3) landscape/building/cell/
|
||
object interleave with per-landcell terrain ranges; (4) delete disproved
|
||
generic clip rules and the whole-stage terrain event.
|
||
|
||
**Review:** retail lens on every stamp/view loop branch (Ghidra) and on the
|
||
call order against capture and decomp; shader review of clip-space sign, y
|
||
inversion, W plane, plane count, scissor for remaining translated categories;
|
||
performance review that command count increase is measured, not hidden by
|
||
reordering.
|
||
|
||
**Automated gate:** transcript equality with the §7 captures at the captured
|
||
depth for all four poses plus the FW0 still fixtures; tests distinguish
|
||
whole-shell-once, Boolean part admission, and actual polygon clipping;
|
||
pan/zoom replay changes membership/draw count only at a retail view boundary;
|
||
no duplicate draw of a stamped part; terrain pixels/mesh counts unchanged when
|
||
no interleave is present; dense-outdoor p50/p99 recorded.
|
||
|
||
**Owner gate:** none standalone; folds into G3.
|
||
|
||
### S4 — Depth and alpha: latch, punches, seals, stamps, lists, flushes (was OH6 + OH7)
|
||
|
||
**Spec:** `oh1-depth-lifecycle.md`, `oh1-alpha-list-contract.md`, the §7
|
||
alpha/depth captures. Retail: the complete `PView::DrawCells` outside-view
|
||
block, `portalsDrawnCount` producer/reset/consumer, the mid-frame stamp
|
||
increment (`@0x005A4886`), far-Z punches, true-depth exit seals;
|
||
`D3DPolyRender::AddMeshToAlphaList`, `FlushAlphaList`,
|
||
`CShadowPart::insertion_sort`, `DrawBlock`'s 0.75 pressure valve.
|
||
|
||
**Behavior change:** one frame-persistent latch owner for `portalsDrawnCount`;
|
||
the landscape → flush → stamp → clear → seal block gated exactly as retail;
|
||
`WalkFrameDriver`'s unconditional interior clear deleted; the mid-frame stamp
|
||
placed exactly so straddling parts draw in both retail scopes; exit seals from
|
||
the exact current views and cell order; look-ins cannot touch the root latch.
|
||
The scope-global CYpt sort is replaced by explicit retail list records with
|
||
per-cell insertion order, FIFO flush, exact full-flush sites, and the 0.75
|
||
valve; transparent EnvCell subsets routed to their retail list. AP-34 retired.
|
||
Vulkan keeps the already-ported state: depth ALWAYS, write ON, color OFF, no
|
||
stencil; far-Z punch, true clip-space seal.
|
||
|
||
**Chunks:** (1) latch owner + conditional block + seal generation + truth-table
|
||
tests; (2) alpha list records + insertion sort + flush sites + valve +
|
||
ordering tests; (3) delete obsolete stencil/bias/skip paths and the CYpt sort.
|
||
|
||
**Tests:** truth table over root kind, `draw_landscape`, outside-view count,
|
||
previous/current portal count → clear/seal/stamp events; two consecutive
|
||
frames proving the latch is cross-frame; multiple look-ins isolated from the
|
||
root; coincident cathedral exits at y≈24/48/72; outdoor root never clears
|
||
interior depth; multiple translucent objects in one cell with reversed
|
||
distance/insertion orders; equal-key stable tie; two cells where a global sort
|
||
disagrees with traversal; particle/object/transparent-cell overlap;
|
||
`DrawBuilding 0f` flush; pre-clear and final flush; 0.75 partial flush;
|
||
alternating blend modes across Vulkan batches.
|
||
|
||
**Review:** retail lens tracing every state write from producer to next-frame
|
||
consumer, and every list from insertion to flush; GPU lens on pipeline state
|
||
after the transcript is exact; architecture lens that the latch has one frame
|
||
owner and resets on generation change.
|
||
|
||
**Automated gate:** depth-event and alpha transcripts exact against §7
|
||
captures; focused walk/depth/alpha suites and full Release build green; AP-34
|
||
deleted; no behavior-changing probe in the cathedral replay.
|
||
|
||
**Owner gate G3 — opaque solidity and transparency.** Cathedral
|
||
`0xF4180106 ↔ 0xF4180104` both directions with zoom/rotate; floating stairs
|
||
`0xF4180107 ↔ 0xF4180112` ascend/descend/pan/zoom; exterior ramp from all
|
||
angles; remote player at `0xF4180112` seen only through valid openings from
|
||
`0x104`, `0x101`, outdoors; Facility Hub stairs at all zoom extents; cathedral
|
||
waterfalls, mist, torches, lifestone/portal effects; Tusker/Nanto/Holtburg
|
||
rotate in place. Pass = player whole, walls opaque, no wall-textured beam or
|
||
missing slab, no terrain bleed, correct transparency order, no effect through
|
||
walls.
|
||
|
||
### S5 — Consumers, material, cleanup, closeout (was OH8 + OH9 + OH10 + OH11)
|
||
|
||
**Spec:** `oh1-construction-landscape-contract.md` §landscape; retail
|
||
`LScape::draw_check_blocks`, `landcell_check`, `get_clip_height`,
|
||
`block_check`, `CLandCell::IsInView` (previous-frame), `CEnvCell::IsInView`
|
||
(constant `PARTIALLY_INSIDE`); `DrawBuilding` degrade selection; the
|
||
fixed-function material stage for translucent detail (AP-232).
|
||
|
||
**Behavior change:** the landscape walk produces the exact retail landcell
|
||
`in_view` set; frustum/AABB reconstruction is replaced for every `IsInView`
|
||
consumer (particle update/degrade, point-light snapshots, directional-shadow
|
||
selection); the Extended particle range remains a deliberate post-retail
|
||
option, Retail mode applies no multiplier; AP-117 retired or narrowed. Building
|
||
degrade selection and complete-body gate exact; translucent detail combine
|
||
reproduces retail's single stage result with framebuffer-equivalence
|
||
fixtures; one audited world-subset state policy table; AP-232 retired. Then
|
||
delete every obsolete owner, fallback, flag, probe, and stale claim, add the
|
||
architectural guards, and run the full closeout.
|
||
|
||
**Cleanup inventory (delete or retire):** competing membership dictionaries;
|
||
origin-cell and visual-AABB fallbacks; disproved generic per-view clip rules;
|
||
whole-stage terrain events; unconditional clear code; scope-global alpha
|
||
ordering; `ACDREAM_PROBE_CATHEDRAL_*` skip flags and the carrier-discriminator
|
||
code; `ACDREAM_PROBE_FACILITY_STAIRS` and `WbDrawDispatcher.FacilityStairProbe`
|
||
with its call sites in `RetailPViewRenderer`, `WalkPView`,
|
||
`WalkProductionWorldData`, `WalkStaticStreamPopulator`,
|
||
`WbDrawDispatcher.OrderedStream/WalkClassify`; obsolete shell-lift, bias,
|
||
stencil, corrective-redraw, suppression tests; `PortalVisibilityBuilder`
|
||
research code out of production; stale launch-option rows; architecture
|
||
claims contradicted by code. Guards: one `WalkPView`/graph owner in the
|
||
production call graph; renderer cannot query DAT; consumers cannot construct
|
||
independent visibility sets; the submitter cannot sort across semantic
|
||
boundaries; no production reference to OH diagnostic symbols.
|
||
|
||
**Automated closeout:** full Release build; focused App/Content/Core/Runtime/
|
||
Launcher suites; hermetic lane
|
||
`Lane!=InstalledDat&Lane!=Linux&Lane!=Manual&Lane!=Timing&Lane!=Live&Lane!=PreparedPackage`;
|
||
installed-DAT lane with exclusions listed; two deterministic geometry/
|
||
membership runs with equal hashes; transcript equality over all fixtures;
|
||
capped/uncapped lifecycle/reconnect routes; R6 nine-stop; portal in/out with
|
||
long destination prep; graceful shutdown with zero retained rows.
|
||
|
||
**Performance checkpoint:** dense Arwic capped/uncapped, Tusker dense scene,
|
||
cathedral floating stairs, Facility Hub; CPU/GPU p50/p99, FPS, draw counts,
|
||
allocation/frame, memory, retained graph/membership bytes, alpha high water. A
|
||
regression over 20% against the recorded pre-OH baseline triggers an explicit
|
||
optimization slice (merge adjacent runs, reuse storage; never reorder, cull,
|
||
or weaken the transcript).
|
||
|
||
**Owner gate G4 — final matrix.** Repeats G1–G3 on one clean binary and adds:
|
||
two-client cathedral wall occlusion; Facility Hub stair circuit; Nanto
|
||
waterfalls and town; Tusker combat/casting/rotation; Holtburg town/building/
|
||
lifestone; two ordinary dungeons chosen without code changes; portal to/from
|
||
each world type; zoom/pan/rotate at seams; ten minutes of free movement. Per
|
||
row PASS/FAIL with location and symptom. The final binary is not rebuilt after
|
||
acceptance except for documentation-only changes.
|
||
|
||
**Documentation closeout:** architecture doc (actual graph and pipeline),
|
||
inventory (asset extraction only, never visibility ownership), divergence
|
||
register reconciliation, launch options after probe deletion, FW ledger
|
||
superseded not deleted, roadmap/milestones, campaign memory. Then merge to
|
||
`main`. Status changes to `CLOSED — USER ACCEPTED` only after G4 and docs match
|
||
code.
|
||
|
||
---
|
||
|
||
## 10. Canonical scene and symptom matrix
|
||
|
||
| Scene | Fixed coordinates/state | Required invariant | Slices |
|
||
|---|---|---|---|
|
||
| Cathedral south transition | `0xF4180106 [37.181568 46.790077 169.804993]` ↔ `0xF4180104 [37.310383 48.895710 169.804993]` | Player and walls whole; no wand/body depth inversion | S3–S4 |
|
||
| Cathedral wall actor | Observer `0x104`, `0x101`, outdoors; remote in `0xF4180112 [36.299465 18.594580 169.804993]` | Actor visible only through a retail-valid sightline | S2–S4 |
|
||
| 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 | S1–S4 |
|
||
| Cathedral exterior ramp | Stand on the formerly invisible ramp | Authored shell/member always renders | S1–S3 |
|
||
| 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 | S1–S4 |
|
||
| Nanto waterfalls | `0xE43D001E [93.826614 126.522484 120.005005]` | Falls do not vanish while rotating; houses occlude | S4–S5 |
|
||
| Tusker Island | Owner's dense combat route | Terrain/scenery/actors stable; spell objects retire | S2, S3, S5 |
|
||
| Holtburg | Town route | Buildings intact; particles/lifestone obey depth | S3–S5 |
|
||
| Ordinary dungeons | Two, chosen before code changes | No cathedral overfit; stairs/walls/portals stable | all |
|
||
|
||
Append-only; a new symptom gets a row and an existing invariant before any fix.
|
||
|
||
---
|
||
|
||
## 11. Test and command policy
|
||
|
||
```powershell
|
||
dotnet build AcDream.slnx -c Release
|
||
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
|
||
```
|
||
|
||
Focused `--filter` runs are for iteration; a slice closes on the full families
|
||
above plus the hermetic lane. Record exact commands and counts in §13.
|
||
|
||
**Launch discipline:** every launched candidate is a green Release build from a
|
||
recorded commit; all behavior-changing probes unset; the owner is told the
|
||
exact commit, recipe, and log path; the owner closes the client.
|
||
|
||
---
|
||
|
||
## 12. Instrumentation lifecycle
|
||
|
||
- One print-only transcript flag for the frame walk, introduced in S3 chunk 1,
|
||
documented in `docs/launch-options.md` in the same commit, output-only,
|
||
never read by any draw decision.
|
||
- Slice-local comparators (S2 old-vs-new membership) live and die inside the
|
||
slice.
|
||
- Existing `ACDREAM_PROBE_CATHEDRAL_*` / `ACDREAM_PROBE_FACILITY_STAIRS` flags
|
||
stay unset and untouched until S5 deletes them.
|
||
- No agent adds a probe outside its chunk contract.
|
||
|
||
---
|
||
|
||
## 13. Execution ledger
|
||
|
||
Update immediately when a slice changes state. Chat is not the ledger.
|
||
|
||
| Slice | Status | Spec | Implementation | Reviews | Automated gate | Owner gate | Notes |
|
||
|---|---|---|---|---|---|---|---|
|
||
| v1 OH0 | CLOSED | `oh0-baseline.md` | `b3b7d922` | read-only classification | Release build green; 319 focused / 1 skip | n/a | historical; candidates it committed are S1/S2 seeds |
|
||
| v1 OH1 | SUPERSEDED | research contracts committed at `5cd4fd2c`/`5d907ae9` (kept, binding) | T0–T3 evidence grammar parked on `quarantine/oh1-evidence-grammar-2026-09-02` | reviews found the grammar a false oracle three times | n/a | n/a | see §15 |
|
||
| S1 Geometry | **CLOSED — G1 PASSED 2026-09-02** | `oh2-cellstruct-surface-contract.md` (§3.5 arbitrated on the binary) | chunk A `acf17246`; chunk B `b681717c`; hygiene `0840d5fb`; review fixes `e2543d0e`; G1 regression fix `8c6563ca` (segment/batch pairing) + its pin test (next commit) | lead verified both chunks against the named pseudo-C and the paired binary; two Opus lens reviews, 8 findings all verified by the lead and fixed; the review round's own upload-order change desynchronized cell-shell index segments from batches (first G1 launch: magenta/stretched/missing walls in every dungeon) and was root-caused and fixed by the lead before the re-gate | build 0/0; Content 213/213 (incl. PreparedPackage on the recipe-8 pak); Core 4,948/4,948 (one load-sensitive allocation test outside S1 passes alone); Bake 21/21; Launcher.Core 365/365; Runtime 1,884/1,884; App hermetic 6,757/6,757 | **G1 PASS**: Facility Hub stairs/doorways, Holtburg house interior, ordinary dungeon, town portal network all whole with correct materials on `8c6563ca` + recipe 8; cathedral shows the ORIGINAL symptom family (neighbor-cell walls drawn through portals over the room), explicitly outside G1 and carried to S3/S4 | dev pak recipe 8 (597,369,112 B; `acdream.recipe7.pak` kept); TOC delta explained; corpus scan old-only 3,197 (all untextured), new-only 0, unexplained 0 |
|
||
| Capture | READY | §7 + `tools/walk-oracle/oh/README.md` | scripts committed `ebaa41df` + `14d8fe64`; lead resolved DBObj::m_DID=+0x28 and the cdecl alpha-function conventions; recon attach re-confirms | — | recon dt/x/uf dumps at session start | owner session ~1 h | before S3 |
|
||
| S2 World graph | IN PROGRESS (planning: ownership map research running) | `oh1-construction-landscape-contract.md` | — | — | — | G2 | seeds in `b3b7d922` |
|
||
| S3 Walk | PLANNED | built-mesh/world contracts + captures | — | — | — | folded into G3 | |
|
||
| S4 Depth + alpha | PLANNED | depth/alpha contracts + captures | — | — | — | G3 | retires AP-34 |
|
||
| S5 Consumers + closeout | PLANNED | landscape contract; AP-232 | — | — | — | G4 | retires AP-117/AP-232; deletes probes |
|
||
|
||
### Rollback ledger
|
||
|
||
| Slice | Commits | Last accepted gate | Revert |
|
||
|---|---|---|---|
|
||
| FW closeout | `b8befded`, `4808d4d1`, `4683ac6f`, `e8808602` | FW/Tusker gates | historical anchors only |
|
||
| v1 OH0 | `b3b7d922` | n/a | `git revert b3b7d922` removes the investigation candidates including the Facility stair fix; not a visual claim |
|
||
| S1 | `acf17246`, `b681717c`, `0840d5fb`, `e2543d0e`, `8c6563ca` (+ pin test) | G1 PASS 2026-09-02 | revert newest-first; then restore `acdream.recipe7.pak` over `acdream.pak` in the dev DAT dir (the recipe-8 consumer rejects a recipe-7 pak, and vice versa) |
|
||
| S2 | — | G2 | fill |
|
||
| S3 | — | G3 | fill |
|
||
| S4 | — | G3 | fill |
|
||
| S5 | — | G4 | fill |
|
||
|
||
---
|
||
|
||
## 14. Risk register (condensed)
|
||
|
||
- **R1 second scene graph.** Graph records own only topology/membership facts;
|
||
mesh/entity state is borrowed. Consumer deletion is inside S2.
|
||
- **R2 over-porting C++ mechanics.** Port observable ordering, ownership,
|
||
stamps, and transitions into retained arrays; equality by transcript.
|
||
- **R3 Vulkan reorders.** Immutable stream; only adjacent compatible runs
|
||
merge; tests place merge-compatible draws around alpha/depth boundaries.
|
||
- **R4 package churn.** S1 owns one recipe bump with strict rejection,
|
||
migration, rollback, corruption tests, launcher coverage.
|
||
- **R5 oracle incompleteness.** The §7 capture is the answer key; a missing
|
||
fact gets one exact additional capture, never an approximation.
|
||
- **R6 scene overfitting.** Production guards reject scene IDs; installed-DAT
|
||
sampling and ordinary-dungeon gates are mandatory.
|
||
- **R7 per-cell command cost.** Correctness-first; the 20% rule triggers an
|
||
explicit optimization slice.
|
||
- **R8 stale docs.** S5 cannot close until architecture text is checked
|
||
against production call sites.
|
||
- **R9 evidence sink (new).** Rule 2 and rule 15. A slice with no production
|
||
change after its first chunk is a red flag, not progress.
|
||
|
||
---
|
||
|
||
## 15. v2 rescope record (2026-09-02)
|
||
|
||
**What happened.** v1's OH1 ("upgrade the oracle first") ran unsupervised for
|
||
eighteen hours and produced ~32K lines of uncommitted canonical-JSONL
|
||
evidence grammar plus 142 tests, three review rounds each finding the grammar
|
||
encoded wrong retail semantics, and zero production change. The grammar
|
||
re-encoded PView inside a validator, making it a second port that needed the
|
||
same retail review; it also validated "strong" evidence that neither the
|
||
retail captures nor the acdream recorder produced. The one unlocking item,
|
||
extending the cdb capture templates, was never started.
|
||
|
||
**What v2 keeps.** All committed research contracts; the FW0 capture corpus
|
||
and its proven line-format + parser + replay pattern (which reached 9/10
|
||
conformant fixtures in FW1); the `b3b7d922` candidates as S1/S2 seeds; the
|
||
retail facts the T3 reviews established (handoff §5.3).
|
||
|
||
**What v2 parks.** The evidence grammar, recorder hooks, importer, manifest
|
||
command, and their docs, verbatim, on
|
||
`quarantine/oh1-evidence-grammar-2026-09-02`.
|
||
|
||
**Stage mapping.** OH2 → S1; OH3a–d → S2; OH4 + OH5 → S3; OH6 + OH7 → S4;
|
||
OH8–OH11 → S5. Owner gates: G1 after S1, G2 after S2, G3 after S4, G4 final.
|
||
|
||
**Process changes.** Rules 2 and 15; the §5 working model; the §7 single
|
||
capture session; evidence products limited to what each slice consumes.
|
||
|
||
**Memory:** `claude-memory/feedback_evidence_infrastructure_sink.md`;
|
||
`claude-memory/project_overhaul_campaign.md` is the START HERE.
|