13 KiB
Runtime local-player physics publication - 2026-08-01
Scope
This is placement Slice 4B2 checkpoints 4-5. It adds the dormant,
presentation-independent transaction which prepares and assigns ownership of
one local-player PhysicsBody and PlayerMovementController, then retains an
exact post-ownership activation lease which can evaluate retail SetPosition
without publishing it. No App or
Headless production route invokes this transaction, so graphical and no-window
game behavior is unchanged and AP-1/AD-1 remain open.
The checkpoints deliberately stop before canonical SetPosition activation. They do not consume the prepared placement operation, enter the body into the physics engine, publish FullCell/world/host/shadow/workset state, or project a presentation entity. Those effects belong to the next transaction and must all use the same Runtime-owned dormant body.
Ownership contract
RuntimeLocalPlayerPhysicsPublicationState is the sole owner of unpublished
local-player body/controller candidates. Each candidate is bound to a token
containing:
- The exact
RuntimeEntityKeyand authored SetPosition placement token. - A monotonic publication ID.
- The nonzero canonical local-player server GUID and exact identity revision.
- The record's physics-body and object-clock ownership epochs.
- The movement state's controller ownership epoch.
- The entity directory's session-lifetime authority.
Preparation constructs a private controller, body, and object clock. It applies the exact authored cell frame, orientation, Setup sphere list, scale, step heights, and accepted final physics state without mutating the canonical entity, shared object clock, engine/worksets, shadow registry, FullCell, host state, or presentation. The candidate remains explicitly out of world and inactive. No method exposes its controller, body, clock, or another mutable reference while it is owned by the publication transaction.
This checkpoint accepts only a pristine initial graph: no canonical body, movement controller, physics host, remote motion, projectile, acquisition or binding operation, or remote-placement contract may exist. It cannot replace or upgrade a live graph. The local-player identity must be live, nonzero, and name the same server GUID as the exact entity incarnation.
Unpublished candidates and ownership-committed dormant controllers reject live
movement operations: update, public SetPosition, blip, outbound-position
capture, movement/position send tracking, and shared-engine position commit.
Only the subsequent activation transaction may promote RuntimeOwnedDormant
to RuntimePublished; this checkpoint never invokes that transition. Once a
Runtime-owned dormant or published controller is replaced, reset, or disposed,
its terminal retirement state rejects the same operations plus
body/configuration mutation and manager acquisition. Publicly constructed
legacy controllers keep their existing standalone behavior.
Failure-atomic commit
Commit revalidates every authority after preparation:
- The entity record is the current incarnation and is not accepted for delete.
- The local-player identity still has the token's exact GUID and revision and has not been disposed.
- The exact authored SetPosition operation and sealed command remain current.
- Session, body, object-clock, and controller ownership epochs still match.
- The body/controller/host/remote/projectile graph remains completely pristine, with no acquisition, binding, or remote-placement operation in progress.
Only after validation completes does the callback-free update-thread tail:
- Rebind the candidate controller from its private clock to the record's exact canonical object clock and mark it Runtime-owned but dormant.
- Store the candidate's exact body on the canonical record, advancing the physics ownership epoch once.
- Store the same controller in
RuntimeLocalPlayerMovementState, advancing the controller ownership epoch once.
The dormant controller rejects every live/configuration operation after these stores; ownership commit alone cannot tick physics, mutate the canonical clock, or publish an outbound frame. These stores allocate no new gameplay owner, invoke no host or presentation callback, and cannot replay an older incarnation. Replacing SetPosition, changing any accepted physics authority, binding remote/projectile state, replacing body/clock/controller ownership, delete plus GUID reuse, reset, or disposal causes the token to reject. An identity switch away and back also rejects because its revision changed. A rejected or superseded candidate is discarded and cannot perform a later live operation. Reset and disposal converge the publication ledger to zero candidates.
Repeated stores of the same body/controller do not advance their epochs; real bind, replacement, and unbind edges do. This makes ABA-shaped reference changes observable even if a later value happens to equal an earlier reference.
Dormant SetPosition evaluation lease
Ownership commit now returns one private activation token captured only after the canonical body and controller stores. It binds the exact entity key, authored placement token and sealed command, local identity GUID/revision, session lifetime, and the post-store physics-body, object-clock, and controller ownership epochs. The owner retains the same record, body, controller, and command behind that token; no caller can substitute an equivalent-looking body or rebuild the mover.
EvaluateActivation revalidates that complete lease and calls Core
PhysicsEngine.SetPosition synchronously with an immutable request. Core's
transaction is pure: it returns committed, deferred-cell, or rejected
placement data without writing the canonical body, FullCell, clock, spatial
worksets, shadows, collision-report owners, host, operation stage, or Place
projection. A missing cell therefore leaves the exact body dormant and the
authored operation retryable. A valid result likewise remains only an
immutable evaluation receipt; this checkpoint has no activation/commit API.
Each evaluation carries an append-only, stable-order union of every cell read
by the complete Core transaction: the AdjustPosition seed and adjusted cell,
visible-child probes (including rejected lateral siblings), rejected
portal/building containment probes, transition/compass retries, and every
normal or scatter attempt. Rejected probes enter only the authority union and
never the final successful shadow/CrossCell footprint. Scatter keeps that union
in retained scratch and materializes its
immutable receipt exactly once after the final attempt, avoiding quadratic
copy/allocation growth at the 64-attempt retail ceiling. The final
CrossCellIds remains the successful placement's authored
shadow footprint; failed scatter probes cannot leak into that commit payload.
Runtime seals every distinct queried landblock against the exact collision
generation, the global collision-world authority, and the dynamic-shadow
mutation revision. An active replacement admission rejects evaluation even
before it commits, while begin/cancel, a re-entrant generation commit, or any
owner insert/remove/move/state/suspend/reflood mutation invalidates an older
receipt.
Entry restrictions also consult the live ClientObjectTable for the resolved
house object, owner and complete restriction record, plus the mover's monarch.
The receipt therefore seals the exact object-table reference, the engine's
monotonic binding epoch, and the table's synchronous mutation revision. Object
creation/removal, owner-property, guest-list, or mover-monarch updates invalidate
the receipt; a null/fresh replacement and an equal-revision A-B-A binding cycle
cannot resurrect it. Retained ClientObject owner, monarch, and restriction
setters synchronously advance every exact owning table even when callers mutate
the object directly rather than re-submit it through AddOrUpdate. Replacement,
removal, and clear detach that observer exactly, and every
HouseRestrictionRecord freezes a defensive snapshot of its input guest map so
no caller-owned dictionary or mutable downcast can alter entry authority behind
the revision.
IsEvaluationCurrent accepts only the newest receipt for the exact activation
lease and rejects it after a position/vector/state/object-description/Create
authority change, identity revision, body/controller replacement, session or
incarnation change, or any sealed collision/shadow authority change.
Re-evaluation supersedes the older receipt without mutating world state.
Re-entrant reset or delete-plus-GUID-reuse during Core evaluation immediately
retires the invalid lease instead of leaving an orphaned dormant graph. An
existing activation lease also blocks candidate preparation even if an
external owner has already cleared the body/controller references; explicit
discard is required before a new candidate can be prepared. Reset and disposal
retire the lease, body, and dormant controller and include the pending
activation in the ownership convergence ledger.
Gates
- Candidate privacy and live-operation rejection.
- Pristine-only admission for body, controller, host, remote/projectile, acquisition/binding, and remote-placement ownership.
- Exact local-player identity, identity-switch, and disposed-identity rejection.
- Exact same-body ownership in entity record and dormant movement controller.
- Dormant rejection after ownership commit plus the isolated controller-level
dormant -> activated -> livelifecycle contract for the next checkpoint. - No mutation of SetPosition, FullCell, spatial roots, host projections, shadows, worksets, world residence, or presentation during this checkpoint.
- Replacement by position, vector, final physics state, object description, CreateObject, remote/projectile/body/clock/controller ownership, and explicit placement cancellation.
- Delete plus same-GUID reincarnation.
- Candidate replacement, reset, disposal, and ownership convergence.
- Pure committed/deferred/rejected SetPosition evaluation with bit-exact body-state snapshots and no canonical, collision-report, projection, clock, FullCell, host, shadow, workset, or operation-stage mutation.
- Complete stable-order queried-cell capture across AdjustPosition, visible-child lookup, normal/scatter retries, map-edge/deferred, rejected, committed, and defensive NoCell outcomes. Scatter deliberately retains retail's RNG consumption; only its authority footprint and commit payload are deterministic for a fixed draw sequence.
- Newest-receipt selection, active-admission rejection, collision-generation replacement, re-entrant begin/cancel and commit invalidation, plus dynamic shadow insert/move/state/suspend/remove invalidation.
- Exact object-table reference/revision/binding authority, including post-evaluation and re-entrant house-object, owner, guest-list, and mover- monarch mutations plus null/fresh/equal-revision ABA replacement. Direct retained-object setters, replacement/removal/clear observer lifetime, shared multi-table ownership, and frozen guest-map input are covered explicitly.
- Re-entrant reset and delete/GUID-reuse convergence plus activation-lease overwrite prevention after an external body/controller clear.
- Post-ownership position, vector, object-description, Create, identity, body, and controller authority replacement.
- Terminal stale-controller rejection after replacement, reset, and disposal.
- Body/controller epochs advance only on actual ownership changes.
The checkpoint-5 focused publication suite passes 70/70 and the focused Core
SetPosition suite passes 59/59. The complete Runtime project passes 666/666;
the complete Core project passes 4,230 tests / 1 skip; and the App Runtime
physics/movement ownership guard passes 6/6. The complete Release solution
builds with zero errors (three pre-existing App-test nullability warnings are
outside this checkpoint), and its invariant-culture test gate passes 10,419
tests / 4 intentional skips. The installed prepared-package gate
uses the exact local acdream.pak. Under the machine's Swedish current culture,
the same three previously known formatting assertions remain unrelated (0,5
versus 0.5 and localized sky text), so the canonical gate runs under
invariant culture.
Next checkpoint
Add the canonical Runtime SetPosition activation transaction. Before its
callback-free tail, it must prepare a presentation-independent Runtime
PhysicsHost/PositionManager/MoveToManager graph, the existing authoritative
authored shadow payload (without rebuilding AP-22 shapes), and an exact staged
collision-report batch. Then it may commit the already-owned dormant body,
contact/water/walkable/response state, object clock, FullCell, exact shadow,
spatial/ordinary workset, host, and SetPosition operation versions; seal the
ordered Place receipt; and invoke the sole ActivateRuntimePublication
transition as the final tickable edge. Collision reports and the Place observer
publish only afterward and must tolerate delete/reset re-entry without replaying
physics. Every pre-commit failure leaves the dormant lease and authored
operation retryable or rejects them; no rollback mutation and no second body or
controller are allowed.