Commit graph

10 commits

Author SHA1 Message Date
Erik
7593078774 refactor(runtime): move session lifetime and ordered transport
Move the canonical WorldSession generation, connect/enter/tick/stop transaction, inbound subscription owner, and retryable teardown acknowledgements into AcDream.Runtime. Keep App as a borrowing graphical host with a single inertable command projection and no mirrored session state.

Validated by 79 Runtime tests, 3,776 App tests with three existing skips, the Release solution build, and 8,428 complete Release tests with five existing skips.

Co-authored-by: Codex <codex@openai.com>
2026-07-25 19:39:24 +02:00
Erik
3f1548b952 fix(net): preserve failed session tick stacks
Keep the original exception stack when cleanup succeeds so connected lifecycle failures identify the real packet/event handler instead of the session wrapper.

Co-authored-by: Erik Nilsson <erikn@users.noreply.github.com>
2026-07-24 19:48:11 +02:00
Erik
aa6ffa5176 refactor(app): compose interaction and retained UI startup 2026-07-22 17:20:47 +02:00
Erik
c557038353 refactor(input): extract the gameplay frame 2026-07-22 01:38:40 +02:00
Erik
0bc9fda9de refactor(streaming): extract the update frame 2026-07-22 01:01:04 +02:00
Erik
4e4aac2c5a refactor(runtime): extract the live object frame 2026-07-22 00:42:26 +02:00
Erik
4a205a3e56 test(streaming): close lifecycle gate after cutover 2026-07-21 23:41:15 +02:00
Erik
6a5d9e2e6a refactor(net): cut GameWindow over to session owner 2026-07-21 12:37:22 +02:00
Erik
d9ccf8a6b9 refactor(net): own complete live session lifecycle 2026-07-21 12:20:55 +02:00
Erik
0b25df53df refactor(app): extract LiveSessionController for network-side session lifecycle (Step 2)
Step 2 of the extraction sequence in docs/architecture/code-structure.md
§4. Lifts DNS resolution + WorldSession instantiation + wireEvents
callback + per-frame Tick + Dispose out of GameWindow.TryStartLiveSession
into a dedicated AcDream.App.Net.LiveSessionController.

What moves:
  - DNS resolution (IPAddress.TryParse + Dns.GetHostAddresses fallback,
    IPv4 preferred) → LiveSessionController.ResolveEndpoint
  - WorldSession instantiation → LiveSessionController.CreateAndWire
  - "live: connecting to ..." console line → CreateAndWire
  - Try/catch around the setup phase → CreateAndWire (separate from the
    Connect/EnterWorld try block that stays in GameWindow)
  - Per-frame _liveSession?.Tick() → _liveSessionController?.Tick()
  - OnClosing _liveSession?.Dispose() → _liveSessionController?.Dispose()

What stays in GameWindow:
  - The 25+ event subscriptions (extracted into a new private
    WireLiveSessionEvents method that the controller invokes via callback)
  - The Connect → CharacterList → EnterWorld → post-EnterWorld setup dance
    (touches Chat, _playerServerGuid, _vitalsVm, _worldState, _settingsStore,
    _settingsVm, _playerModeAutoEntry; moving these would balloon Step 2's
    scope and risk surface)
  - All 60+ outbound _liveSession.Send* call sites (touch the field by
    name; LiveSessionController.Session is the controller-side mirror)

The _liveSession field remains as a convenience handle synced with
_liveSessionController.Session; it tracks the same WorldSession instance.

Behavior preservation:
  - Same DNS-resolution sequence, same "live: connecting to ..." line,
    same wiring-vs-Connect ordering as pre-refactor.
  - Same 25+ event subscriptions in the same order, byte-for-byte.
  - Same Connect/EnterWorld error handling (the catch block stays in
    GameWindow because it disposes _combatChatTranslator which is also
    a GameWindow field).

Closes #76.

One subtle nullable-flow fix the compiler required: the chat-bus
lambda's `var liveSession = _liveSession;` capture became
`var liveSession = session;` (the non-null parameter) so the compiler
can prove non-null inside the lambda body. Both pointed to the same
WorldSession instance; only the static analysis changed.

Verification:
  - dotnet build green
  - dotnet test: AcDream.App.Tests 10/10, Core.Net.Tests 294/294,
    UI.Abstractions.Tests 419/419 — all green. Core.Tests 1073/1081
    (same 8 pre-existing physics failures as baseline; unrelated).
  - Live ACE session against +Acdream verified end-to-end:
    * Connection + handshake + EnterWorld
    * Door double-click → OnLiveMotionUpdated round-trip
      (cmd=0x000B open / cmd=0x000C close)
    * NPC double-click → outbound Use
    * Ground item F-key pickup × 4 successful (Amaranth, Comfrey,
      Damiana, Dragonsblood)
    * Spawn stream + chat channels + remote-entity motion all healthy
    * Clean OnClosing → controller.Dispose

Walking-range auto-walk + pickup-overshoot bugs observed during
verification are pre-existing (filed as #77); they live in
PlayerMovementController.DriveServerAutoWalk / threshold logic
which this refactor did not touch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:15:57 +02:00