287 lines
17 KiB
Markdown
287 lines
17 KiB
Markdown
# Runtime local-player physics publication - 2026-08-01
|
|
|
|
## Scope
|
|
|
|
This is placement Slice 4B2 checkpoints 4-6. It adds the dormant,
|
|
presentation-independent transaction which prepares and assigns ownership of
|
|
one local-player `PhysicsBody` and `PlayerMovementController`, retains an exact
|
|
post-ownership evaluation lease, and commits the canonical Runtime SetPosition
|
|
activation in retail order. No App or Headless production route invokes this
|
|
transaction yet, so graphical and no-window game behavior is unchanged and
|
|
AP-1/AD-1 remain open until their hosts cut over.
|
|
|
|
Checkpoint 6 consumes the prepared placement operation only after the exact
|
|
body/controller/identity/collision envelope is current. It publishes FullCell,
|
|
world residence, host, shadow, workset, object-clock, and ordered Place state
|
|
from that same Runtime-owned dormant body. There is no second body, mirrored
|
|
gameplay owner, rollback mutation, or presentation callback inside the
|
|
canonical tail.
|
|
|
|
## Ownership contract
|
|
|
|
`RuntimeLocalPlayerPhysicsPublicationState` is the sole owner of unpublished
|
|
local-player body/controller candidates. Each candidate is bound to a token
|
|
containing:
|
|
|
|
- The exact `RuntimeEntityKey` and 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 checkpoint-6 activation transaction may promote `RuntimeOwnedDormant`
|
|
to `RuntimePublished`; preparation and evaluation never invoke 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:
|
|
|
|
1. Rebind the candidate controller from its private clock to the record's exact
|
|
canonical object clock and mark it Runtime-owned but dormant.
|
|
2. Store the candidate's exact body on the canonical record, advancing the
|
|
physics ownership epoch once.
|
|
3. 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. During evaluation, a valid result likewise
|
|
remains only an immutable receipt; checkpoint 6's separate commit API consumes
|
|
that receipt only after revalidating the complete activation envelope.
|
|
|
|
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.
|
|
|
|
## Canonical activation and retail ordering
|
|
|
|
The implementation follows the named-retail chain rather than treating
|
|
SetPosition as a single opaque callback:
|
|
|
|
- `CPhysicsObj::SetPosition` at `0x005160C0` owns the outer placement call.
|
|
- The internal wrapper at `0x00515BD0` evaluates residence and collision.
|
|
- `CPhysicsObj::SetPositionInternal(CTransition*)` at `0x00515330` commits the
|
|
accepted frame/contact prefix and later shadow/cell state.
|
|
- `CPhysicsObj::enter_world` at `0x00516170` is the final live edge.
|
|
- `CPhysicsObj::leave_world` at `0x005155A0` is the canonical retirement edge.
|
|
|
|
Runtime splits that chain into a prepared, callback-free transaction and an
|
|
ordered notification suffix:
|
|
|
|
1. Install the accepted frame and contact prefix on the still-dormant body and
|
|
perform the first acceleration calculation.
|
|
2. Open one narrow dormant ground phase and invoke `HitGround` or
|
|
`LeaveGround`. Movement reapplication may call retail `set_velocity`, but
|
|
the phase closes with `Active=false`; the body is still out of world, has no
|
|
host/spatial membership, and its object clock is inactive.
|
|
3. Synchronize accepted State and Vector authorities, run the post-ground
|
|
acceleration/sliding phase, and dispatch the already-installed collision
|
|
batch.
|
|
4. Revalidate the complete ownership/collision envelope. Accepted State and
|
|
Vector updates are synchronized; Position, ObjDesc, Create, Setup,
|
|
incarnation, identity, collision-generation, body, controller, host, or
|
|
session displacement aborts the old transaction.
|
|
5. Apply velocity-current physical response and stationary bits, prepare the
|
|
final shadow mutation and Place receipt, then perform the callback-free
|
|
FullCell/body/host/controller/spatial/object-clock tail.
|
|
6. Dispatch exact shadow notifications and the ordered Place projection only
|
|
after the complete live graph is visible.
|
|
|
|
Collision and shadow mutations use explicit prepare/apply/dispatch receipts.
|
|
Receipt dispatch is exact-once and owner-local, so reverse-order receipts for
|
|
different owners remain valid while a superseding mutation of the same owner
|
|
stops the stale suffix. Collision owner states carry the exact SetPosition
|
|
batch ID. Reentrant Position or newer-batch replacement suppresses remaining
|
|
reciprocal/environment callbacks, and abort cleanup force-ends/removes only the
|
|
still-exact old batch, including reverse rows and the environment latch. The
|
|
combined Runtime physics ownership ledger includes pending collision and
|
|
shadow SetPosition receipts; teardown cannot report convergence while either
|
|
receipt remains.
|
|
|
|
Candidate construction applies the accepted `PhysicsDesc` values in retail
|
|
`CPhysicsObj::set_description` order before sealing ownership: final state,
|
|
friction, clamped elasticity, `set_velocity` (including the 50-unit clamp),
|
|
and angular velocity. Network acceleration remains parse-only because retail
|
|
recalculates it from the final physics state. This initial vector bootstrap is
|
|
required even when the SetPosition receipt's source Vector authority is still
|
|
current; the later refresh intentionally skips in that case. Collision
|
|
callbacks may advance State/Vector authority without invalidating the
|
|
immutable geometry/identity envelope, and a changed Vector authority refreshes
|
|
the dormant body through the same `set_velocity` path before physical response.
|
|
|
|
A deferred-cell commit atomically suspends an authored shadow registration and
|
|
consumes its notification receipt. Explicit publication discard cancels the
|
|
exact SetPosition lease and body/controller ownership, while the suspended
|
|
registration remains owned by the live entity/shadow registry and is reusable
|
|
by a later activation. A deterministic discard -> generation-ready -> new
|
|
activation gate proves the same registration restores without stale rows or a
|
|
pending receipt. Entity/lifetime teardown remains the terminal owner of that
|
|
suspended registration.
|
|
|
|
## 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.
|
|
- Initial PhysicsDesc velocity, angular velocity, friction, and elasticity
|
|
bootstrap, including activation with the retail 50-unit velocity clamp.
|
|
- Dormant rejection after ownership commit plus the controller-level
|
|
`dormant -> activated -> live` lifecycle contract exercised by checkpoint 6.
|
|
- No mutation of SetPosition, FullCell, spatial roots, host projections,
|
|
shadows, worksets, world residence, or presentation during preparation or
|
|
evaluation; the separately gated activation commit owns those mutations.
|
|
- 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.
|
|
- Publication/activation sequence exhaustion is preflighted before candidate
|
|
allocation or replacement, leaving no private or canonical owner behind.
|
|
- Shadow-registry reset invalidates even a prepared, unapplied shapeless
|
|
transaction which owns no logical rows or pending dispatch receipt.
|
|
- 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-6 focused publication/collision suite passes 129/129, the
|
|
focused Core shadow transaction suite passes 16/16, and the complete Runtime
|
|
project passes 695/695 under invariant globalization. The Runtime Release build
|
|
passes with zero warnings and zero errors. Broader Core/App/solution and
|
|
connected gates remain for the parent integration checkpoint. Under the
|
|
machine's Swedish current culture, the three previously known formatting
|
|
assertions remain unrelated (`0,5` versus `0.5` and localized sky text), so the
|
|
canonical Runtime gate runs under invariant globalization.
|
|
|
|
## Next checkpoint
|
|
|
|
Cut the graphical and no-window local-player hosts over to this Runtime-owned
|
|
activation transaction, then delete their duplicate SetPosition
|
|
activation/publication paths. The cutover must preserve the same exact body,
|
|
controller, shadow payload, deferred-cell lease, collision receipt ordering,
|
|
and graceful teardown proven here; no host may reconstruct or replay the
|
|
canonical transaction.
|