Route accepted non-autonomous local UpdateMotion state through retail's wholesale interpreted-motion funnel, so ACE-selected melee and missile actions use the normal motion queue and action-stamp gate. Share nullable wire conversion with remotes and remove the local direct command replay. Co-Authored-By: Codex <codex@openai.com>
3.2 KiB
Local combat UpdateMotion — retail receive pseudocode
Date: 2026-07-11
Question
Who chooses and plays the local player's melee or missile attack motion?
Named-retail oracle
ClientCombatSystem::ExecuteAttackat0x0056BB70sends the targeted melee/missile request and updates combat-repeat state. It does not choose a concrete swing command and does not play an animation locally.CPhysics::SetObjectMovementat0x00509690rejects a local autonomous echo, but accepts a newer non-autonomous movement event, storeslast_move_was_autonomous = false, callsunpack_movement, then returns 1 soCommandInterpreter::LoseControlToServerruns.MovementManager::unpack_movementat0x00524440, case 0, unpacks anInterpretedMotionState, callsmove_to_interpreted_state, then applies the sticky-object and standing-long-jump trailers.CMotionInterp::move_to_interpreted_stateat0x005289C0copies the state wholesale, reapplies style/forward/side/turn, and dispatches fresh command list entries under the 15-bitserver_action_stampgate. The player skips only command entries whose autonomous bit is set.
ACE cross-reference
ACE's Player_Melee.DoSwingMotion selects the actual maneuver from the combat
table, constructs a Motion, marks the target sticky, and broadcasts it.
Missile attacks similarly enqueue the server-selected aim action, followed by
reload and Ready. MovementData.IsAutonomous documents the wire split as
client-initiated true, server-initiated false.
Retail pseudocode
on local attack input:
send TargetedMeleeAttack or TargetedMissileAttack
do not invent or play a swing locally
on UpdateMotion for local player:
apply movement and server-control sequence gates
if event.isAutonomous:
drop the entire event
player.lastMoveWasAutonomous = false
interrupt current move
unstick
apply outer style if it changed
if movementType is MoveTo/TurnTo:
route to MoveToManager
return
if movementType == InterpretedMotionState:
ims = constructor defaults (NonCombat, Ready, speeds 1)
unpack every present field over ims
move_to_interpreted_state(ims)
copy every axis wholesale
apply style, forward, sidestep, turn
for each fresh command-list entry:
if local player and entry.autonomous: skip
dispatch entry through the motion table
apply sticky target trailer
write standingLongJump, including false
command interpreter loses control to server
next local input edge takes autonomous control back
acdream correction
The local branch already had the autonomous-event rejection and the
interrupt/style/MoveTo routing, but deliberately skipped the mt-0 wholesale
copy. It then replayed Commands[] directly through
AnimationCommandRouter, bypassing retail's action-stamp and local-autonomous
gates. The correction routes local mt-0 through the existing
MotionInterpreter.MoveToInterpretedState and persistent motion-table sink,
exactly like remotes, and removes the direct replay. A shared App-layer factory
now owns nullable-wire-to-constructor-default conversion for both branches.