fix(world): complete recall before teleport hide
Match retail's update ordering so object animation, particles, and scripts advance before inbound teleport state is applied. Separate input-originated movement from post-network autonomous position output, and reconcile presentation without a second physics tick so recall cannot resume after arrival. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
dded9e6b17
commit
75acae02d6
13 changed files with 1068 additions and 332 deletions
|
|
@ -844,8 +844,17 @@ Repository links:
|
|||
4. No client-side impact, explosion, damage, or deletion is synthesized.
|
||||
5. Presentation frame ordering is fixed: advance animation/root motion,
|
||||
publish indexed parts, compose equipped children, drain animation hooks,
|
||||
tick owner PhysicsScripts, refresh attached emitters/lights, then advance
|
||||
particle simulation and draw.
|
||||
refresh attached emitters/lights, advance particle simulation, tick owner
|
||||
PhysicsScripts, dispatch inbound network events, run the post-inbound
|
||||
command-interpreter position check, reconcile spatial derivatives without
|
||||
advancing time, then draw. The explicit network boundary ports
|
||||
`SmartBox::UseTime @ 0x00455410`: `CPhysics::UseTime` updates every object
|
||||
(including its particle and script managers) before SmartBox drains its
|
||||
inbound queue, after which `CommandInterpreter::UseTime @ 0x006B3BF0`
|
||||
evaluates AutonomousPosition. Within each object,
|
||||
`CPhysicsObj::UpdateObjectInternal @ 0x005156B0` updates
|
||||
`ParticleManager` before `ScriptManager`, so a particle created by a script
|
||||
begins simulation on the following object frame.
|
||||
|
||||
Retail stages animation hooks inside `CSequence::update`, then executes them
|
||||
from `CPhysicsObj::process_hooks` before the new root is committed. The same
|
||||
|
|
|
|||
|
|
@ -276,10 +276,45 @@ The viewer reset copies the player's complete position into both `viewer` and
|
|||
boom outward through the same damped and swept path used after camera
|
||||
collision. Reusing the source-world viewer is not retail behavior.
|
||||
|
||||
## Recall completion versus Hidden
|
||||
|
||||
The retail teleport hook does not clear the character's animation sequence.
|
||||
The arrival presentation is instead hidden by the portal scene and its final
|
||||
world view-plane transition while the normal motion/update stream settles. Therefore acdream
|
||||
must not add an arrival-only animation reset.
|
||||
Recall completion is instead guaranteed by the enclosing frame order:
|
||||
|
||||
```text
|
||||
Client.UseTime:
|
||||
Timer.update_time()
|
||||
ClientNet.UseTime()
|
||||
process packet controller/cache/UI work
|
||||
SmartBox.UseTime()
|
||||
SmartBox.Draw()
|
||||
|
||||
SmartBox.UseTime:
|
||||
CObjectMaint.UseTime()
|
||||
CPhysics.UseTime() // advances PartArray, particles, scripts
|
||||
GameTime/LScape/Ambient.UseTime()
|
||||
while inbound queue not empty:
|
||||
DispatchSmartBoxEvent() // SetState/Hidden lands here
|
||||
CommandInterpreter.UseTime() // ShouldSendPositionEvent -> AP
|
||||
```
|
||||
|
||||
The exact call sites are `Client::UseTime` `0x00411C40` and
|
||||
`SmartBox::UseTime` `0x00455410`, and `CommandInterpreter::UseTime`
|
||||
`0x006B3BF0`. `SmartBox::DoSetState` `0x004520D0`
|
||||
applies Hidden directly and does not advance or reset animation. Separately,
|
||||
`CPhysicsObj::UpdatePositionInternal` `0x00512C30` skips `CPartArray::Update`
|
||||
while Hidden. Therefore the ordering boundary is load-bearing: the current
|
||||
frame's animation must advance before an inbound Hidden transition can freeze
|
||||
it.
|
||||
|
||||
ACE schedules lifestone recall teleport after the MotionTable-reported action
|
||||
length. With the installed human DATs, the boundary is about 15.06024 seconds;
|
||||
floating-point conversion can leave acdream at frame 149.999998 of the
|
||||
0..149 recall node if it dispatches Hidden before the current object tick. On
|
||||
UnHide that microscopic remainder becomes a visible destination-side recall
|
||||
tail. Retail's object-before-network order retires the node first. The faithful
|
||||
fix is that frame barrier, never an arrival-only Ready/reset command and never
|
||||
advancing PartArray while Hidden.
|
||||
|
||||
## acdream integration translation
|
||||
|
||||
|
|
@ -303,6 +338,23 @@ must not add an arrival-only animation reset.
|
|||
strand the transit, while canonical physics retains its own retail gates.
|
||||
- Destination placement resets the retail chase camera's published and sought
|
||||
positions to the player before the normal update path resumes.
|
||||
- `RetailLiveFrameCoordinator` owns the `SmartBox::UseTime` phase barrier:
|
||||
local/remote object and projectile advancement, final pose/hook publication,
|
||||
attached emitters/lights, particle simulation, and PhysicsScripts all precede
|
||||
inbound session dispatch in that retail order; rendering consumes the resulting
|
||||
coherent snapshot.
|
||||
- `RetailLocalPlayerFrameController` owns the local player's exactly-once
|
||||
object tick. Input-originated movement and jump packets are serialized from
|
||||
its pre-network result; F751 or ForcePosition received later in the frame
|
||||
cannot relocate or replay those one-shot commands. After inbound dispatch,
|
||||
`CommandInterpreter::UseTime @ 0x006B3BF0` evaluates AutonomousPosition from
|
||||
the current controller frame, matching its exact retail slot.
|
||||
- After inbound dispatch, a non-time-advancing reconciliation composes equipped
|
||||
children and refreshes emitter/light anchors from the authoritative root. It
|
||||
does not rerun animation, scripts, particles, or fades. A player first created
|
||||
by that inbound pass is likewise projected without receiving a late physics
|
||||
tick; its first normal object tick occurs on the next update.
|
||||
This is update-loop ordering, not portal-specific animation logic.
|
||||
- Destination residency remains acdream's asynchronous adaptation. It supplies
|
||||
the same `EndTeleportAnimation` edge retail receives when its blocking cell
|
||||
load completes; it does not alter presentation ordering.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue