acdream/docs/research/2026-07-12-death-and-auto-target-pseudocode.md
Erik 9b97102c67 fix(combat): persist death and retarget on kill
Keep the velocity-only NPC adaptation inside the locomotion family so authoritative Dead motion remains persistent. Route selection clears through a dedicated combat target controller that reacquires the closest eligible creature when retail Auto Target conditions apply.

Co-Authored-By: Codex <codex@openai.com>
2026-07-12 09:19:38 +02:00

2.2 KiB

Persistent death and post-death Auto Target pseudocode

Sources: Sept 2013 EoR named retail client.

  • ClientCombatSystem::AutoTarget (0x0056BC80)
  • ClientCombatSystem::RecvNotice_SelectionChanged (0x0056BD80)
  • CPlayerSystem::SelectNext (0x0055F9A0)
  • MovementManager::unpack_movement (0x00524440)
  • CPhysicsObj::MoveOrTeleport (0x00516330)

Animation authority

on UpdateMotion(interpretedState):
    pass the state through MovementManager and CMotionInterp
    Dead is a persistent substate selected by the motion table

on UpdatePosition(position, velocity):
    update the physics pose and velocity
    do not select Ready, Walk, Run, or any other animation

acdream retains a documented AP-80 adaptation for ACE actors that move only through position snapshots: velocity may choose a visible locomotion cycle. That adaptation is now restricted to replacing only Ready/Walk/Run-family states. An authoritative action or substate such as attack, hit reaction, or Dead always wins. This preserves the adaptation without allowing a late position delta to make a corpse stand again.

Auto Target after the selected creature dies

when authoritative Dead motion is applied to the selected object:
    clear selected object
    publish SelectionChanged

RecvNotice_SelectionChanged():
    update target tracking
    if selected object is zero
       and combat mode is Melee or Missile
       and Auto Target is enabled:
        AutoTarget()

AutoTarget():
    if a recent valid last-attacked object exists:
        select it
    else:
        SelectNext(forward=true, includeCurrent=true, COMPASS_ITEM)

SelectNext(... COMPASS_ITEM) while in Melee/Missile:
    reject non-attackable, fellowship, hidden, and out-of-radar candidates
    rank eligible candidates by the retail weighted spatial distance
    select the best candidate

The current M2 world-state projection has no retail lastAttacked instance-id quality, so its existing closest eligible creature scan implements the fallback branch. The important lifecycle behavior is exact: authoritative death clears selection, and the SelectionChanged consumer reacquires only when Auto Target is enabled in Melee/Missile combat.