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>
This commit is contained in:
Erik 2026-06-20 18:31:47 +02:00
parent 653e7f380f
commit f6a576af8e
2 changed files with 111 additions and 0 deletions

View file

@ -46,6 +46,23 @@ Copy this block when adding a new issue:
---
## #145 — Portals only work once per session (can't run in, run out, re-enter)
**Status:** OPEN
**Severity:** HIGH (blocks repeated portal/dungeon travel — user, 2026-06-20)
**Filed:** 2026-06-20
**Component:** net/streaming — teleport (0xF751) + PortalSpace + arrival
**Description (user, 2026-06-20):** A portal can only be used ONCE per session. The first teleport works (run into a portal); a subsequent portal use (run out again, or re-enter) does not. Goal: run into a portal, run out again, repeatedly — portals usable any number of times in one session.
**Root cause / status (UNVERIFIED):** Likely a stuck teleport-state issue — after the first 0xF751 PlayerTeleport (PortalSpace hold → `TeleportArrivalController` places → back to InWorld), some state isn't reset for the second teleport: candidates are PortalSpace not cleared, the arrival `Phase` stuck at `Holding`, a cell-membership/streaming gap, or the dungeon collapse↔expand state (#133/#135 machinery). Likely overlaps **#138** (teleport OUT of a dungeon loads incompletely) — may be the same root or a sibling. **First step:** instrument a SECOND teleport and find WHERE it stalls (does the 0xF751 arrive? does PortalSpace toggle? does `TeleportArrivalController.Tick` place? does the streaming window re-expand?).
**Files:** `WorldSession.cs:999` (0xF751 handler); `PlayerMovementController.cs:75/840` (`PlayerState.PortalSpace`); `TeleportArrivalController.cs` (`Phase` Idle/Holding, the placement flip); `GameWindow.cs:4903/5332/5362` (PortalSpace observer + arrival placement); streaming collapse↔expand (see #138).
**Acceptance:** run into a portal, run out, re-enter — repeatedly in one session, each time placing + streaming correctly.
---
## #144 — Dungeon interiors still read too dim vs retail (torch-sparse stretches + per-vertex bake)
**Status:** OPEN

View file

@ -0,0 +1,94 @@
# 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`).