P0 (verbatim-spatial-pipeline-port) Tasks 1+2. ConformanceDats loads the
cottage-doorway cells from the real dats with their real ContainmentBsp;
CottageDoorwayCharacterizationTests maps the Holtburg 0140..017F indoor
neighborhood and pins the master-plan threshold building (origin
161.93,7.50,94.00): 0xA9B40170 vestibule (exit portal 0xFFFF + portal to
0171), 0xA9B40171 room. Grid math confirms the outdoor side is landcell
0xA9B40031 -> the 0031<->0170<->0171 ping-pong is verified real. Verified
interior points recorded for the point_in_cell/find_cell_list goldens.
Plan: docs/superpowers/plans/2026-06-03-p0-conformance-apparatus.md
Notes: docs/research/2026-06-03-p0-conformance-apparatus-notes.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The doorway saga (void -> transparent walls -> flaps) proved patching the hybrid is hopeless:
retail does membership + collision + camera + render as ONE coupled pipeline; acdream
reimplemented pieces with mismatched criteria at the seams. Master plan to port ALL of it
verbatim: A membership (find_cell_list/find_transit_cells/find_building_transit_cells intrinsic,
no bridge), B uniform collision (no indoor/outdoor fork) + door collision, C camera
(update_viewer + find_visible_child_cell), D the full PView render (ConstructView/InitCell/
ClipPortals/GetClip/DrawCells/DrawPortal + the update_count watermark). KEEP/REPLACE/DELETE
lists, decomp anchors per function, P0-P6 sequence (apparatus-first, foundation-up, visual gate
each), and the kickoff prompt. Supersedes the render-only redesign's scope.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The inside/outside render currently splits viewpoints: the player cell roots
visibility + the portal side-test, the eye only projects. Retail uses ONE
viewpoint — the collided camera (viewer) — for the mode decision, indoor root,
side-test, AND projection (RenderNormalMode -> DrawInside(viewer_cell) @92675;
InitCell side-test vs viewer.viewpoint @432991; viewer_cell = sphere_path.curr_cell
@92871). The split makes the render mode follow the player while the screen comes
from the camera -> doorway-straddle void + see-through transition (user evidence
2026-06-03). Spec unifies on the viewer: V1 un-split (robust viewer cell from the
camera sweep, no AABB/grace -> no U.4c flap; lighting stays on the player cell),
V2 DrawPortal (outside-looking-in), V3 floor seal. Supersedes residual-A; merges
A+C. Keeps the blue-hole fix (CurrCell player-only).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Canonical handoff: docs/research/2026-06-03-membership-and-bluehole-shipped-handoff.md
(what shipped: membership Stage 1 ordered-CELLARRAY port + the blue-hole render-root
clobbering fix; the full remaining-issues list — A camera-collision, B R1b particles,
C R2 outside-looking-in, Stage 2 membership, #7 stairs, the 5-test baseline; KEEP/
DON'T-REDO; key files + decomp anchors; copy-paste pickup prompt for next session).
- ISSUES.md: recorded the cottage doorway flap DONE (both causes) in Recently closed.
- render design spec §7: R1 + flap marked DONE; A/B/C mapped to the next render phases.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ports retail CELLARRAY::add_cell (acclient_2013_pseudo_c.txt:701036): ordered list,
dedup by cell_id, append at end. The order is load-bearing for the verbatim
find_cell_list current-cell-first interior-wins pick (next commits) that fixes the
R1 cottage membership flap. Implements ICollection<uint> (helper-facing) +
IReadOnlyCollection<uint> (consumer-facing). 5 unit tests.
Also lands the membership-port pseudocode (workflow step 3) + the Stage-1 plan.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bite-sized plan for R1 (the per-cell DrawInside core): InteriorEntityPartition
(3-bucket, TDD), InteriorRenderer per-cell loop, the binary render decision in
OnRender (indoor = DrawInside only), and the :1756 bypass repurpose. Particles
deferred to R1b. Grounded in the live code surface (exact file:line + signatures).
Ends at the R1 user visual gate (sealed Holtburg cottage, no bleed).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves the plan §3 open questions with the user this session:
- object/entity/particle draw = LITERAL PER-CELL LOOP (retail DrawCells),
not a global MDI batch with per-instance clip. Fidelity > perf > blast-radius.
- sequencing = HOLISTIC: build the per-cell DrawInside directly; no intermediate
global-pass gate-fix. First visual gate = sealed cottage interior, no bleed.
- terrain in the seal = FAITHFUL: drawn only through the exit-portal clip, never
as a floor under the interior. Inventory's 'relax Skip' suggestion REJECTED as a
non-retail workaround; grey-floor = a sealing bug (verify cell mesh in R1).
- WB mesh pipeline KEPT (per-cell draws from the global buffers, batched within a
cell); two-camera invariant preserved (eye projects, player cell roots visibility).
Phases (holistic): R1 unified per-cell DrawInside (the core) -> R2 outside-looking-in
(DrawPortal) -> R3 dungeons -> R4 polish+cleanup. Each ends GREEN + a user visual gate.
Retail anchors cited throughout (RenderNormalMode 0x453aa0, DrawCells 0x5a4840, etc).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Phase W indoor seal did NOT land. The 2026-06-02 visual gate proved the interior render is fundamentally broken (#78: transparent walls, outdoor terrain + scenery entities bleeding in, grey floors, no outside-looking-in). Stage 4 (sky-through-door clip) was real but a top layer on a base that never sealed.
DECISIVE EVIDENCE (committed in the handoff): the PVS computes correctly AND the cell shells render correctly (opaque, textured, complete — the [shell] probe shows zero NOSNAP / zero missing-texture). The failure is the SEAL + three inconsistent gates — concretely the WbDrawDispatcher.cs:1756 ParentCellId==null -> return true bypass draws outdoor scenery indoors, and the indoor path draws the outdoor world then gates it instead of running ONLY DrawInside. Retail, when inside, runs ONE PView flood: visibility IS the cull; the landscape enters only through clipped exit portals + a conditional depth-only clear.
Dossier (per the user's mandate: NO shortcuts/bandaids, port from retail, redesign the whole pipeline if needed, brainstorm first):
- Master handoff (root cause + retail target + reusable-vs-redesign + apparatus + do-not-repeat + copy-paste pickup prompt).
- Huge staged redesign plan R0(brainstorm)->R1(one visibility authority, kill the bleed)->R2(indoor=DrawInside-only)->R3(the seal, DrawCells port)->R4(per-cell object/particle clip)->R5(outside-looking-in)->R6(dungeons)->R7(polish/conformance). Each ends at a user visual gate.
- 3 research docs: full retail render pipeline reference (705 lines, decomp-verified), acdream pipeline inventory + failure map, reference cross-check (WB two-pipe is the wrong model).
#78 promoted to the redesign. The 5 remaining Core test failures are pre-existing physics/collision bugs, none render-related.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per-step subagent-driven plan for the render half: T0 test-hygiene baseline,
Stage 3 render-root unification (root at CellGraph.CurrCell + seen_outside, drop
the FindCameraCell grace-frame fallback), Stage 4 PView seal (sky/landscape inside
the portal-clip bracket + conditional doorway Z-clear = no blue-hole; EnvCellRenderer
GL_BLEND verify), Stage 5 entity/particle cell-clip. Key reframe from grounding the
plan in the actual code: the PView infra (PortalVisibilityBuilder BFS + OutsideView,
ClipFrame, EnvCellRenderer GL_BLEND fix, WbDrawDispatcher cell gate) ALREADY EXISTS and
the A8 stencil split is already gone — so the render half is wire-and-fill-gaps, not a
from-scratch port. Execution policy: no intermediate user gates, single final visual
verification, full suite green at verification.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stage 1 (return swept sp.CurCellId, 3e1d502) was gated and the doorway strobe
PERSISTS: [cell-transit] still flips 0170<->0031. Airtight root from code analysis:
Transition.FindEnvCollisions re-derives the cell from the STATIC origin via
engine.ResolveCellId at TransitionTypes.cs:1947 and clobbers sp.CheckCellId (:1949)
at the start of every sweep pass — a second, earlier static re-derive the four
studies missed (they targeted the late return-site). It is the sole path that can
set an indoor swept cell outdoor (the containment pick at :2075 skips outdoor cells).
:1947 is dual-purpose (jitter source AND the only indoor->outdoor exit), so Stage 2
must replace it with a directed exit-portal crossing + do_not_load prune + exitOutside
re-gate — a careful #98-area rework, not a one-line delete. Render residuals at the
gate (no interior outside-looking-in, blue-through-door, particle/NPC bleed) are all
expected Stages 3-5, not Stage-1 regressions. Stage 1 is kept (correct + necessary).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bite-sized TDD plan for design Stages 0-1 + W2b revert + visual gate: add the
[cell-swept] diagnostic, return the swept sp.CurCellId from ResolveWithTransition
(retail SetPositionInternal), revert the superseded W2b hysteresis, visual-gate the
doorway/cellar strobe, then lock it with a doorway replay regression. Render chunk
(Stages 3-5) gets its own spec+plan after this gate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Four independent decomp studies (Opus 4.8 x2, Sonnet 4.6, external Codex)
converge: retail carries the cell through the collision sweep (validate_transition
advances curr_cell only on an accepted move, reverts on a block) and commits it in
SetPositionInternal — it never re-derives membership from a static resting position.
acdream already ports the sweep machinery (sp.CurCellId/CheckCellId, ValidateTransition,
CheckOtherCells) but ResolveWithTransition discards the swept cell and re-derives
statically via ResolveCellId (PhysicsEngine.cs:909/928) — the root of the
0170<->0031 doorway/cellar ping-pong. The do_not_load_cells prune is secondary
(static/cross-cell lists), not the anti-flicker; W2b was doubly misplaced and is reverted.
Render: one PView::ConstructView portal traversal over the same cell graph, rooted at
the physics current cell; seen_outside (not a dungeon flag) gates landscape; the outside
draws through exit portals clipped to the doorway (no blue-hole, no stencil split).
Dungeons/interiors share the machinery; "underground" is emergent.
Design doc lays out the staged, evidence-first rewrite (Stage 0 diagnostic ->
Stage 1 transition-owned membership [visual gate] -> Stage 2 CELLARRAY/prune parity ->
Stages 3-5 render root + PView seal + entity clip). Adds the shared research prompt and
all four study reports as the grounding record.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8 TDD tasks (RED->GREEN), Core-only, zero behavior change, built alongside the legacy cell systems. Grounded in the retail CObjCell survey + acdream inventory + #98 fixtures.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pixel-grounded investigation concluded the indoor 'world from below' is a cell-MEMBERSHIP disagreement between render-side CellVisibility and physics-side ResolveCellId, not any single draw gate (terrain has one gated draw path; it leaks only on render null-root frames). Decision with user: full migration onto one retail CObjCell graph across physics+collision+render+streaming, staged in 5 verify-each cycles. This lands the evidence model + the Stage 1 (ObjCell scaffold) design. No code yet.
- docs/research/2026-06-02-render-cell-membership-evidence.md (the why, from pixels)
- docs/superpowers/specs/2026-06-02-unified-cell-graph-stage1-design.md (Stage 1)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A week on the indoor render (Phase U.4 → U.4c → 2026-05-31) fixed the flap but
produced NO shippable progress: walls/ceiling don't seal, outdoor terrain is
visible from inside (#78), the enclosure reads grey/transparent. Root cause is
ARCHITECTURAL, not a bug.
Evidence this session (direct, via the new [shell] probe + screenshots) RULED OUT
every subsystem except the gating architecture: the interior cell shells render
fine (geometry/texture/opaque/depth all correct, zh=0 tr=0); the visibility
traversal computes correct sets + non-empty portal clips; cull mode is fine; the
camera/eye thread was a detour. The residual is that OUTDOOR geometry is not gated
to portal openings when indoors, and acdream enforces visibility THREE inconsistent
ways (TerrainClipMode / per-cell shell clip / entity ParentCellId filter with an
outdoor-stab bypass) instead of retail's ONE PView gate.
This commit is the reset handoff + documentation, not a code fix:
- docs/research/2026-05-31-render-architecture-reset-handoff.md — canonical: honest
state, evidence ledger (ruled-out / do-not-repeat), the mapped 3-gate patchwork,
the retail PView target (one traversal → one gate for ALL geometry), the reset
mission, and a copy-paste pickup prompt.
- docs/architecture/acdream-architecture.md — new "Render Pipeline" SSOT section
(current divergence + unified-PView target + the one rule: compute visibility
once, enforce it once). (Doc has pre-existing corruption below this section —
flagged for separate cleanup.)
- Apparatus: ACDREAM_PROBE_SHELL → [shell] (EnvCellRenderer per-cell prepared/drawn
geometry + flags) added to RenderingDiagnostics + EnvCellRenderer. Throwaway.
- docs/superpowers/specs/2026-05-31-camera-collision-indoor-engagement-design.md —
spec for e099b4c (camera collision; now parked as orthogonal to the seam).
Next session: STOP point-fixing; do the architecture reset to a single PView gate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Five tasks: (1) RED apparatus reproducing the doorway flap on a synthetic
C0->C1->C2(exit) chain; (2) Layer 1 LoadedCell.VisibleCells + SeenOutside
plumbing; (3) oracle-ported PVS grounding of set membership (the fix, gated by
task 1); (4) seen_outside invariants (sealed=empty, threshold=stable); (5)
live [vis] + visual gate. Task 3 is a faithful port (add_views 433382 /
InitCell 432896 / ClipPortals 433572), pseudocode-first, not fabricated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Grounds the visible-cell SET in the stable per-cell PVS (stab_list) + seen_outside,
refreshed on cell entry, the way retail does (grab_visible_cells 311878, add_views
433382, DrawInside 433793). Our PortalVisibilityBuilder rebuilds the set per-frame
from a pose-brittle CameraOnInteriorSide walk, so a flipped side-test drops the exit
cell, empties OutsideView, and TerrainMode.Skip flaps terrain/shells off at the
doorway. Both stable inputs already live in-process (envCell.VisibleCells,
envCell.Flags & SeenOutside); U.4c is plumbing + grounding, not new dat parsing.
Apparatus-first: characterize the flap on a live ACDREAM_PROBE_VIS capture + port the
add_views/ClipPortals/AddToCell semantics to pseudocode before implementing; the
builder is not declared correct until a live [vis] shows non-empty + narrowing
OutsideView. No hysteresis band-aid (forbidden). Indoor rendering untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
One PView-faithful portal-visibility pass replacing the abandoned two-pipe
(inside/outside) split (#103). Settled in brainstorm 2026-05-30:
- Full Phase U in one spec (indoor BFS + outdoor building-peering + dungeon
fixpoint + distance-priority ordering + reciprocal OtherPortalClip).
- Per-cell gate = hardware clip planes (gl_ClipDistance) + scissor pre-check
(retail's two-level model); structurally immune to the #103 global-mask flood.
- Terrain stays its own path, gated to OutsideView (retail-faithful; NOT the
handoff's "terrain as cells" sketch).
- Salvage = reuse the clip math (PortalView/ScreenPolygonClip/PortalProjection,
~36 tests), rework the builder (PortalViewBuilder), delete the stencil pipeline
+ GameWindow two-pipe orchestration. Audited keep-list preserves the real
EnvCellRenderer / BuildingId / camera-collision fixes.
Staged U.1-U.6 with three visual gates. Retail anchors + acdream file:line
injection points catalogued in the spec.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The plan's Task 2 code block still showed moverFlags: ObjectInfoState.None; the
shipped code (fcea05f) and spec §5.1 use IsViewer|PathClipped|FreeRotate|
PerfectClip (retail init_object(player, 0x5c)). Update the stale snippet so the
plan matches reality (this stale block was the likely source of a re-report).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The 2026-05-18 retail-chase-camera spec scoped collision out citing "retail
doesn't raycast." Phase A8.F falsified that (SmartBox::update_viewer DOES sweep
viewer_sphere); mark the note superseded and point to the A8.F spec.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Code review found the probe passed ObjectInfoState.None; retail's
SmartBox::update_viewer calls init_object(player, 0x5c) =
IsViewer|PathClipped|FreeRotate|PerfectClip (pseudo-C :92864). PathClipped makes
the sweep hard-stop at first contact (TransitionTypes.cs:811) instead of
edge-sliding around corners (which would re-trigger the A8.F camera-cell
instability); IsViewer lets the eye pass through creatures, colliding only with
world geometry. Resolves the spec's slide-vs-stop open question. Also reset
CollideCamera in the Defaults_AreRetailValues baseline test (review: maintenance
trap). Spec §5.1/§11.1 synced.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bite-sized TDD plan for the swept-sphere camera collision: CollideCamera flag,
ICameraCollisionProbe + PhysicsCameraCollisionProbe (reuses ResolveWithTransition),
RetailChaseCamera slot-in, GameWindow wiring, Camera-menu toggle, visual
acceptance. Also refines the spec from planning findings: the InitPath +radius
sphere-center offset (ToSpherePath/FromSpherePath z-shift) and the deterministic
probe test scope (z-offset round-trip + cellId==0 guard; collision correctness
rides the existing sweep suite + visual).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Design for porting retail's stage-2 camera collision (SmartBox::update_viewer):
sweep a 0.3 m sphere from the head-pivot to the damped eye via the existing
ResolveWithTransition engine (collides both indoor cell walls and GfxObj
building shells, e.g. the cottage cellar per #98/#101), publish the stopped
position as the eye. Fixes the A8.F flap by keeping the eye out of walls so the
camera-cell + portal side-tests stay stable. Self-skip via LocalEntityId; gated
by CameraDiagnostics.CollideCamera (default ON). Corrects the prior
retail-chase-camera spec's "no camera collision" note.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The 2026-05-28 handoff's "uncommitted A8 batch" is stale: 5dc4140 landed
the batch after the handoff. Step 0 reduces to stripping the leftover
ACDREAM_A8_DIAG_* flags (still present in RuntimeOptions + GameWindow).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Faithful port of retail PView recursive portal-clip visibility
(ConstructView/ClipPortals/GetClip) to fix the residual A8 cellar flap.
Key finding: WB has no per-portal recursion — the flat-stencil algorithm
cannot express the fix; the recursion is retail-only. Builder ports as
GL-free CPU math producing a recursively-clipped OutsideView; enforcement
maps onto the existing A8 stencil pipeline. Builds on (does not supersede)
the A8 WB full-port baseline.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Lands the working A8 indoor-rendering and streaming fixes accumulated this
session. User has verified these visually to some degree (e.g. lifestone /
translucent meshes confirmed fine under the FrontFace flip; bridge / wall /
collision regressions confirmed fixed after travel); not every path has been
exhaustively gated. The cellar-flap defect remains OPEN and will be solved
the retail-faithful way via a dedicated brainstorm (see handoff docs).
Rendering core (reviewed, high confidence):
- EnvCellRenderer SSBO stride fix: upload packed Matrix4x4[] (64B) instead of
the 80B CPU InstanceData struct the shader never expected — fixes the
transform/texture "explosion" for any draw with >1 instance (cells that
dedupe to a shared cellGeomId). Real root cause.
- WB-style global FrontFace(CW) + per-batch CullMode carried through the MDI
layout (GroupKey + BuildIndirectArrays + DrawIndirectRange split into
same-cull runs with absolute uDrawIDOffset per run).
- EntitySet partitioning (IndoorPass / OutdoorScenery / LiveDynamic) +
WorldEntity.BuildingShellAnchorCellId so building shells scope to their
dat-derived building cell instead of rendering everywhere.
- RenderOutsideInAcdream (look into buildings from outside) +
CollectVisiblePortalBuildings frustum cull of portal bounds.
- Sky-when-inside-building + per-cell audit probe + GL-state probe.
Streaming / perf (test-covered; not independently code-reviewed this session):
- Near/far priority queues so near work wins over far; PromoteToNear carries
full landblock + mesh data; LandblockEntriesWithoutAnimatedIndex avoids
rebuilding the animated-lookup dict in the hot draw path. Fixes the
bridge-not-appearing / missing-walls / broken-collision-after-travel
regressions and improves post-transition FPS.
Tooling + docs:
- tools/A8CellAudit: offline dat cell/portal/building dumper (portals +
buildings modes) — reproduces the cellar-flap investigation with no launch.
- docs/research cellar-flap root-cause + option-2 handoff (the didInsideStencil
double-duty finding + the WB-recursive design decision + brainstorm prompt),
entity-taxonomy, replan, issue-78 visibility investigation.
Diagnostics retained on purpose: ACDREAM_A8_DIAG_* gates, portal_stencil.vert
provisional pos.w clamp, and the probe families are kept (env-var gated, zero
cost when off) because the pending option-2 cellar-flap brainstorm needs them.
Strip in the option-2 ship commit.
Indoor branch stays behind ACDREAM_A8_INDOOR_BRANCH=1 (default off = pre-A8
visual). Build green; App tests + Core (streaming/dispatcher/loader) tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the four reverted RR7 variants from 2026-05-27 with a
verbatim port of WB VisibilityManager.RenderInsideOut.
Plan covers 10 tasks across 5 dependency waves:
- Wave 1 (tasks 1-4, 7): extract WbRenderPass, WbFrustum,
EnvCellSceneryInstance/EnvCellLandblock, EnvCellVisibilitySnapshot;
add IndoorCellStencilPipeline.RenderBuildingStencilMask
- Wave 2 (task 5): build EnvCellRenderer with inline RenderModernMDI
- Wave 3 (task 6): wire EnvCellRenderer into landblock streaming
- Wave 4 (task 8): port RenderInsideOutAcdream byte-for-byte
- Wave 5 (task 9): probe trail [envcells]/[stencil]/[draworder]/[buildings]
- Wave 6 (task 10): probe-gated visual verification launch
Process rules carved from RR7 saga:
- No visual gate without probe data first
- No partial WB ports (Steps 1-5 ship together)
- No conceptual adaptations
- Trust-but-verify after every subagent
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both documents retained for historical reference. The new full-WB-port
design + plan (2026-05-26-phase-a8-wb-full-port-design.md + plan, ea60d1f +
651e7e2) replace them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brainstorm-approved design for the A8 R3.5 → restructure pivot. Replaces
the R3.5 v1+v2 frankenstein (terrain twice + depth-clear workaround) with
WB's RenderInsideOut order verbatim: skip initial sky+terrain when inside,
delete the depth-clear, add a stencil-gated sky step inside the indoor
branch so windows show real sky (closes R4 Issue B).
Unifies the two-flag asymmetry (cameraInsideCell lenient + cameraReallyInside
strict) into a single strict cameraInside flag via PointInCell. Grace
mechanism in CellVisibility stays alive for non-render consumers.
Six tasks ahead, in order:
RR0 — pre-restructure falsification spike (Issues A + C on main?)
RR1 — revert R3.5 v1+v2 (38d5374 + 2bfeafd)
RR2 — restructure render frame to WB-faithful order
RR3 — verify SkyRenderer doesn't toggle stencil state
RR4 — visual verification matrix (cottage/cellar/inn/dungeon + transitions)
RR5 — ship docs (close#78; file new follow-ups if pre-existing on main)
Next: superpowers:writing-plans to produce the per-task plan.
Note: the design references two predecessor docs that are currently
untracked in this worktree (entity-taxonomy + phase-a8-replan). Their
contents are read-stable on disk; committing them is a separate concern
(they belong to the prior session's work). The handoff doc this design
continues from is at f90fa2f.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Session-end documentation for the issue #100 ship and the visibility-
culling investigation handoff for the next session.
Three documents land together:
- docs/superpowers/plans/2026-05-25-issue-100-terrain-cutout.md
(the 3-task plan that drove this session's f48c74a / a64e6f2 /
84e3b72 — never committed by Tasks 1-2)
- docs/research/2026-05-25-issue-100-terrain-cutout-handoff.md
(the predecessor session's smoking-gun research that drove the
#100 fix — never committed by the prior session)
- docs/research/2026-05-25-issue-100-shipped-and-culling-handoff.md
(THIS session's handoff: what shipped, what visual-verification
surfaced, the issue family map for #78 + #95 + the new cellar-
stairs finding, root-cause hypothesis, retail anchors, WB
references, do-not-retry list, and pickup prompt for the next
session's investigation + plan + implementation)
Plus two updates to existing files:
- CLAUDE.md — adds a ship paragraph for #100 to the M1.5 progress
block. References the new handoff doc as the next-session pickup
point.
- docs/ISSUES.md #78 — broadens scope from "outdoor stabs visible
through floor" to "outdoor stabs + terrain mesh visible inside
EnvCells". Adds the 2026-05-25 cellar-stairs evidence (per user
direction: not filed as new issue; treated as evidence
reinforcing #78's hypothesis #2). Promotes hypothesis #2 to
"high confidence as of 2026-05-25" and adds the retail anchor
(acclient_2013_pseudo_c.txt:311397 CEnvCell::find_visible_child_cell).
Acceptance criteria broadened to include the cellar-stairs case.
Next session: pickup prompt at the bottom of the new handoff doc
drives a /investigate → writing-plans → subagent-driven-development
pass on indoor-cell visibility culling — the work that closes#78
+ cellar-stairs together, and possibly #95 if the infrastructure
overlaps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Captures the brainstorm session 2026-05-24 evening after A6.P4 slice 1
(b49ed90) shipped without closing #99. Investigation surfaced the actual
root cause: doors register as a single 14cm × 20cm bounding-cylinder
approximation derived from Setup.Radius/Height fallback. Their real
collision-bearing geometry lives in per-part GfxObj BSPs (3 parts for
Setup 0x020019FF), including the threshold polygon spanning the doorway.
Retail-faithful design: every server-spawned entity registers N shadow
entries (one per CylSphere + one per Sphere + one per Part-with-BSP),
all sharing the same EntityId. UpdatePhysicsState propagates ETHEREAL
flips to all entries via the existing EntityId-iteration path. Unifies
the live-entity and landblock-static registration code paths under one
ShadowShapeBuilder.
Retail anchor: CObjCell::find_obj_collisions → CPhysicsObj::FindObjCollisions
→ CPartArray::FindObjCollisions → CPhysicsPart::find_obj_collisions →
CGfxObj::find_obj_collisions. One PhysicsObj per entity, parts iterated
internally for collision (acclient_2013_pseudo_c.txt:276776-275055).
Five-commit migration sequence; tests at three layers (builder unit tests,
registry behavior tests, live-capture regression pin). Approach A approved
by user 2026-05-24.
Spec stands on its own as M1.5 work; not formally assigned a phase letter
per CLAUDE.md's "don't invent phase numbers on the fly" rule.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Knowledge-preservation pass after the issue #98 cellar-up fix shipped
(`b3ce505`). Closes the saga's documentation loop and plans the next
phase.
Changes:
- docs/research/2026-05-23-a6-p3-issue98-comparison-harness-findings.md
Appended "Resolution 2026-05-24" section: v3 hypothesis falsified,
actual mechanism (head-bump cottage GfxObj floor poly from below)
confirmed, b3ce505 fix shipped, known door regression flagged.
Memory artifacts cross-referenced.
- docs/ISSUES.md
#98 moved to DONE with full resolution writeup + decomp anchors.
#99 filed: door regression at building thresholds (caused by
b3ce505's indoor-primary gate). Closes via A6.P4.
#100 filed: transparent rectangular patches around houses
(terrain rendering). Bisect found commit 35b37df introduced the
hiddenTerrainCells mechanism that collapses 24m outdoor cells
when buildings sit in them; cottage building only fills part of
its cell so the rest of the 24m cell shows the sky-bleeding gap.
Three fix-path options documented.
- docs/superpowers/specs/2026-05-24-phase-a6-p4-retail-shadow-architecture.md
Full A6.P4 design doc. Three-slice plan: (1) query-side portal
expansion to close#99 while preserving #98 fix, (2) port retail's
BuildShadowCellSet at registration time so per-cell semantics match
`CObjCell::find_cell_list`, (3) remove b3ce505 stopgap entirely.
Decomp anchors, file-by-file plan, risk inventory, open questions.
Memory entries written separately (out-of-tree at
~/.claude/projects/.../memory/):
- feedback_retail_per_cell_shadow_list.md
The architectural lesson: retail uses per-cell shadow_object_list
with portal-aware registration; our landblock-wide spatial
registry diverges at indoor/outdoor seams.
- feedback_apparatus_for_physics_bugs.md
The apparatus-first pattern that cracked the saga: live capture +
fixture dump + replay harness. Template for future physics bugs.
Quote rule: "when a physics bug is resisting and you catch
yourself about to ship 'fix attempt N+1 with no new evidence,'
STOP. Build the apparatus first."
- MEMORY.md index updated with both new entries.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds one log line per AdjustOffset call (gated by ACDREAM_PROBE_STEP_WALK)
naming the branch taken (no-cp / no-cp-slide / slide-degenerate /
slide-crease / into-plane / away-plane, optionally +safety-push) plus
zGain = output.Z - input.Z.
No math or control-flow changes — pure observability so the next capture
can disambiguate the three failure-mode hypotheses for the cellar-ramp
climb cap. Re-reading the existing capture (a6-issue98-negpoly-...log)
showed the sphere DOES climb 90.00 -> 92.79 (2.79 m gain), then caps,
contradicting the divergence comparison's "no altitude gain" framing.
The real question is what stops the climb at world Z ~= 92.79 with the
cottage floor still 1.21 m higher. Existing [step-walk] probes wrap
AdjustOffset; this new probe reveals which branch the projection takes.
Fix plan with the four-branch decision tree at
docs/superpowers/plans/2026-05-23-a6-p3-issue98-cellar-up-fix.md.
Test baseline maintained: 1167 + 8.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
15-task TDD plan covering the three pieces of A6.P1:
Phase A — Build the [push-back] acdream probe (Tasks 1-9):
toggle + 3 helpers + 3 emission sites in BSPQuery/Transition,
DebugVM mirror, CLAUDE.md env-var docs.
Phase B — Build the cdb infrastructure (Tasks 10-12):
7-BP cdb script, PowerShell runner, README.
Phase C — Execute 9 captures + findings stub (Tasks 13-15):
PDB-match verify, capture dir + findings stub, scenario captures.
API surface verified against current code: ResolvedPolygon has no
Id property (probe omits poly attribution; cross-ref via time-
adjacent [push-back-cell] line). CheckOtherCells locals are
sp.CheckCellId + cellId + result (verified at TransitionTypes.cs
lines 1418-1473). SpherePath has Collide/InsertType/WalkInterp,
ObjectInfo has State (verified).
Spec: docs/superpowers/specs/2026-05-21-phase-a6-indoor-physics-fidelity-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brainstormed + approved 2026-05-21 for M1.5 milestone work. Designs
the cdb probe spike methodology (7 retail breakpoints + new
[push-back] probe) to capture retail's per-tick BSP collision
response state at 9 indoor scenarios (4 buildings + 5 dungeon sites)
and compare against acdream. Working hypothesis: BSPQuery.AdjustSphereToPlane
or its callers over-correct vs retail, producing the family of
indoor symptoms (walls walk through, ping-pong, vibration, multi-Z
falling) plus driving the existing #90 + TryFindIndoorWalkablePlane
workarounds. A6 ships in 4 slices: P1 probe spike, P2 analysis,
P3 surgical fixes, P4 workaround removal + acceptance.
Phase O (DatPath Unification) pre-empted M1.5 and shipped 2026-05-21;
A6 resumes from Phase O state. Phase O only touched rendering/dat
code; indoor physics design is unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Plan: 7 tasks decomposing spec T2..T9 with bite-sized TDD-style steps,
exact file paths, commit-message templates, and a T4 safety-check
branch (refactor in place if ObjectMeshManager._dats call sites <=20;
fall back to thin adapter otherwise).
Spec fix: §4.1 mesh-pipeline files now correctly placed under
src/AcDream.App/Rendering/Wb/ instead of Core (ObjectMeshManager uses
Silk.NET.OpenGL types from Managed* wrappers, and CLAUDE.md forbids
Core depending on GL). §4.2's layer split (TextureHelpers in Core,
rest in App) was already correct.
Plan task order: T2 (setup) -> T5 (Core helpers, lowest risk) ->
T3 (App GL infra) -> T4 (App mesh pipeline + dat-shim) -> T7 (drop
refs + cleanup) -> T8 (visual verification) -> T9 (ship). T5 moved
earlier than spec order to validate the namespace migration flow on
small-blast-radius files before the load-bearing T4.
Self-review: all 12 spec decisions (O-D1..O-D12) mapped to plan tasks;
placeholders intentional + explained (MIT license body fetched at T2
step 4; commit-message parameters filled at task close).
Spec: docs/superpowers/specs/2026-05-21-phase-o-dat-path-unification-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
O-T1 audit (REPORT-ONLY) maps acdream's transitive closure on WorldBuilder:
33 files / ~7.7K LOC across Chorizite.OpenGLSDLBackend (28 files) and
WorldBuilder.Shared (5 files). Verdict on O-Q1 (thread-model): SAFE —
adapters run render-thread only; no worker-thread access to WB code.
Spec amendments incorporated via brainstorm:
- O-D7: Refactor ObjectMeshManager to take DatCollection directly (not
via adapter). T4 safety check — fall back to thin adapter if call-site
count >20.
- O-D8: Drop LandSurfaceManager, EnvCellRenderManager, PortalRenderManager,
TerrainRenderManager from the extract list — audit confirmed not reachable
(we have our own ports or never used them).
- O-D9: Promote 3 internal types in Chorizite to public on extraction
(EmbeddedResourceReader, TextureFormatExtensions, BufferUsageExtensions).
- O-D10: Strip [MemoryPackable] from TerrainEntry (we don't serialize).
- O-D11: Namespace AcDream.Core.Rendering.Wb.* for extracted code.
- O-D12: Drop ResolveId + [indoor-upload] NULL_RESULT diagnostic block.
Task breakdown: T6 (EnvCell/portal) eliminated; T5 (stateless helpers)
shrinks to 0.5d; T4 (mesh + refactor) grows to 2.5d. Net effort estimate
holds at ~7.75d.
All originally-open spec questions are now closed (Q1/Q2/Q3/Q4) or
deferred to T3 with an explicit verify step (Q5: SixLabors.ImageSharp
reachability).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase O extracts the WB pieces we actually use (mesh pipeline, texture
decode, GL state, scenery, terrain blending, EnvCell/portal decode —
roughly 3-5K LOC) into src/AcDream.Core/Rendering/Wb/, swaps their
dat dependency from DefaultDatReaderWriter to our DatCollection, and
drops the WorldBuilder.Shared + Chorizite.OpenGLSDLBackend project
references. WB stays in references/ as a read reference, not as a
project dependency. MIT attribution in NOTICE.md.
Tagline: ONE thing touches the DATs.
Discipline: verbatim copy first, no "improvements" while extracting.
Refactors land in follow-up phases. Out of scope: re-porting from
retail decomp; perf optimization; API cleanup.
User direction 2026-05-21: pre-empts M1.5. M1.5 paused at its
2026-05-20 baseline; A6/A7 don't touch dat infrastructure so no
rework needed when it resumes.
Files:
- docs/superpowers/specs/2026-05-21-phase-o-dat-path-unification-design.md (new, full spec)
- docs/plans/2026-04-11-roadmap.md (Phase O block inserted before M1.5; M1.5 marked PAUSED)
- CLAUDE.md (Currently-working-toward line updated; M1.5 block marked paused)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>