diff --git a/CLAUDE.md b/CLAUDE.md index 6aa36681..e9cfe49e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -109,9 +109,11 @@ movement queries. ## Current state **Currently working toward: M1.5 — Indoor world feels right** (building/cellar demo -DONE + gated; **#137 dungeon collision CLOSED, A7 dungeon lighting #79/#93 CLOSED -2026-07-09** — two root causes fixed + user-reverified 2nd-floor case; REMAINING -critical path = **#138 teleport-OUT**). One **user-report-driven +DONE + gated; dungeons now navigable end-to-end — **#133/#137/#95/#79/#93/#80 all +CLOSED** (A7 lighting fixed, user-reverified). REMAINING = one recorded dungeon +round-trip user gate (**#138 ESSENTIALLY RESOLVED** in code — see +`docs/ISSUES.md`); sole live residual = far-town teleport-OUT arrival cascade +(**#145-residual, REOPENED** — capture-harness-first). One **user-report-driven parity track** still interleaves at the issue level (NOT a milestone; see the M1.5 note in the milestones doc): **D.2b retail UI** (next: container-switching — `claude-memory/project_d2b_retail_ui.md`). The **R5 movement-manager arc is DONE** diff --git a/docs/ISSUES.md b/docs/ISSUES.md index 989ad815..144a61a2 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -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). diff --git a/docs/plans/2026-04-11-roadmap.md b/docs/plans/2026-04-11-roadmap.md index f2a2d4c6..273bc07e 100644 --- a/docs/plans/2026-04-11-roadmap.md +++ b/docs/plans/2026-04-11-roadmap.md @@ -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** | diff --git a/docs/plans/2026-05-12-milestones.md b/docs/plans/2026-05-12-milestones.md index 7d3286f6..4f9e4c7b 100644 --- a/docs/plans/2026-05-12-milestones.md +++ b/docs/plans/2026-05-12-milestones.md @@ -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