acdream/docs/research/2026-05-19-indoor-followup-handoff.md
Erik b04ad448fa docs(handoff): indoor follow-up brief + fresh-session kickoff prompt
After Phase 1+2 (indoor cell rendering — missing floors fixed),
9 follow-up issues (#78-#86 in docs/ISSUES.md) need their own
phases. This handoff doc gives the next session everything it needs
to start cold: probe infrastructure status, issue cluster groupings,
suggested phase order, and the verification approach that worked
for Phase 1+2.

Companion prompt file is a self-contained kickoff that can be pasted
into a fresh Claude Code session to start work on the cluster.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:36:18 +02:00

6.8 KiB

Indoor cell rendering — follow-up handoff

Status: Phase 1 (diagnostics) + Phase 2 (fix for missing floors) shipped 2026-05-19. Merged to main. The 9 new bugs surfaced when floors started rendering are filed as docs/ISSUES.md#78 through #86.

This doc is the start-of-session brief for whoever picks up the next indoor-walking phase.


What's in place

Diagnostic infrastructure (Phase 1)

Five [indoor-*] probes are wired and on a runtime-toggleable flag — leave them in place; they're useful for any indoor follow-up work:

Probe Where Toggle
[indoor-walk] WbDrawDispatcher.WalkEntitiesInto per cell entity that passes visibility ACDREAM_PROBE_INDOOR_WALK=1 or DebugPanel checkbox
[indoor-cull] Same site, when entity is rejected (visibleCellIds-miss or frustum) ACDREAM_PROBE_INDOOR_CULL=1
[indoor-upload] WbMeshAdapter.IncrementRefCount + Tick() for EnvCell ids ACDREAM_PROBE_INDOOR_UPLOAD=1
[indoor-lookup] WbDrawDispatcher.Draw per-MeshRef TryGetRenderData call ACDREAM_PROBE_INDOOR_LOOKUP=1
[indoor-xform] Same site, for cellGeomId SetupPart's composed world matrix ACDREAM_PROBE_INDOOR_XFORM=1

Master toggle: ACDREAM_PROBE_INDOOR_ALL=1 cascades to all five. All probes are zero-cost when off.

The WbMeshAdapter also now injects a ConsoleErrorLogger<ObjectMeshManager> (replacing the default NullLogger) so any future exception WB silently catches surfaces as [wb-error] lines automatically. This was the key unlock for Phase 2's diagnosis — see feedback_logger_injection_for_silent_catches memory entry.

Other Phase 1/2 fixes already in main

  • Indoor ambient color is now retail-faithful (0.20, 0.20, 0.20) — was guessed (0.10, 0.09, 0.08).
  • Indoor lighting triggers off player cell, not camera cell — fixes "darker when camera enters" with third-person chase.
  • WB submodule patched (ObjectMeshManager.cs:1230 Setup-prefix guard at TryGet<Setup>). Lives on eriknihlen/WorldBuilder@acdream at SHA 34460c4. Submodule pointer in acdream's main advanced.

The 9 follow-up issues

Full descriptions + hypotheses are in docs/ISSUES.md. Summary table:

# Title Cluster Severity
#78 Outdoor stabs/buildings visible through floor Cell-BSP / visibility HIGH
#79 Spurious spot lights on walls indoors Indoor lighting MEDIUM
#80 2nd floor camera goes very dark Indoor lighting MEDIUM
#81 Static building stabs don't react to atmospheric lighting Indoor lighting MEDIUM
#82 Some slope terrain lit incorrectly Terrain shading LOW
#83 Walking up stairs broken Physics / movement HIGH
#84 Blocked by air indoors Cell-BSP / collision HIGH
#85 Pass through walls from outside→in Cell-BSP / collision HIGH
#86 Click selection penetrates walls Cell-BSP / interaction MEDIUM

Proposed phase groupings:

  • Cluster A: Cell-BSP + portal cull — likely fixes #78, #84, #85, #86 in one phase. Shared root cause hypothesis: the cell BSP physics geometry isn't being correctly used by the movement resolver / WorldPicker / depth-cull. Common pieces:

    • _physicsDataCache.CacheCellStruct at GameWindow.cs:5384 caches with cellTransform (including +0.02f Z bump for render anti-z-fight) — physics may be misaligned.
    • WB's VisibilityManager.RenderInsideOut stencil pipeline is unused by acdream — explains #78.
    • WorldPicker raycast doesn't test cell BSP — explains #86.
    • Wall BSP polys likely one-sided — explains #85.
  • Cluster B: Indoor lighting plumbing — #79, #80, #81 each need separate investigation but share the mesh_modern.frag + SceneLightingUbo pipeline. #82 may be terrain-shader-specific.

  • Standalone: #83 stairs — needs the existing physics step-up logic to handle EnvCell stair geometry. Could share work with Cluster A if cell BSP is the common path.

Suggested order:

  1. Cluster A first. Biggest gameplay impact (collision is broken). Probably 1-2 weeks of work.
  2. #83 stairs as a follow-up once cell BSP collision is solid.
  3. Cluster B lighting last. Smallest gameplay impact, biggest visual polish.

Where to start a new session

The recommended kickoff prompt is at docs/research/2026-05-19-indoor-followup-prompt.md. Drop it into a fresh Claude Code session in this repo and it should orient itself.

Key files to point Claude at when starting:

  • This handoff doc.
  • docs/ISSUES.md lines covering #78-#86 (search for "Indoor walking issue cluster").
  • docs/research/2026-05-19-indoor-cell-rendering-cause.md — Phase 2 cause analysis, useful as the "what we already know" anchor for any follow-up.
  • docs/research/2026-05-19-indoor-cell-rendering-verification.md — what's working today.

Important context

  • Don't touch the diagnostic infrastructure in WbMeshAdapter or RenderingDiagnostics unless you're extending it. Phase 2 left it ready for re-use.
  • The probes are runtime-toggleable — DebugPanel has checkboxes. No relaunch needed to flip them.
  • ConsoleErrorLogger is now the default WB logger. Any future WB-internal exception will surface as [wb-error] automatically without any new diagnostic code.
  • Don't try to patch WB upstream — the user wants the fix to live only in their fork (eriknihlen/WorldBuilder). Future WB patches go on the acdream branch of the fork.
  • The +0.02f Z bump on cell origin at GameWindow.cs:5362 exists to prevent z-fighting with terrain. It's applied to both render geometry AND physics BSP. May be a confounding factor for #84 (blocked by air).

Verification approach for the next phase

Same pattern that worked for Phase 1+2:

  1. Diagnostics first. Add probes / log surfaces for the suspected failure paths. The ConsoleErrorLogger may already be surfacing relevant errors — check launch.log first.
  2. Capture cold. Launch the client (the Phase 1 + Phase 2 launch incantation is documented at the top of CLAUDE.md), walk into Holtburg Inn, take note of the user-observable symptom (e.g., "I'm at position X, I tried to walk through a wall and went through").
  3. Identify the root cause definitively. Don't apply a fix until the captured data points at one specific code site.
  4. Apply a surgical fix. Per CLAUDE.md's no-workarounds rule — fix the actual cause, not the symptom.
  5. Re-capture and verify. Visual confirmation by the user is the acceptance test.

Phase 1+2 took 4 client launches total once the diagnostic infrastructure was in place. The Cluster A phase should be similar — assuming the cell-BSP hypothesis holds, one probe addition + one capture should pin the root cause.