docs(runtime): close simulation ownership

This commit is contained in:
Erik 2026-07-26 16:29:28 +02:00
parent cdee7a4b49
commit 4743f7c409
11 changed files with 281 additions and 33 deletions

View file

@ -0,0 +1,156 @@
# Slice J5.7 — simulation-ownership closeout
Date: 2026-07-26
Scope: ownership and teardown cleanup only; no retail algorithm, packet,
timing, collision policy, gameplay outcome, or graphical presentation change
## Objective
Close the temporary seams left by J5.1J5.6 so one Runtime lifetime owns the
complete presentation-independent simulation graph:
- canonical entity/object identity and accepted wire state;
- selection, interaction, combat, magic, and local movement intent;
- per-session physics, remote motion, projectiles, shadows, and spatial
worksets;
- reset, projection withdrawal, and terminal retirement.
App remains the graphical host. It supplies physical input, immutable
DAT/content inputs, transport and projection acknowledgements, then presents
committed Runtime state through animation, meshes, particles, audio, cameras,
retained UI, markers, and diagnostics.
## Named-retail invariant
J5.7 preserves the already-ported retail control flow. The one relocated
initialization detail follows:
- `CPhysicsObj::set_description` at `0x00514F40`
CreateObject velocity and angular velocity are installed once when Runtime
constructs the canonical remote body. Later authoritative Vector updates flow
through the existing retail timestamp gate and canonical record. App no longer
constructs a second body or repeats the accepted CreateObject vector install.
The projectile, movement, collision, interaction, combat, and spell algorithms
remain those documented by the preceding J5 evidence notes. No constant,
branch, packet order, server-authority boundary, or visible effect changed.
## Closed ownership gaps
Production commit
`cdee7a4b49addb5e1500753f6a885f7c899bd0f0`:
- removes the App remote-motion/physics-host/canonical-runtime/cell/placement
compatibility aliases after production consumers moved to Runtime types;
- deletes `LiveEntityRemoteMotionRuntimeView<T>` and the App
`RemotePhysicsBodyInitializer`;
- makes `LiveEntityNetworkUpdateController` borrow the canonical
`LiveEntityRuntime` and delegate body, remote-motion, vector, wakeup, and
activation work to `RuntimePhysicsState`;
- makes Runtime install accepted CreateObject velocity and angular velocity
exactly once at canonical body construction;
- makes `RuntimeEntityObjectLifetime.CompleteProjectionRetirement` own final
simulation-component retirement after the App projection acknowledges
withdrawal;
- removes App-side mutation of canonical remote/body/host/placement component
slots;
- makes current-runtime checkpoints borrow `IRuntimeEntityView` and inventory
views rather than reconstructing state from App projections or
`ClientObjectTable`;
- adds terminal clearing for `PhysicsEngine`, `ShadowObjectRegistry`, spatial
worksets, collision residence, bodies, hosts, remotes, and projectiles;
- adds `RuntimeSimulationOwnershipSnapshot`, one terminal ledger spanning
entity/object, physics, and gameplay ownership;
- adds a Runtime-only fixture host that drives movement, use, combat, casting,
and projectile simulation without loading App, UI, Silk.NET, OpenAL, ImGui,
Arch, or a native window.
`ILocalPlayerMotionSource` remains as a presentation-facing source name for
the animation projection seam. It does not construct, store, or mutate a
second movement owner; graphical animation borrows the exact
`RuntimeLocalPlayerMovementState`.
## Failure and parity matrix
The closeout fixtures cover every J5.7 boundary:
| Boundary | Evidence |
|---|---|
| construction | per-instance entity/object/physics/gameplay owners; canonical remote-body acquisition; no presentation/backend assembly load |
| subscription | entity, communication, gameplay, and projection observers isolate failures and detach exactly |
| command | graphical and direct movement, use, combat, and magic commands reach the same exact owners |
| projection acknowledgement | vector, rebucket, projectile, and terminal projection failures preserve canonical committed state and allow retry/convergence |
| reset | interaction, action, movement, session, entity/object, and physics reset paths converge without replay |
| disposal | combined simulation ledger, physics residence, shadows, worksets, objects, and subscriptions reach exact zero |
Normalized graphical/direct parity is pinned by:
- `CurrentGameRuntimeAdapterTests.GraphicalAndDirectCombatMagicCommands_ReachTheExactSameOwners`;
- `CurrentGameRuntimeAdapterTests.DirectAndGraphicalHosts_ProduceIdenticalEntityObjectTrace`;
- `RuntimeLocalPlayerMovementStateTests.GraphicalAndDirectCommandsMutateOneAutorunLatch`;
- `RuntimeSimulationFixtureHostTests.RuntimeOnlyHostDrivesCompleteJ5SimulationWithoutPresentation`.
The projection-failure fixture additionally proves that a failed graphical
acknowledgement cannot strand or roll back canonical simulation state:
- `RuntimeSimulationFixtureHostTests.ProjectionAcknowledgementFailureStillAllowsTerminalConvergence`.
## Automated acceptance
On the production commit:
- focused App ownership/entity/projectile/hydration suite: 198 passed;
- Runtime tests: 323 passed;
- App tests: 3,717 passed / 3 skipped;
- complete Release solution: 8,596 passed / 5 skipped;
- Release solution build: zero errors; 17 pre-existing warnings;
- source/dependency guards pass;
- `git diff --check` is clean.
The combined Runtime fixture loads no presentation or backend assembly and
its terminal `RuntimeSimulationOwnershipSnapshot.IsConverged` is true after
normal operation and injected projection failure.
## Connected acceptance
Both accepted connected gates used the exact rebuilt executable and source
commit `cdee7a4b49addb5e1500753f6a885f7c899bd0f0`.
- Lifecycle/reconnect:
`logs/connected-world-gate-20260726-160825/report.json`
passed all seven fresh-login, outdoor, dungeon, revisit, graceful-disconnect,
and uncapped fresh-process reconnect checkpoints. Both processes exited
gracefully with code zero, with zero failures and only the 25 expected
world-edge empty-landblock misses.
- Canonical nine-stop route:
`logs/connected-r6-soak-20260726-161406.report.json`
reported `binaryMatchesSource = true`, materialized all nine destinations,
passed forward, jump, combat, and authoritative movement-truth exercises at
Caul, Holtburg, and the Caul return, and exited gracefully with code zero
and zero failures. Every checkpoint converged with zero pending publication,
retirement, worker-completion, or destination backlog.
The earlier post-commit route
`logs/connected-r6-soak-20260726-155912.report.json` was behaviorally green
but is deliberately rejected as exact-binary evidence because its embedded
binary SHA preceded the source commit. It remains in the audit trail. The
solution was rebuilt and both accepted gates were then rerun.
The user-accepted connected behavior carried through J5 includes local
movement and target-facing, near/far object use, combat and spell bars,
projectile presentation, collision, repeated portal/recall, and reconnect.
J5.7 changes only ownership seams and the exact-binary routes exercise those
same owners after cleanup.
## Divergence and rollback
J5.7 removes duplicate ownership and compatibility seams. It introduces no
new retail behavior or divergence, so the divergence register requires no new
row.
Exact rollback:
```text
git revert cdee7a4b49addb5e1500753f6a885f7c899bd0f0
```