docs: reconcile M1.5 tracking with git reality — G.3 dungeons SHIPPED, not "broken"

The milestones doc, roadmap, CLAUDE.md banner, and #138's ISSUES cross-ref had
drifted ~4 weeks behind shipped work — they still claimed "dungeons don't work
AT ALL / terrain-less landblocks unsupported (#133)", which sent this session
chasing a phantom door "regression" for an hour. Git reality (and tonight's live
dungeon session) refute it:

- #133 teleport-into-dungeon DONE (G.3a hold-until-hydrate FSM 7947d7a/2ce5e5c8/47ae237e);
  the terrain-less premise was refuted at design time (90786c19: dungeon LandBlock
  is flat-terrain, streams via the existing pipeline).
- #95 portal-graph visibility blowup RESOLVED (9.1M→~39k instances, a40c38e8).
- #137 dungeon collision CLOSED (0efa7ed2); doors #187/#188; A7 lighting #79/#93/#80/#154 CLOSED.
- #138 teleport-OUT ESSENTIALLY RESOLVED in code — the remaining M1.5 gap is one
  RECORDED end-to-end round-trip user gate, not broken code.

Also fixes a numbering trap: #138's body cited "#146/#147" for its collision
residuals, but those numbers are D.2b inventory-polish issues in this worktree;
the real residuals are #152 (portal-in walls, DONE 49d743f) + #151 (far-town
walls, FIXED 9743537). Sole live residual now surfaced: far-town teleport-OUT
arrival cascade (#145-residual, REOPENED — capture-harness-first).

Historical working-notes annotated [SUPERSEDED] rather than deleted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-10 09:45:05 +02:00
parent 217a4bad69
commit 5e271dd719
4 changed files with 75 additions and 43 deletions

View file

@ -2064,9 +2064,11 @@ See divergence register **AP-59**.
**Status:** ✅ ESSENTIALLY RESOLVED — position-desync FIXED via #145; server-object re-hydrate
SHIPPED (`LandblockEntityRehydrator`, AP-48); avatar-vanish (symptom B) ACTUAL root found +
FIXED + user-confirmed (`afd5f2a`, 2026-06-24 — skip the per-frame `RelocateEntity` while
`PortalSpace`). Remaining collision residuals split out to **#146** (Holtburg portal-in
building walls) + **#147** (Arwic far-town frame) — those are the live follow-ups, not #138
itself. See the 2026-06-24 update at the bottom of this entry.
`PortalSpace`). Remaining collision residuals split out to **#152** (Holtburg/building portal-in
walls, DONE `49d743f`) + **#151** (Arwic far-town frame, FIXED `9743537`) — those are the live
follow-ups, not #138 itself. (⚠️ Numbering trap: #146/#147 in this file are unrelated D.2b
inventory-polish issues — see below — not the collision follow-ups; the correct numbers are
#151/#152.) See the 2026-06-24 update at the bottom of this entry.
**Severity:** MEDIUM (breaks the dungeon→outdoor transition; collision + visuals wrong after exit)
**Filed:** 2026-06-14
**Component:** streaming — dungeon collapse↔expand (the #133/#135 collapse) + teleport-arrival
@ -2113,7 +2115,7 @@ Both are the **entity-lifecycle/render path across a teleport**, NOT the streami
**Implementation (B — player vanish, candidate):** `GpuWorldState.RemoveLandblock` rescued persistent entities only from `_loaded`, silently dropping a persistent entity sitting in the **pending bucket** (the player is re-injected via `AppendLiveEntity` every frame; right after a teleport its landblock hasn't streamed yet → pending; if that landblock is then unloaded mid-churn the player was dropped → "vanishes after a couple round-trips"). Fix: rescue persistent pending entries too. Tests `RemoveLandblock_RescuesPersistentEntity_FromPendingBucket` (+ negative). This is a provable correctness fix for the "persistent ⇒ survives unload" invariant; it is the leading candidate for symptom B but needs user re-verification to confirm it is the complete cause.
**UPDATE 2026-06-24 — symptom B (avatar vanish) ACTUAL root found + FIXED (`afd5f2a`, user-confirmed + trace-verified):** the pending-bucket rescue above was necessary but NOT the whole cause. The real culprit: the per-frame avatar-sync (`GameWindow` ~:8018) calls `GpuWorldState.RelocateEntity` using the player controller's cell, which stays the **FROZEN SOURCE cell** until `PlaceTeleportArrival` materializes the destination. Mid-transit it dragged the avatar — which the teleport's `DrainRescued` re-inject had correctly placed at the destination center — back into the now-UNLOADED source landblock's pending bucket, where nothing recovers it (`RelocateEntity` only scans `_loaded`). Fix: skip the per-frame relocate while `_playerController.State == PortalSpace`. Verified by a new env-gated avatar-lifecycle probe (`ACDREAM_PROBE_ENT` / `EntityVanishProbe`): pre-fix `[ent] APPEND lb=0x0007FFFF(source) -> PENDING -> DRAWSET ABSENT` never recovered; post-fix every teleport goes `RESCUE -> ABSENT -> APPEND(destination) -> PRESENT` and stays drawn. **The remaining #138 collision residual split into #146 (Holtburg portal-in building walls) + #147 (Arwic far-town frame).**
**UPDATE 2026-06-24 — symptom B (avatar vanish) ACTUAL root found + FIXED (`afd5f2a`, user-confirmed + trace-verified):** the pending-bucket rescue above was necessary but NOT the whole cause. The real culprit: the per-frame avatar-sync (`GameWindow` ~:8018) calls `GpuWorldState.RelocateEntity` using the player controller's cell, which stays the **FROZEN SOURCE cell** until `PlaceTeleportArrival` materializes the destination. Mid-transit it dragged the avatar — which the teleport's `DrainRescued` re-inject had correctly placed at the destination center — back into the now-UNLOADED source landblock's pending bucket, where nothing recovers it (`RelocateEntity` only scans `_loaded`). Fix: skip the per-frame relocate while `_playerController.State == PortalSpace`. Verified by a new env-gated avatar-lifecycle probe (`ACDREAM_PROBE_ENT` / `EntityVanishProbe`): pre-fix `[ent] APPEND lb=0x0007FFFF(source) -> PENDING -> DRAWSET ABSENT` never recovered; post-fix every teleport goes `RESCUE -> ABSENT -> APPEND(destination) -> PRESENT` and stays drawn. **The remaining #138 collision residual split into #152 (Holtburg/building portal-in walls, DONE `49d743f`) + #151 (Arwic far-town frame, FIXED `9743537`).** (#146/#147 in this file are unrelated D.2b inventory-polish issues.)
**Acceptance:** portal out of the 0x0007 dungeon → full outdoor world streams (trees/scenery present), **server objects (doors/NPCs/portals) render**, **own avatar renders across repeated round-trips**, collision works, position tracks (no avatar-vs-camera desync).

View file

@ -7,6 +7,11 @@
## Current program: Phase W — Unified Cell Graph (UCG)
**[SUPERSEDED — G.3 dungeon work shipped; M1.5 next step = #138 round-trip
gate + #145-residual. See the shipped table + `docs/plans/2026-05-12-milestones.md`
M1.5 section for current status. This section's W1/W2a history below is kept
for record.]**
**Pivot (2026-06-02).** The render-pipeline reset stalled because the indoor "world from
below" is a cell-**membership** disagreement between the render-side `CellVisibility` and
the physics-side `ResolveCellId` — not any single draw gate (pixel-grounded evidence:
@ -99,6 +104,10 @@ W1 plan: [`docs/superpowers/plans/2026-06-02-unified-cell-graph-stage1.md`](../s
| Indoor walking Phase 2 — Portal-based cell tracking | 2026-05-19. Portal-graph traversal replaces Phase D's AABB containment. Six commits: `1969c55` CellBSP+Portals wired into CellPhysics; `aad6976` CellTransit.FindCellList + FindTransitCellsSphere + AddAllOutsideCells + ResolveCellId rename; `069534a` BuildingPhysics + CheckBuildingTransit for outdoor→indoor entry; `702b30a` code-review polish; `3ffe1e4` pass foot-sphere center to ResolveCellId (critical fix — was passing CheckPos instead of GlobalSphere[0].Origin, causing PointInsideCellBsp to return false at floor level); `eb0f772` TryFindIndoorWalkablePlane synthesizes walkable plane from cell floor poly so the resolver doesn't fall through to outdoor SampleTerrainWalkable. **Closes #87, #85, and the wall-pass-through portion of #84 (fully closes #84).** Files #88 (indoor static object vibration — pre-existing) and #89 (BSPQuery.SphereIntersectsCellBsp — approximation in CheckBuildingTransit). `[cell-transit]`, `[indoor-bsp]`, `[check-bldg]`, `[cell-cache]` probes stay in place. Handoff: [`docs/research/2026-05-19-indoor-walking-phase2-shipped-handoff.md`](../research/2026-05-19-indoor-walking-phase2-shipped-handoff.md). | Live ✓ |
| Indoor walking Phase A4 — Multi-cell BSP iteration | 2026-05-20. Ports retail's `CTransition::check_other_cells` (`acclient_2013_pseudo_c.txt:272717-272798`). After the primary cell's BSP returns OK, every other cell the foot-sphere overlaps is queried via `BSPQuery.FindCollisions`. Halt on first Collided/Adjusted/Slid; Slid clears the contact-plane fields. Three commits land the slices: `e6369e2` `CellTransit.FindCellSet` overload (refactor `FindCellList` to expose the candidate set); `493c5e5` `Transition.CheckOtherCells` + `ApplyOtherCellResult` combine helper; `691493e` (orig `967d065`, then `3add110` revert, then this reapply) wires `CheckOtherCells` into `FindEnvCollisions`. 10 new unit tests; 1139 + 8 baseline maintained. **Visual verification surfaced a separate, pre-existing M2 blocker:** at the Holtburg inn doorway the CellId ping-pongs between outdoor `0xA9B40022` and indoor vestibule `0xA9B40164` rapidly because indoor BSP push-back exits the indoor CellBSP volume → ResolveCellId reclassifies as outdoor → wall checks bypassed on outdoor ticks. Bug reproduces fully with A4 reverted (`launch-revert2.log`), confirming A4 is not the cause. A4 is correct and tested but **dormant in practice** until the ping-pong is fixed. Handoff: [`docs/research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md`](../research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md). Spec: [`docs/superpowers/specs/2026-05-20-phase-a4-multi-cell-bsp-design.md`](../superpowers/specs/2026-05-20-phase-a4-multi-cell-bsp-design.md). Plan: [`docs/superpowers/plans/2026-05-20-phase-a4-multi-cell-bsp.md`](../superpowers/plans/2026-05-20-phase-a4-multi-cell-bsp.md). | Live ✓ (dormant pending cell-tracking fix) |
| Phase O — DatPath Unification | 2026-05-21. ONE thing touches the DATs. Extracted ~33 WB files / ~7.7K LOC into `src/AcDream.{Core,App}/Rendering/Wb/`. Dropped project references to `WorldBuilder.Shared` + `Chorizite.OpenGLSDLBackend` from `AcDream.App.csproj` and `AcDream.Core.csproj`. `DefaultDatReaderWriter` eliminated; `DatCollection` is the only dat reader. `WbMeshAdapter` consumes it via `DatCollectionAdapter` (O-D7 fallback; `ObjectMeshManager` has 26 internal `_dats.*` call sites exceeding the 20-site inline-swap threshold). `references/WorldBuilder/` stays in-tree as read-reference. **Visual side-by-side passed**: Holtburg town, inn interior, dungeon all render identically to pre-O. `NOTICE.md` includes WB MIT attribution. Spec: [`docs/superpowers/specs/2026-05-21-phase-o-dat-path-unification-design.md`](../superpowers/specs/2026-05-21-phase-o-dat-path-unification-design.md). Audit: [`docs/superpowers/specs/2026-05-21-phase-o-t1-wb-audit.md`](../superpowers/specs/2026-05-21-phase-o-t1-wb-audit.md). Plan: [`docs/superpowers/plans/2026-05-21-phase-o-plan.md`](../superpowers/plans/2026-05-21-phase-o-plan.md). | Live ✓ |
| G.3 — Dungeon render/stream | Dungeon support shipped: the dungeon `LandBlock` is flat-terrain and streams through the existing pipeline (premise that terrain-less landblocks were unsupported was refuted at design time). Portal-graph visibility blowup closed (#95 RESOLVED, 9.1M→~39k instances, `a40c38e8`). | Live ✓ |
| G.3a — Teleport-into-dungeon | Hold-until-hydrate FSM: teleport-in no longer Resolves before the dungeon landblock hydrates. Closes #133. Commits `7947d7a` / `2ce5e5c8` / `47ae237e`. | Live ✓ |
| #137 — Dungeon collision | Dungeon BSP/collision fidelity fix. CLOSED 2026-07-08, user re-gate `0efa7ed2`. | Live ✓ |
| A7.L1 — Dungeon lighting | Indoor/dungeon lighting fidelity (#79/#93/#80/#154). CLOSED 2026-07-09, commits `d275ed55` / `9ebb2060` (see also `44cced71`). | Live ✓ |
Plus polish that doesn't get its own phase number:
- FlyCamera default speed lowered + Shift-to-boost
@ -525,7 +534,7 @@ Research: R9 + R12 + R13.
- **✓ SHIPPED — G.1 — Sky + weather + day-night.** Deterministic client-side from Portal Year time. Sky dome geometry + keyframe gradients + rain/snow particles. See `r12-weather-daynight.md`. Full data + visual stack shipped: Region dat loader, keyframe interp, WeatherSystem with 5-kind PDF + transitions + storm flashes, WorldSession→WorldTimeService sync via ConnectRequest+TimeSync, SkyRenderer with sky-object arcs + UV scroll, rain/snow billboard renderer, F7/F10 debug cycle keys.
- **✓ SHIPPED — G.2 — Dynamic lighting.** 8-light D3D-style fixed pipeline. Hard-cutoff at Range, no attenuation inside. Cell ambient. Shader UBO per frame. See `r13-dynamic-lighting.md`. SceneLightingUbo std140 at binding=1 feeds terrain + mesh + mesh_instanced + sky shaders. LightingHookSink auto-registers Setup.Lights at entity stream-in, flips IsLit on SetLightHook, unregisters on landblock unload.
- **Indoor portal-based cell tracking (follow-up to Indoor walking Phase 1 / issue #87).** Replace `PhysicsDataCache.TryFindContainingCell` AABB containment with retail's `CObjMaint::HandleObjectEnterCell` portal traversal. When the player crosses a cell portal boundary, `CellId` propagates through the `CEnvCell` portal connectivity graph. Prerequisite for wall collision from outside (#85) and the remaining #84 threshold symptom. PDB symbols and `acclient.h` `CCellStructure` refs are in place (see #87). **Unblocks G.3.**
- **G.3 — Dungeon streaming + portal space.** `EnvCellStreamer`, portal-visibility BFS, `PlayerTeleport (0xF751)` handling with `LoginComplete` re-send, "pink bubble" loading state. **Blocked on indoor portal-based cell tracking above** (and previously on L.2e) for trustworthy indoor/outdoor portal transit, adjacent-cell ownership, and building entry/exit collision boundaries. See `r09-dungeon-portal-space.md`.
- **✓ SHIPPED — G.3 — Dungeon streaming + portal space.** `EnvCellStreamer`, portal-visibility BFS, `PlayerTeleport (0xF751)` handling with `LoginComplete` re-send, "pink bubble" loading state. Dungeons render, stream, teleport-in, collide, light, and their doors work — see the shipped-table rows (G.3, G.3a, #137 collision, A7.L1 lighting) below and the M1.5 section of `docs/plans/2026-05-12-milestones.md` for current gate status (one recorded end-to-end round-trip user gate outstanding; live residual = far-town teleport-OUT arrival cascade, #145-residual REOPENED). See `r09-dungeon-portal-space.md`.
**Acceptance:** walk outside at dusk, see the sky gradient + sun moving; enter a torch-lit dungeon via portal; leave back to daylight.
@ -1318,7 +1327,7 @@ hitch and follows.
| Combat doesn't show in the chat log | **I.7 FIXED** ✓ |
| Accented character names show as `?` or garbled | **I.5 FIXED** ✓ (Windows-1252 codec) |
| No sound | **Phase E.2** |
| Dungeons / foundry interior missing | **Phase G.3** after **L.2e** cell/building ownership |
| Dungeons / foundry interior missing | **Phase G.3 — SHIPPED** (render/stream/teleport-in/collide/light/doors all closed; M1.5 next step = #138 round-trip gate + #145-residual) |
| Can't fight monsters | **Phase F.3** (combat math + damage) |
| Can't cast spells | **Phase F.4** |
| No inventory panel | **Phase F.2 + F.5** |

View file

@ -3,12 +3,18 @@
**Status:** Living document. Created 2026-05-12.
**Sits above:** [`docs/plans/2026-04-11-roadmap.md`](2026-04-11-roadmap.md) (the strategic phase index).
**Currently working toward:** **M1.5 — Indoor world feels right.** The
building/cellar demo is DONE + user-gated, but M1.5 was EXTENDED 2026-06-13
to include **dungeon support (full Phase G.3)** — dungeons don't work yet
(terrain-less dungeon landblocks aren't supported by the streaming/load
pipeline; issue #133). M1.5 does NOT land until dungeons work. M2 stays
deferred. (Correction: M1.5 was briefly marked landed 2026-06-13; the user
reverted that — the indoor world isn't done while dungeons are broken.)
building/cellar demo is DONE + user-gated. M1.5 was EXTENDED 2026-06-13 to
include **dungeon support (full Phase G.3)** — dungeons initially didn't
work at all (issue #133), but that premise was refuted at design time
(commit `90786c19`: the dungeon LandBlock is flat-terrain and streams via
the existing pipeline), and G.3 has since **SHIPPED**: dungeons render,
stream, teleport-in, collide, light, and their doors work — each piece
individually user-gated (#133/#137/#95/#79/#93/#80 all CLOSED). M1.5's
dungeon-demo scenario is functionally met; M1.5 stays 🔵 ACTIVE /
not-yet-landed, awaiting ONE recorded end-to-end dungeon round-trip user
gate. The sole remaining live-code residual is the far-town teleport-OUT
arrival cascade (**#145-residual, REOPENED** — capture-harness-first). M2
stays deferred.
---
@ -193,19 +199,25 @@ close range and the player sees "You pick up the X." in chat.
### M1.5 — "Indoor world feels right" — 🔵 ACTIVE (building/cellar demo DONE; EXTENDED 2026-06-13 to include dungeon support / Phase G.3)
**EXTENDED 2026-06-13 — dungeons pulled into M1.5 scope.** The
building/cellar demo (below) is DONE + user-gated, but attempting the
dungeon demo surfaced that dungeons don't work AT ALL: terrain-less
dungeon landblocks aren't supported anywhere in the streaming/load/
render/physics pipeline (`LandblockLoader.Load` returns null with no
`LandBlock` terrain record; the streamer fails with no terrain mesh; the
teleport snap Resolves before hydration — issue #133). The user decided
M1.5 is NOT done while the indoor world excludes dungeons, and chose the
**EXTENDED 2026-06-13 — dungeons pulled into M1.5 scope; G.3 SHIPPED.** The
building/cellar demo (below) is DONE + user-gated. Attempting the dungeon
demo initially surfaced that dungeons didn't work AT ALL — terrain-less
dungeon landblocks appeared unsupported anywhere in the streaming/load/
render/physics pipeline (`LandblockLoader.Load` returning null, no terrain
mesh, teleport snap Resolving before hydration — issue #133). That premise
was refuted at design time (commit `90786c19`: the dungeon `LandBlock` is
flat-terrain and streams via the existing pipeline). The user chose the
FULL Phase G.3 scope (dungeon streaming + portal-space loading screen +
multi-landblock dungeon LOD + `PlayerTeleport` handling). Design in
progress (`docs/superpowers/specs/` — dungeon-support spec). M1.5 lands
when: building/cellar demo (DONE) + dungeon demo (enter via portal,
navigate 3-5 rooms, walls block, smooth transitions) both pass.
multi-landblock dungeon LOD + `PlayerTeleport` handling), and it has since
**SHIPPED**: teleport-into-dungeon (G.3a hold-until-hydrate FSM closes
#133), dungeon collision (#137 CLOSED), the #95 portal-graph visibility
blowup (RESOLVED), dungeon doors (#187/#188), and A7 dungeon lighting
(#79/#93/#80/#154, all CLOSED). M1.5's dungeon-demo scenario (enter via
portal, navigate 3-5 rooms, walls block, smooth transitions) is
functionally met; M1.5 now awaits ONE recorded end-to-end dungeon
round-trip user gate. The sole remaining live-code residual is the
far-town teleport-OUT arrival cascade (**#145-residual, REOPENED** — see
below).
**Building/cellar demo — DONE + user-gated.** The indoor world reads as
solid. Across the
@ -222,8 +234,8 @@ closed); cell transitions are smooth (the doorway "flap" family killed —
#119/#128, #112, #113, #124, #129/#130/#131/#132, #108-residual, #127 all
closed with user gates). The #90-stickiness + `TryFindIndoorWalkablePlane`
synthesis workarounds were removed by A6.P4. Remaining feel-level debt is
tracked (#116 slide-response, partial Ghidra fix shipped; A7 indoor
lighting fidelity not yet done — folded forward).
tracked (#116 slide-response, partial Ghidra fix shipped). A7 indoor/
dungeon lighting fidelity CLOSED 2026-07-09 (#79/#93/#80/#154).
**Interleaved parity tracks (reconciled 2026-07-04 — NOT milestones).** Two
work streams have run alongside M1.5, both driven by the user's live
@ -259,16 +271,21 @@ as ad-hoc rework. Rule 2's freeze still binds all NON-MP work. MP runs in
dedicated side-track sessions; the M1.5 critical path wins every conflict,
and MP4 is hard-queued behind #137.
**Still OPEN in M1.5 — dungeon support (Phase G.3, issue #133).** Dungeons
don't work: the streaming/load/render/physics pipeline was built entirely
around outdoor landblocks (terrain + scattered buildings) and has no path
for terrain-less indoor-only dungeon landblocks. Confirmed gaps:
`LandblockLoader.Load` returns null with no `LandBlock` record; the
streamer fails with no terrain mesh; the teleport-arrival snap Resolves
before the dungeon hydrates → places the player in the old frame over
ocean. Full G.3 scope chosen by the user 2026-06-13 (streaming + portal-
space loading screen + multi-landblock LOD + `PlayerTeleport` handling).
Spec under `docs/superpowers/specs/`.
**Dungeon support (Phase G.3, issue #133) — SHIPPED.** The original
premise here (terrain-less dungeon landblocks unsupported anywhere in the
streaming/load/render/physics pipeline) was refuted at design time
(commit `90786c19`: the dungeon `LandBlock` is flat-terrain and streams
via the existing pipeline). Full G.3 scope (streaming + portal-space
loading screen + multi-landblock LOD + `PlayerTeleport` handling) has
shipped: teleport-into-dungeon (G.3a hold-until-hydrate FSM,
`7947d7a`/`2ce5e5c8`/`47ae237e`) closed #133; dungeon collision closed
#137 (`0efa7ed2`); the #95 portal-graph visibility blowup RESOLVED
(9.1M→~39k instances, `a40c38e8`); dungeon doors shipped (#187
`e2e285b8`, #188 `3284dd0a`); A7 dungeon lighting closed
(#79/#93/#80/#154, `44cced71`/`d275ed55`/`9ebb2060`). Remaining: one
recorded end-to-end dungeon round-trip user gate, plus the far-town
teleport-OUT arrival cascade residual (**#145-residual, REOPENED** —
capture-harness-first).
---
@ -302,8 +319,9 @@ M1.5's planned phases (A6 + A7) are unaffected.
"enter the Holtburg Sewer dungeon" but that location doesn't exist on
this ACE server (discovered during A6.P1 capture session). Additionally,
A6.P1 surfaced **issue #95** (portal-graph visibility blowup) which makes
ANY dungeon visually unusable on entry. Demo scenario revised in two
parts:
ANY dungeon visually unusable on entry. **[SUPERSEDED — #95 RESOLVED
(9.1M→~39k instances, `a40c38e8`); dungeons ship; see M1.5 section
above.]** Demo scenario revised in two parts:
**Building/cellar demo (achievable after A6.P3 lands):**
Walk into the Holtburg inn, climb to the 2nd floor, walk around without
@ -317,7 +335,8 @@ through. Throughout:
artifacts, static decorations participate in env lighting.
**Dungeon demo (blocked on issue #95 fix; promote to post-M1.5 if
the visibility bug isn't addressed in M1.5 scope):**
the visibility bug isn't addressed in M1.5 scope):** **[SUPERSEDED — #95
RESOLVED, dungeons ship; see M1.5 section above.]**
Enter any dungeon via portal (substitute for "Holtburg Sewer"). Navigate
~3-5 rooms without rendering corruption (no see-through-walls, no
other-dungeons-rendered-inside). Walls block, stairs work, items block,
@ -352,7 +371,7 @@ patch.
- **#83** — Indoor multi-Z walking broken (cellars, 2nd floors, intermittent falling-stuck)
- **#88** — Indoor static objects vibrate (suspected sub-step state corruption — A6.P2 maps to Finding 2 family)
- **#90** — CellId ping-pong (workaround in place; remove during A6.P4)
- **#95** — Portal-graph visibility blowup (filed 2026-05-21; **blocks the dungeon half of the M1.5 demo** but is NOT in A6 scope; either add a dedicated phase inside M1.5 to fix it OR promote the dungeon demo to post-M1.5)
- **#95** — Portal-graph visibility blowup (filed 2026-05-21; **blocks the dungeon half of the M1.5 demo** but is NOT in A6 scope; either add a dedicated phase inside M1.5 to fix it OR promote the dungeon demo to post-M1.5) **[SUPERSEDED — RESOLVED, 9.1M→~39k instances, `a40c38e8`; dungeons ship; see M1.5 section above.]**
- **L-indoor** — Lighting indoors broken (file as new # during M1.5 kickoff)
- **L-spotlight** — Items projecting spotlight on walls (file as new # during M1.5 kickoff)
- **Stairs walk-through** — captured + characterized by A6.P2 (Finding 2 family); fix in A6.P3