acdream/docs/research/2026-07-26-slice-j3-4-canonical-object-lifetime.md

4 KiB

Slice J3.4 closeout — canonical entity/object lifetime

Outcome

J3.4 is complete at:

5ef8b5371d8990f0380acd939e71cd711289d429

AcDream.Runtime.Entities.RuntimeEntityObjectLifetime is now the one presentation-free owner of the live session's:

  • canonical RuntimeEntityDirectory; and
  • canonical ClientObjectTable.

The graphical host, session router, retained UI, inventory interaction, paperdoll, magic, cooldown, and diagnostic owners borrow those exact instances. GameWindow no longer allocates or publicly owns a live object table, and LiveEntityRuntime no longer allocates its own entity directory.

Transaction boundary

CreateObject and DeleteObject retain the established retail-facing synchronous order.

For an accepted create:

  1. Runtime accepts or refreshes the exact canonical incarnation.
  2. The Runtime lifetime group applies the retained-object mutation.
  3. The group revalidates the exact canonical record and CreateIntegrationVersion before, during, and after callbacks.
  4. App continues graphical hydration only while the same acceptance remains current.

For an authoritative delete:

  1. Runtime issues one exact RuntimeEntityDeleteAcceptance.
  2. The active canonical identity is retired.
  3. The acceptance commits retained-object removal exactly once.
  4. App completes the retryable graphical/resource teardown suffix.

The acceptance rejects replay and use by another Runtime instance.

Important lifecycle distinction

An authoritative server delete and an offscreen/dormant prune are not the same operation.

  • Authoritative DeleteObject removes the retained ClientObject.
  • Dormant liveness pruning withdraws the graphical/live projection but keeps retained object information.

A focused regression test exposed an early implementation that deleted object information during every unregister. The final implementation carries an explicit removeRetainedObject decision and keeps freshness authority in Runtime. This preserves existing behavior without a timing guard or retry workaround.

Architecture checks

  • Runtime can construct the lifetime group without App, UI, Silk, OpenAL, Arch, or ImGui.
  • Two Runtime groups can own conflicting GUIDs and objects independently.
  • Production App source guards reject new ClientObjectTable() and new RuntimeEntityDirectory().
  • Studio/sample-data tables remain independent fixture owners.
  • There is no copied inventory model, asynchronous seam, extra input frame, or backend dependency in Runtime.
  • Session reset clears the Runtime-owned object table before graphical projection teardown, matching the established retryable manifest order.

Verification

Final automated results:

  • Runtime tests: 118 passed;
  • Core ClientObjectTable focus: 86 passed;
  • Core ObjectTableWiring focus: 6 passed;
  • inventory/item/paperdoll/magic/cooldown/runtime-adapter focus: 273 passed;
  • hydration/runtime/reset/composition focus: 172 passed;
  • App tests: 3,762 passed / 3 skipped;
  • complete Release solution: 8,453 passed / 5 skipped;
  • Release build: pass, with only the 17 pre-existing Core warnings.

Exact-binary connected evidence:

logs/connected-world-gate-20260726-055713/report.json

The route used two sessions and seven checkpoints. Both processes exited gracefully with code zero. It reported zero failures, zero render-scene shadow mismatches, zero pending deltas, zero pending live teardown, and zero pending retirement/publication/upload work. The only warning was the route's expected 25 world-edge landblock misses.

Rollback

git revert 5ef8b5371d8990f0380acd939e71cd711289d429

Do not revert J3.3 as a shortcut for a J3.4 failure.

Next boundary

J3.5 publishes one monotonic, per-session entity/object delta stream from committed Runtime state. Both direct/no-window and graphical hosts must observe the same sequence and borrow the same views. It must replace the current App event reconstruction without adding a second queue, copied world, or frame of latency.