docs: roadmap + ISSUES.md — Phase 2 indoor cell rendering closure

- Roadmap shipped-table: two new rows for Phase 1 (diagnostics) +
  Phase 2 (fix). Header status block updated to 2026-05-19 with the
  Phase 2 cause + fix one-liner and pointer to the 9 surfaced issues.
- ISSUES.md: filed nine new issues (#78-#86) covering the indoor
  bugs the user observed once the floor rendered. Grouped under an
  "Indoor walking issue cluster" header. Cross-references the Phase 1
  + Phase 2 work that surfaced them. Hypotheses + suspected root
  causes documented for each.

The 9 issues split into two probable shared-cause groups:
- Cell BSP / portal cull (#78, #84, #85, #86) — likely fixable in
  one phase.
- Indoor lighting plumbing (#79, #80, #81, #82) — needs separate
  investigation per-symptom.

Plus #83 (stairs) which probably needs its own physics phase work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-19 13:17:08 +02:00
parent 73288657fd
commit 98977b8f66
2 changed files with 278 additions and 2 deletions

View file

@ -46,7 +46,281 @@ Copy this block when adding a new issue:
# Active issues
## #76 — [DONE 2026-05-16 · `0b25df5`] LiveSessionController extraction (Step 2) regresses interaction + chat outbound
---
## Indoor walking issue cluster (2026-05-19)
The Phase 2 indoor cell rendering fix (floor now renders inside buildings)
surfaced nine pre-existing indoor bugs the user observed at Holtburg Inn
the moment they could walk indoors. None caused by the floor fix — all
existed before but were unobservable because there was no floor to stand
on. Filed individually below; #78 + #84 + #85 + #86 likely share a root
cause (cell BSP / portal-cull plumbing), and #79 + #80 + #81 + #82 share
the indoor-lighting plumbing.
---
## #78 — Outdoor stabs/buildings visible through the rendered floor
**Status:** OPEN
**Severity:** HIGH (immediate visual jank now that floors render)
**Filed:** 2026-05-19
**Component:** rendering, visibility
**Description:** Standing inside Holtburg Inn looking at the floor or
walls, the user sees other buildings in the distance at their correct
world position + scale — but visible THROUGH the floor and walls. As if
the cell mesh is rendered but doesn't occlude or stencil-cull what's
behind it.
**Root cause / status:** Two plausible causes:
1. The `+0.02f` Z bump applied to cell origin at `GameWindow.cs:5362`
pushes the floor mesh 2 cm above terrain, so depth test correctly
occludes terrain. But OUTDOOR STABS (landblock-baked building geometry)
at the same X,Y may have Z values comparable to or higher than the
cell-mesh floor, producing z-fighting / see-through.
2. Outdoor stabs aren't being culled when the player is inside an
EnvCell — this is the Phase 1 Task 3 deferred work
("Cull outdoor stabs when indoors via VisibleCellIds"). WB has a
`RenderInsideOut` stencil pipeline (`references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/VisibilityManager.cs`)
that acdream never invokes.
**Files:**
- `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs` (per-entity walk —
consider gating outdoor stab entities on visible-cell membership).
- `src/AcDream.App/Rendering/CellVisibility.cs:222+` (`ComputeVisibility`
returns `VisibleCellIds`; the dispatcher already filters by
`entity.ParentCellId ∈ visibleCellIds` but outdoor stabs have
`ParentCellId == null` so they always pass).
**Acceptance:** Standing inside a sealed-interior cell, no outdoor
geometry is visible through floor/walls. Standing where a cell has a
real outdoor portal (door open, window) outdoor geometry is correctly
visible through the portal.
---
## #79 — Indoor lighting: spurious spot lights on walls
**Status:** OPEN
**Severity:** MEDIUM
**Filed:** 2026-05-19
**Component:** lighting
**Description:** Walking around inside Holtburg Inn, the user sometimes
sees spot-light-like patches on the interior walls that don't correspond
to retail's lighting.
**Root cause / status:** Point lights from cell static objects (torch
entities) are being registered via `LightInfoLoader.Load` + `LightingHookSink`
(Phase 1 verified). Their per-light parameters (position, range, intensity,
cone) may be wrong — wrong falloff treatment, wrong world-space transform,
or wrong direction for spot lights. Spec at
`docs/research/deepdives/r13-dynamic-lighting.md` documents the retail
LightInfo→LightSource mapping but the live behavior hasn't been verified
against retail.
**Files:**
- `src/AcDream.Core/Lighting/LightInfoLoader.cs`
- `src/AcDream.App/Rendering/Shaders/mesh_modern.frag``accumulateLights`
spot-cone logic.
**Acceptance:** Side-by-side comparison with retail at the inn shows
matching torch-light pools.
---
## #80 — Camera on 2nd floor goes very dark
**Status:** OPEN
**Severity:** MEDIUM
**Filed:** 2026-05-19
**Component:** lighting
**Description:** Walking up to the second floor of a building, the
lighting suddenly goes much darker than retail.
**Root cause / status:** Possible causes:
1. The `playerInsideCell` lighting trigger (Phase 1 / commit `1024ba3`)
uses `CellVisibility.IsInsideAnyCell(playerPos)` which is a brute-force
PointInCell scan. The 2nd floor cell may not be in the loaded set OR
may have wrong bounds.
2. The per-cell ambient is currently a flat `(0.20, 0.20, 0.20)` for
any indoor cell. Retail has per-cell ambient overrides; ours doesn't
read them. A 2nd-floor cell with stairwell shadowing may need a
different value.
**Files:**
- `src/AcDream.App/Rendering/GameWindow.cs:8330+` (`UpdateSunFromSky`,
indoor branch).
**Acceptance:** 2nd-floor cells render with similar brightness to
ground floor; transition is not abrupt.
---
## #81 — Static building stabs don't react to atmospheric lighting changes
**Status:** OPEN
**Severity:** MEDIUM
**Filed:** 2026-05-19
**Component:** lighting, rendering
**Description:** Outside, time-of-day changes (sunrise/sunset/lightning)
don't visibly affect static building stabs (the inn / cottages). The
buildings stay statically lit while terrain and scenery shift colors.
**Root cause / status:** Stabs are rendered through `WbDrawDispatcher`
with `mesh_modern.frag` which DOES consume the `SceneLightingUbo`
(sun + ambient + fog). Verify the shader is being used for stabs and
that the UBO is bound at the right binding slot per draw call.
Possibly a shader-path divergence — terrain uses `terrain_modern.frag`,
entities use `mesh_modern.frag`, but stabs/scenery may be on a
different path.
**Files:**
- `src/AcDream.App/Rendering/Shaders/mesh_modern.frag`
- `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs`
**Acceptance:** Stabs darken/brighten in sync with terrain + scenery
across the day/night cycle.
---
## #82 — Some slope terrain lit incorrectly
**Status:** OPEN
**Severity:** LOW (cosmetic)
**Filed:** 2026-05-19
**Component:** rendering, terrain
**Description:** Specific terrain slopes appear lit "wrong" compared to
retail.
**Root cause / status:** Likely terrain normal calculation or the
landblock-edge normal-blending divergence between WB and retail (per
`feedback_wb_migration_formulas.md` — WB's terrain split formula
differs from retail's `FSplitNESW`).
**Files:**
- `src/AcDream.App/Rendering/TerrainModernRenderer.cs`
- `src/AcDream.App/Rendering/Shaders/terrain_modern.frag`
**Acceptance:** Side-by-side comparison with retail at the same Holtburg
slopes shows matching shading.
---
## #83 — Walking up stairs broken
**Status:** OPEN
**Severity:** HIGH (blocks vertical indoor traversal)
**Filed:** 2026-05-19
**Component:** physics, movement
**Description:** When the player tries to walk up stairs inside a
building, movement is broken — gets stuck, gets bounced, or fails to
ascend.
**Root cause / status:** The retail physics has explicit step-up logic
(`CPhysicsObj::step_up` etc.) ported into `PhysicsEngine` for outdoor
terrain ramps. For indoor stairs (EnvCell CellStruct geometry composed
of polygons), the step-up resolver may not be examining cell BSP
correctly, OR cell BSP and cell mesh disagree on stair Z values.
**Files:**
- `src/AcDream.Core/Physics/PhysicsEngine.cs`
- `src/AcDream.Core/Physics/TransitionTypes.cs` (cell BSP query path).
**Acceptance:** Walking forward at the base of an inn stairwell ascends
to the second floor without getting stuck.
---
## #84 — Blocked by air indoors
**Status:** OPEN
**Severity:** HIGH (blocks indoor navigation)
**Filed:** 2026-05-19
**Component:** physics, collision
**Description:** While walking inside buildings, the player sometimes
collides with invisible obstacles in mid-floor where there's nothing
visible.
**Root cause / status:** Cell BSP geometry doesn't align with the
visible cell mesh. Possibilities:
1. The `cellTransform` applied to physics in
`_physicsDataCache.CacheCellStruct(envCellId, cellStruct, cellTransform)`
at `GameWindow.cs:5384` includes the `+0.02f` Z bump, but the BSP
geometry may not be lifted with it — physics geometry sits 2cm BELOW
render geometry, so invisible "ceilings" at floor-level cause
blockage.
2. CellStruct BSP contains polygons that the cell mesh doesn't include
(or vice versa) — the two are derived from different fields.
**Files:**
- `src/AcDream.App/Rendering/GameWindow.cs:5362-5384` (cellOrigin Z bump
+ physics cache call).
**Acceptance:** Walking through interior cell space hits collisions
only where visible walls/furniture exist.
---
## #85 — Pass through walls from outside→in
**Status:** OPEN
**Severity:** HIGH (gameplay-breaking)
**Filed:** 2026-05-19
**Component:** physics, collision
**Description:** Approaching a building from the outside, the player
can walk THROUGH walls into the interior — one-directional wall
collision. From the inside trying to exit, the wall does block.
**Root cause / status:** Cell BSP polygons likely have one-sided
normals (front-facing only). Approach from the inside hits the front;
approach from the outside hits the back which BSP traversal treats as
"behind the plane" → no collision. Retail handles this via two-sided
collision polys or per-poly back-face handling.
**Files:**
- `src/AcDream.Core/Physics/BSPQuery.cs`
- `src/AcDream.Core/Physics/TransitionTypes.cs` (`FindObjCollisions` cell
branch).
**Acceptance:** Walking into an inn wall from outside collides; player
must enter via the door portal.
---
## #86 — Click selection penetrates walls
**Status:** OPEN
**Severity:** MEDIUM
**Filed:** 2026-05-19
**Component:** input, interaction
**Description:** Clicking through a wall from the outside selects NPCs
and objects inside the building. The `WorldPicker` raycast doesn't
intersect cell BSP geometry.
**Root cause / status:** `WorldPicker.BuildRay + Pick` (introduced in
Phase B.4) tests against entity AABBs and scenery BSPs but probably
not cell BSP. Outdoor NPCs are pickable because their entity AABB is
the test target; indoor NPCs are pickable from outside because the
wall isn't in the ray's intersection set.
**Files:**
- `src/AcDream.App/Rendering/WorldPicker.cs` (or equivalent — check
Phase B.4b reference).
**Acceptance:** Clicking on a wall doesn't select NPCs behind it.
---
**Status:** DONE
**Severity:** MEDIUM (refactor blocker; doesn't affect main branch which is unchanged)