feat(runtime): prepare authored SetPosition movers
This commit is contained in:
parent
237d1184d2
commit
442cb8f97b
8 changed files with 1516 additions and 70 deletions
|
|
@ -159,14 +159,16 @@ the pre-existing line-ending/stat-noise paths are deliberately excluded.
|
|||
|
||||
## Remaining work - required order
|
||||
|
||||
### 1. Exact authored mover preparation
|
||||
### 1. Exact authored mover preparation - complete 2026-08-01
|
||||
|
||||
Build every SetPosition request from Setup's ordered authored spheres, exact
|
||||
scale/presence semantics, StepUp/StepDown heights, flags, cell-local frame and
|
||||
orientation, and current position/vector/state authority versions. Do not
|
||||
synthesize a cylinder from visual radius/height or pre-mutate canonical state.
|
||||
The dormant preparation contract is implemented and independently reviewed.
|
||||
It binds the Runtime-owned accepted frame and exact Setup DID, preserves the
|
||||
ordered authored spheres and scale/step semantics, seals the returned command,
|
||||
and forces stale deferred residents through exact re-preparation without
|
||||
pre-mutating canonical state. See
|
||||
[`2026-08-01-runtime-set-position-authored-mover-preparation.md`](2026-08-01-runtime-set-position-authored-mover-preparation.md).
|
||||
|
||||
### 2. Atomic local-controller/body publication
|
||||
### 2. Atomic local-controller/body publication - next
|
||||
|
||||
Prepare off-canonical, then perform one Runtime-validated atomic transaction
|
||||
which publishes the exact same body to graphical and no-window controllers.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
# Runtime SetPosition authored mover preparation - 2026-08-01
|
||||
|
||||
## Scope
|
||||
|
||||
This is placement Slice 4B2 checkpoint 3. It adds the dormant,
|
||||
presentation-independent preparation contract used to turn an accepted Runtime
|
||||
position into retail's exact `CPhysicsObj::SetPosition` mover input. No App or
|
||||
Headless production route consumes the contract yet, so game behavior is
|
||||
unchanged and AP-1/AD-1 remain open.
|
||||
|
||||
## Retail oracle
|
||||
|
||||
The implementation was checked against the named September 2013 client:
|
||||
|
||||
- `PhysicsDesc::PhysicsDesc` `0x0051D4D0`
|
||||
- `PhysicsDesc::UnPack` `0x0051DDD0`
|
||||
- `CPhysicsObj::set_description` `0x00514F40`
|
||||
- `CPhysicsObj::SetPosition` `0x005160C0`
|
||||
- `SPHEREPATH::init_sphere` `0x0050C670`
|
||||
- `CPartArray::GetNumSphere` `0x00518060`
|
||||
- `CPartArray::GetSphere` `0x00518070`
|
||||
- `CPartArray::GetStepUpHeight` `0x005180D0`
|
||||
- `CPartArray::GetStepDownHeight` `0x005180F0`
|
||||
- `CTransition::init_object` `0x00509E40`
|
||||
- `OBJECTINFO::init` `0x0050CF30`
|
||||
|
||||
SetPosition calls `CTransition::init_object(..., state = 0)` directly. It does
|
||||
not use the ordinary-movement `CPhysicsObj::get_object_info` path. Consequently
|
||||
the SetPosition state carries the player/PK/PKLite/impenetrable classifications
|
||||
(plus acdream's pointer-free entry-restriction carrier), but it does not add
|
||||
Contact, OnWalkable, PathClipped, FreeRotate, or EdgeSlide. Ethereal and
|
||||
`step_down = !Missile` are separate `OBJECTINFO` fields derived from the current
|
||||
physics state.
|
||||
|
||||
## Exact preparation contract
|
||||
|
||||
- Runtime captures the complete accepted server frame under the exact entity,
|
||||
session, position, vector/velocity, wire-state, final-physics-state mutation,
|
||||
object-description, and create-integration authorities. A host cannot
|
||||
substitute a second position.
|
||||
- Collision-world X/Y uses the target landblock's active live-centered offsets;
|
||||
full cell ID, cell-local XYZ, and the complete quaternion remain unchanged.
|
||||
- Setup resolution is bound to the canonical Setup DID. A known but unavailable
|
||||
Setup remains retryable. Resolved-absent is valid only when the canonical
|
||||
object has no Setup. An authored empty Setup remains distinct and still
|
||||
contributes its scaled StepUp/StepDown heights.
|
||||
- The complete ordered Setup sphere list is retained. Core later applies
|
||||
retail's `min(count, 2)` traversal cap. The successfully resolved no-PartArray
|
||||
or zero-sphere arm reaches Core with an empty list, where SetPosition supplies
|
||||
the retail dummy sphere `(0,0,0.1)`, radius `0.1`, scale `1.0`.
|
||||
- Scale precedence is `PhysicsDesc.Scale ?? EntitySpawn.ObjScale ?? 1.0`.
|
||||
Present zero and finite negative values are preserved. Scale is not consumed
|
||||
by a resolved-absent dummy mover.
|
||||
- Every authored command is sealed to the exact preparation operation. Manual,
|
||||
stale, replaced, or merely value-equivalent commands cannot bypass the seal.
|
||||
- A wire-state, final-state mutation (including NoDraw and missile-stop),
|
||||
vector/velocity, description, or create change during a deferred cell wait
|
||||
returns the resident to `AwaitingPreparation`; the stale mover is never
|
||||
replayed when the collision generation wakes.
|
||||
- Preparation mutates no body, clock, FullCell, spatial/shadow registration,
|
||||
bucket, camera, world entity, or presentation resource.
|
||||
|
||||
Legacy direct SetPosition remains a distinct token mode so the dormant slice
|
||||
does not change existing call sites or their warmed allocation ceiling. If a
|
||||
legacy operation becomes deferred and later needs new authored data, the
|
||||
presence of Runtime's preparation authority makes the exact seal mandatory.
|
||||
|
||||
## Ownership and validation
|
||||
|
||||
`RuntimeSetPositionState` owns one exact-key preparation-authority entry only
|
||||
for operations which require authored preparation. The entry dies with the
|
||||
operation on replacement, acknowledgement, cancellation, delete, session
|
||||
reset, or disposal and participates in terminal convergence accounting.
|
||||
|
||||
Preparation-only validation checks the exact cell frame, live-centered world
|
||||
position, values consumed by the first two retail spheres, Setup-derived step
|
||||
heights, line/scatter inputs, and bounded scatter attempts. The legacy direct
|
||||
validator retains its prior behavior, including retail's dummy-sphere and
|
||||
first-two-sphere semantics.
|
||||
|
||||
## Gates and review
|
||||
|
||||
- Focused authored-mover plus SetPosition residence tests: 80/80.
|
||||
- Runtime Release build: zero warnings and zero errors.
|
||||
- Complete Runtime project under invariant culture: 595/595.
|
||||
- Complete Release solution with installed DAT/pak fixtures: 10,342 passed /
|
||||
4 intentional skips.
|
||||
- Retail-conformance review: canonical frame, DID binding, scale/step/sphere
|
||||
behavior, exact SetPosition flags, and deferred wake checked against the
|
||||
named addresses above.
|
||||
- Architecture/adversarial review: command sealing, legacy promotion,
|
||||
replacement, deferred wake, direct compatibility, allocation, reset, GUID
|
||||
reuse, and ownership convergence checked.
|
||||
|
||||
The three ordinary current-culture Runtime failures are pre-existing Swedish-
|
||||
locale formatting assumptions (`0,5` versus `0.5` and localized sky text); the
|
||||
same complete project passes under invariant culture.
|
||||
|
||||
## Next checkpoint
|
||||
|
||||
Implement the dormant atomic local-player physics publication transaction:
|
||||
prepare a private controller/body/clock without canonical mutation, evaluate
|
||||
SetPosition against that candidate, then publish the exact same body relation
|
||||
to `RuntimeEntityRecord` and `RuntimeLocalPlayerMovementState` in one callback-
|
||||
free Runtime commit. App and Headless production activation remains a later
|
||||
checkpoint.
|
||||
Loading…
Add table
Add a link
Reference in a new issue