acdream/docs/research/2026-06-20-indoor-lighting-done-next-portal-reuse-handoff.md
Erik f6a576af8e docs: file #145 (portals work once/session) + session handoff (next: #145 then #144)
Indoor lighting DONE this session (#142/#143 closed). Per user: do NOT merge to
main; start fresh next session. NEXT-session order set in the handoff:
1. #145 — portals only work once per session (run in/out/re-enter repeatedly).
   Machinery: 0xF751 PlayerTeleport -> PortalSpace -> TeleportArrivalController ->
   streaming collapse/expand. Likely overlaps #138. Instrument a 2nd teleport first.
2. #144 — dungeon interiors still too dim vs retail (cdb side-by-side first).

Handoff: docs/research/2026-06-20-indoor-lighting-done-next-portal-reuse-handoff.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 18:31:47 +02:00

94 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Handoff — indoor lighting DONE; NEXT: #145 portal re-use, then #144 dungeon dimness
**Date:** 2026-06-20
**Branch:** `claude/thirsty-goldberg-51bb9b`**committed, NOT merged to main, NOT pushed** (user's call)
**Milestone:** M1.5 "Indoor world feels right"
---
## What shipped this session (on the branch, not pushed)
The entire indoor-lighting saga. **#142 + #143 CLOSED, user-confirmed.**
| Commit | What |
|---|---|
| `ef5049f` | #142 per-instance sun gate (indoor objects skip the sun, per-draw like retail) |
| `0d8b827` | **THE root-cause fix** — EnvCellRenderer landblock-key bug + viewer light + weenie fixture lights |
| `57c2ab7` | #143 dynamic-light D3D `1/d` attenuation (portal + viewer spread softly) |
| `653e7f3` | docs: close #142/#143, file #144 |
| (this) | docs: file #145 + this handoff |
**One-line story:** interiors were dark NOT because of the sun/ambient (those were
already retail-faithful — the 0.2-flat/sky split == `CellManager::ChangePosition`
0x004559B0). The real bug was a landblock-key lookup in
`EnvCellRenderer.GetCellLightSet`: it keyed `_landblocks` by `cellId & 0xFFFF0000`
(0xXXYY**0000**) instead of the streaming key 0xXXYY**FFFF**, so the lookup missed
for EVERY cell → `SelectForObject` never ran → every interior wall got ZERO point
lights, always. Fix: `(cellId & 0xFFFF0000) | 0xFFFF`. Found by a `[cell-light]`
probe (inBounds=False selected=0 → True selected=3-4) after 3+ speculative fixes.
Retail mechanisms ported alongside it (all faithful, decomp-cited):
- **Viewer light** — `SmartBox::set_viewer` 0x00452c40: white fill pinned to the
player every frame; `1/d` att, range 15. `LightManager.UpdateViewerLight`.
- **Weenie fixture lights** (AP-44) — server-object `Setup.Lights` registered on
spawn (`OnLiveEntitySpawnedLocked`); the meeting-hall portal's magenta light
rides this → #143 lit "for free."
- **Dynamic vs static attenuation** — `config_hardware_light` 0x0059ad30:
dynamic = `1/d` + range×1.5; static = `1/d³` + range×1.3. Per-light `IsDynamic`
flag packed into `GlobalLight.coneAngleEtc.y`.
Register: AP-43 (#142 sun gate), AP-44 (weenie lights), AP-47 (acdream's always-lit
interiors vs retail's 40-light pop-in — INTENTIONAL). Full lighting detail:
memory `reference_retail_ambient_values.md` (2026-06-20 resolution note).
**Suites:** Core 1505 / App 476 green.
---
## NEXT SESSION — in this order
### 1. FIRST — #145: portals only work once per session (HIGH)
User wants: **run into a portal, run out, re-enter — repeatedly.** Currently only the
FIRST teleport works; the second portal use does nothing.
- **Machinery:** `WorldSession.cs:999` (0xF751 PlayerTeleport) → `PlayerMovementController`
`PlayerState.PortalSpace` (`:75`/`:840`) → `TeleportArrivalController` (`Phase`
Idle/Holding; the placement delegate flips PortalSpace back to InWorld) →
`GameWindow.cs:4903/5332/5362` (PortalSpace observer + arrival placement) →
streaming collapse↔expand (#133/#135 machinery).
- **First step (don't guess):** instrument a SECOND teleport and find WHERE it stalls —
does the 2nd 0xF751 arrive? does PortalSpace toggle back to InWorld? does
`TeleportArrivalController.Tick` place via `PlaceTeleportArrival`? does the streaming
window re-expand? One probe across those four points pins it.
- **Likely overlaps #138** (teleport OUT of a dungeon loads the outdoor world
incompletely) — may be the same root or a sibling; check together.
### 2. THEN — #144: dungeon interiors still too dim vs retail (MEDIUM)
Dungeons improved (torch cells light up now — the landblock-key fix + viewer fill), but
torch-sparse stretches + overall brightness still trail retail (user: "better but not
good enough").
- **Approach:** side-by-side **cdb capture of retail's dungeon**`world_lights`
active set + `world_lights.ambient_color` + the viewer-light intensity at the SAME
spot — vs acdream's `[light]`/`[light-detail]` there. Do NOT guess.
- **Candidates:** per-vertex Gouraud bake under-lights low-poly dungeon walls (AP-35
residual); the sealed-dungeon flat 0.2 ambient too dark; retail leans harder on the
viewer light / carries more dynamics.
---
## Launch / probes
`testaccount2` / `testpassword2` (character Horan, spawns near Holtburg; reaches the
0x0007 Town Network dungeon). Canonical launch + `ACDREAM_PROBE_LIGHT=1` +
`ACDREAM_PROBE_CELL=1``[light]` / `[light-detail]` / `[cell-transit]`. The
`[cell-light]` per-cell probe was STRIPPED (the bug it found is fixed) — re-add a
per-cell light probe in `EnvCellRenderer.GetCellLightSet` if #144 needs it.
## Pointers
- memory `reference_retail_ambient_values.md` — lighting resolution + the cdb toolchain.
- `docs/architecture/retail-divergence-register.md` — AP-43 / AP-44 / AP-47.
- `docs/ISSUES.md`#144, #145, #138 (related), #137 (dungeon collision).
- cdb toolchain: CLAUDE.md "Retail debugger toolchain" (binary matches `refs/acclient.pdb`).