Commit graph

30 commits

Author SHA1 Message Date
Erik
a9a822f206 refactor(runtime): unify generation reset for direct hosts
Move canonical per-session teardown into one retryable Runtime transaction, reduce App reset to projection acknowledgements, and prove the same GameRuntime graph through deterministic no-window lifecycle, gameplay, portal, fault, reconnect, and isolation gates.\n\nCo-authored-by: Codex <noreply@openai.com>
2026-07-27 00:43:26 +02:00
Erik
cdee7a4b49 refactor(runtime): close simulation ownership
Move remote-motion construction, CreateObject vector initialization, final simulation-component retirement, and the combined J5 ownership ledger into Runtime. Delete App compatibility views and moved-state reconstruction while preserving the existing graphical projection and retail update order.
2026-07-26 15:53:31 +02:00
Erik
20df9d155d refactor(runtime): own combat and magic intent
Move attack build/repeat state, combat-mode policy, authoritative auto-target transitions, and spell-cast intent beneath RuntimeActionState. Keep App as the input, world-query, DAT-policy, transport, and presentation adapter while preserving retail request and busy ordering. Add direct/graphical parity, reset, failure, and instance-isolation coverage.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 11:56:40 +02:00
Erik
f5f7b4177f refactor(runtime): own interaction transactions
Move use throttling, appraisal identity, queued interactions, and exact post-arrival pickup state beneath RuntimeActionState. Keep App as the picker, movement, transport, and retained-presentation adapter while preserving retail send and UseDone ordering. Add reset, disposal, GUID-reuse, callback-reentrancy, and transport-failure coverage.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 11:13:09 +02:00
Erik
b298f99f91 refactor(runtime): own canonical action state
Move selection, combat, and interaction target mode under one Runtime owner; make plugins, retained UI, session routing, and typed runtime views borrow its exact children; and add failure-safe reset, instance isolation, source ownership, and normalized checkpoint coverage without changing retail ordering.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 10:44:09 +02:00
Erik
89e6b207f8 refactor(runtime): close canonical gameplay ownership
Unify the toolbar shortcut manager with Runtime inventory state, route retail-ordered shortcut and spellbook command effects through the canonical owners, and make retained controllers borrow those exact instances. Remove the item-interaction transaction fallback and add graphical/no-window parity plus failure-safe terminal ownership-ledger coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 09:48:51 +02:00
Erik
dcb61efb5a refactor(runtime): expose canonical gameplay state
Move character options and movement skills into the Runtime-owned character graph, expose borrowed inventory, character, and social views, and route retained UI state commands through generation-gated typed Runtime contracts. Preserve the existing synchronous wire path while deleting the App-owned option and skill mirrors and extending normalized parity checkpoints.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 09:12:30 +02:00
Erik
d02a12ceac refactor(runtime): own magic and player state
Move the coupled Spellbook and LocalPlayerState into one Runtime-owned character graph, route content, live-session, retained UI, reset, and shutdown through that exact owner, and delete the duplicate desired-component snapshot from inventory state. Preserve synchronous retail update and reset ordering while adding independent-instance and retryable-failure coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 08:39:02 +02:00
Erik
011efbeaa7 refactor(runtime): own inventory transaction state
Move the retail one-request-at-a-time gate, shared use busy references, external-container state, item mana, shortcuts, and desired-component snapshots into one Runtime-owned graph over J3's exact ClientObjectTable. Retained UI and session routing now borrow that owner; reset and shutdown preserve the existing order while failure/reentrancy tests protect the transaction boundary.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 08:20:32 +02:00
Erik
c9d25ade50 refactor(runtime): own communication and social state
Construct chat history, negotiated channels, friends, squelch, and reply targets in one presentation-independent Runtime owner. Make live routing, retained UI, devtools, and current-runtime projections borrow the exact instances, preserve reconnect reset semantics, and publish failure-isolated reentrant-safe chat commits.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 07:50:16 +02:00
Erik
5ef8b5371d refactor(runtime): own canonical entity and object lifetime
Introduce one presentation-free RuntimeEntityObjectLifetime for the exact entity directory and ClientObjectTable. Make GameWindow, graphical projections, retained UI, interaction, session routing, create/delete integration, and reset borrow that owner while preserving synchronous retail ordering, dormant retention, and retry semantics.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 05:54:46 +02:00
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
823936ec31 fix(streaming): preserve portal destination ownership
Detach old-world spatial ownership atomically, prioritize destination retirement dependencies, and reveal the viewport at the retail transition edge. Give private paperdoll views independent mesh ownership and retain dormant ACE entities so portal revisits preserve server objects without extending active GPU lifetimes.
2026-07-25 08:35:12 +02:00
Erik
0eb6648589 feat(rendering): compare the incremental shadow scene
Construct Slice F's non-drawing scene only for lifecycle automation, drain accepted static and live deltas at the final update boundary, and compare exact current-path fingerprints at cadence and checkpoints. Publish bounded mismatch, journal, index, digest, and memory evidence without changing normal launches or draw submission.

Release: 8,211 passed, 5 skipped.
2026-07-24 22:24:30 +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
643cdfe66e feat(ui): port retail appraisal panel
Preserve retail's one-pending-appraisal busy lifetime, parse the complete gated response, and mount the authored examination layout in the shared main-panel host. Keep known 3D preview and inscription-write gaps explicit in AP-110.
2026-07-23 11:34:08 +02:00
Erik
826f9ea9b5 refactor(app): complete session startup composition
Move the live-session reset and routing graph, combat and diagnostic command targets, and the sole gameplay input subscriber into Phase 7 before frame publication. Add exact retryable ownership for late bindings so partial startup cannot strand session or component teardown edges.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 18:49:31 +02:00
Erik
aa6ffa5176 refactor(app): compose interaction and retained UI startup 2026-07-22 17:20:47 +02:00
Erik
557eb7ef6b refactor(net): own live session composition
Extract reset, selection, entered-world, and route construction behind LiveSessionHost while preserving the sole LiveSessionController authority. Retain partial route and subscription cleanup for retry, and replace the embedded ACE-only shortcut with the exact named-retail unsigned skill formula.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 10:36:06 +02:00
Erik
e91f310279 refactor(update): cut over the frame orchestrator
Reduce GameWindow.OnUpdate to one typed orchestration call and remove transitive window callbacks from teardown, liveness, teleport placement, live presentation, auto-entry, and entity packet routing. Preserve the frozen retail object/network order while making the production owner graph explicit and testable.
2026-07-22 03:31:38 +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
fcb66198fc refactor(world): canonicalize live physics host ownership 2026-07-21 14:05:34 +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
4f31a5085f refactor(net): converge live session state reset 2026-07-21 12:00:48 +02:00
Erik
961bdd07b7 refactor(net): own live session routing 2026-07-21 11:17:09 +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