diff --git a/docs/ISSUES.md b/docs/ISSUES.md index 32cf3ce..8d4baee 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -46,6 +46,86 @@ Copy this block when adding a new issue: # Active issues +## #76 — LiveSessionController extraction (Step 2) regresses interaction + chat outbound + +**Status:** OPEN +**Severity:** MEDIUM (refactor blocker; doesn't affect main branch which is unchanged) +**Filed:** 2026-05-16 +**Component:** app / refactor (Step 2 of `docs/architecture/code-structure.md` §4) + +**Description:** A first attempt at Step 2 — extracting `LiveSessionController` +out of `GameWindow.cs` — was implemented and reverted in the same session +on the `claude/hungry-tharp-b4a27b` worktree. Visual verification at +Holtburg revealed: + +- Chat input field accepts text + Enter but nothing is sent (no echo, no + ACE response). +- Double-click on doors / NPCs fires `[B.4b] use guid=... seq=N` outbound + (verified in `launch.log`) but no visible client-side effect (door doesn't + swing, NPC doesn't dialogue). +- R + click-target produces `[B.4b] use-deferred guid=... seq=N`, the + player auto-walks to the target, but the deferred Use does NOT fire on + arrival (regresses the Phase B.6 / issue #63 / #75 work). + +The Step 1 (`eda936d` RuntimeOptions) and Rule 5 follow-up +(`32423c2` DumpSteepRoof → PhysicsDiagnostics) commits are NOT affected +and stay clean. + +**Root cause / status:** Unknown. The refactor preserved every event +subscription line-for-line (verified by `git diff` — only one `_liveSession.X +=` +line moved, all others present). The new shape: + +``` +TryStartLiveSession() + → _liveSessionController.CreateAndWire(_options, WireLiveSessionEvents) + → new WorldSession(endpoint) + → wireEvents(session) // i.e. WireLiveSessionEvents(session) + → Chat.OnSystemMessage("connecting...") + → _liveSession.Connect(user, pass) + → ...character validation + EnterWorld + post-setup... +``` + +Looks identical to the original control flow. Hypotheses to test on a +clean re-attempt: + +1. **Timing of `_liveSession` field assignment.** The new code assigns + `_liveSession` inside `WireLiveSessionEvents` before subscriptions + run, and again after CreateAndWire returns. The original code set + `_liveSession` once at the inline `new WorldSession(...)` site. A + subtle ordering bug between subscriptions and `_liveSession`'s + externally visible state may matter. +2. **LiveCommandBus closure capture.** The `var liveSession = _liveSession;` + capture inside the chat handler block may have been getting a + different value than before — though the field IS set by the time + the capture happens (line 1 of `WireLiveSessionEvents`). +3. **Inbound packet ordering.** ACE may be sending the first + StateUpdate / spawn stream BEFORE the EnterWorld dance completes in + the new flow; if subscriptions are wired but `_liveSession` field + is briefly inconsistent, an early handler call could see a partial + state. The `_liveSession?.Tick()` route now goes through + `_liveSessionController?.Tick()`; verify that's not the difference. +4. **Some non-subscription side effect** in `WireLiveSessionEvents` + that wasn't carried over correctly — over-indentation suggests a + diff-friendly intermediate state; full re-indentation may surface + the bug. + +**Files (in the reverted state — recover from worktree git reflog or +re-write):** +- `src/AcDream.App/Net/LiveSessionController.cs` (new, ~115 LOC) +- `src/AcDream.App/Rendering/GameWindow.cs` — `TryStartLiveSession` split + + new `WireLiveSessionEvents` method + +**Research:** No memory entry yet. If the re-attempt succeeds, add a +`feedback_step2_extraction_pitfalls.md` capturing whichever hypothesis +turned out to be the bug. + +**Acceptance:** Step 2 lands when the full M1 demo loop (walk Holtburg, +double-click inn door + door swings, double-click NPC + NPC dialogues, +F-key pickup on a ground item) works identically to the pre-refactor +behavior, AND chat input echoes back through the panel. + +--- + ## #75 — [DONE 2026-05-16 · `f035ea3`] Auto-walk should drive body directly, not synthesize player-input **Status:** DONE