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

4.9 KiB
Raw Blame History

Handoff — indoor lighting DONE; NEXT: #145 portal re-use, then #144 dungeon dimness

Date: 2026-06-20 Branch: claude/thirsty-goldberg-51bb9bcommitted, 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 (0xXXYY0000) instead of the streaming key 0xXXYYFFFF, 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 lightSmartBox::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 attenuationconfig_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 dungeonworld_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).