Files
Commonwealth-Online-Public/docs/weapon-animation-sync.md
T
andrew 89c3e82554 Implement proxy weapon animation sync for ranged guns
Milestone 1: Proxy actors now equip remote players' right-hand weapons and play armed idle/locomotion poses when weaponDrawn=true. Adds rightHand weapon slot to equippedItems protocol, weapon graph variable support (iSyncGunDown: 0=drawn, 1=holstered), and weapon FSM events (weaponDraw, readyStateEnter, gunDownStateEnter). Fixes two critical animation state churn bugs: frustum-visibility flicker no longer resets animation state on every update tick, and idle proxies no longer register as changed on every frame. Includes WeaponBehavior graph loading via AIProcess::RequestLoadAnimationsForWeaponChange() and manual weapon attachment fallback. New docs/weapon-animation-sync.md reference guide maps animation events and variables from F4-Animation-Research. Experimental alert-state reassertion for armed proxies to test NPC combat state gating of weapon-ready poses.
2026-07-02 17:23:09 +12:00

7.0 KiB

Weapon Animation Sync Reference

Source: F4-Animation-Research unpacked XML (RaiderRootBehavior.xml, WeaponBehavior.xml)

Overview

Fallout 4 weapon animation is hierarchical:

  • RaiderRootBehavior — Master humanoid graph (1058 events, 299 variables)
  • WeaponWrappingBehavior — Injury/special-case wrapper
  • WeaponBehavior — Gun-specific FSM (state machine)
  • Clips — WPN* shared anims + Weapon//* per-weapon overrides

For proxy actors to hold and fire weapons, the animation graph must switch from MTBehavior (unarmed) to WeaponBehavior when a weapon is equipped.


Key Graph Variables

Root Graph (RaiderRootBehavior)

Variable Type Role
iSyncGunDown int Weapon state: 0=ready/drawn, 1=holstered/lowered
iRifleDrawnStateID int Rifle-specific drawn state (confirm exact values in-game)
RifleDrawnCurrentState int Current rifle state mirror
iAttackState int Attack sub-state (0=idle, 1=attacking, etc.)
isFiring bool Currently firing (true only during fire animation)
iSyncFireState int Fire state mirror (syncs with attack events)
IsAttackReady bool Can initiate attack
GunGripPointer (struct) Hand IK to weapon grip

WeaponBehavior Graph

Uses similar ints but delegates to RaiderRoot for most state. Primary events drive FSM transitions; graph variables control blending.


Key Animation Events

Events are edge-triggered (fire once on transition); graph must reach the target state to play the corresponding clip.

Draw / Holster Lifecycle

Event RaiderRoot WeaponBehavior Effect
weaponDraw fires accepts Start draw animation (hand to gun)
weaponSheathe (WeaponBehavior may handle internally)
readyStateEnter fires Weapon drawn and ready to fire
gunDownStateEnter fires Weapon lowered (walking with gun holstered)
gunDownStateExit fires Exiting lowered state
unEquip fires End draw (return to unarmed)

Fire / Attack

Event RaiderRoot WeaponBehavior Effect Notes
fireSingle fires accepts Single shot, hip-fire Primary for non-ADS
attackStart fires accepts Generic attack start (melee also uses) May be melee fallback
attackStartAuto fires Auto-fire start Hold-to-fire weapons
attackStartOver ? Attack overflow / dual-wield? TBD
attackStartSlave fires Upper-body-only fire overlay (while moving) Combines with locomotion
attackRelease fires End attack (auto-fire release) Holds until received
weaponFire (Internal annotation; not an event) Marks fire frame in clips

Sighted / ADS

Event Status Role
sightedStateEnter TBD ADS enter
sightedStateExit TBD ADS exit

Defer ADS until gun draw + single-shot fire are stable.


Weapon Clip Categories

From F4-Animation-Research extracted/Character/Animations/:

Shared (All guns)

Clip Use
WPNEquip Draw animation
WPNIdleReady Idle, gun drawn
WPNIdleGunDown Idle, gun holstered but equipped
WPNIdleSighted Idle, aiming down sights
WPNFireSingleReady Fire animation, hip
WPNFireAutoReady Auto-fire loop, hip
WPNFireSingleSighted Fire, aiming
WPNReload Generic reload
WPNWalkForwardReady Walk with gun ready
WPNRunForwardReady Run with gun ready
SneakWPN* Sneak with gun
WPNGrenadeThrow Thrown weapon

Per-Weapon Overrides (Animations/Weapon//)

Folder Examples Use
44Pistol, 10mm, Pistol WPNAssemblyPose, WPNFireSingle*Slave Grip and fire pose (pistols hold differently than rifles)
HuntingRifle, CombatShotgun Per-weapon-specific fire, reload Shoulder-fired weapon animations
LaserRifle, PlasmaRifle Per-type variants Energy weapons (different recoil, charge-up anims)
Minigun WPNMeleeShredder, charge-up Spin-up and charging
GaussRifle, ChargeWeapons WPNChargeUp, WPNBoltCharge Charge mechanics

Phase 1 Validation Checklist

Testing on local player (to observe what graph vars actually change when playing animations):

  • Draw weapon (right-hand equipped)
    • Observe: Which graph vars flip? Which NotifyAnimationGraphImpl() calls return graphAccepted=true?
    • Expected: iSyncGunDown → 0, readyStateEnter fires, WPNIdleReady plays
  • Holster weapon (lower gun while keeping equipped)
    • Expected: iSyncGunDown → 1, gunDownStateEnter fires, WPNIdleGunDown plays
  • Fire single shot (hip-fire)
    • Expected: fireSingle fires, WPNFireSingleReady plays, isFiring flips
  • Walk / run with gun drawn
    • Expected: armed locomotion clips (WPNWalk*, WPNRun*) play; speed graph var scales movement
  • Log output in CommonwealthOnline.log should show var names and event accept/reject

Testing on proxy with test weapon equipped (temporary dev code):

  • Equip test weapon on proxy actor
  • Manually fire same events as local player
  • Verify proxy enters same FSM states and plays same clips
  • Confirm WeaponBehavior graph is active (check logs for which behavior is managing animation)

Exit Criteria:

Create a small reference table in this file (update below) with confirmed:

  1. Graph variable names, types, and observed value ranges
  2. Event names that return graphAccepted=true on proxy with weapon equipped
  3. Any variables/events that failed or misbehaved
  4. Notes on clip naming for armed locomotion

Validation Results

To be filled after Phase 1 testing

Confirmed Variables

Variable Type Values Notes
(pending)

Confirmed Events

Event Graph Accepted Notes
(pending)

Observed Issues

(none yet)


Integration Notes (for later phases)

Protocol Fields

  • rightHand: { slot: "rightHand", formId: "0001F4A6" } — Equipped WEAP form ID
  • weaponDrawn: true/false — Is weapon ready to fire (draw state; iSyncGunDown=0)
  • actionEvents[].eventName — Fire events: "fireSingle", "attackStart" (discrete actions)

Proxy Animation Apply Order (per frame)

  1. Equip weapon (if rightHand.formId changed) → Forces behavior graph reload
  2. Apply draw state (write iSyncGunDown based on weaponDrawn)
  3. Fire draw/holster events (if weaponDrawn edge-triggered)
  4. Apply locomotion (existing Speed/Sprint/Sneak logic)
  5. Fire locomotion events (existing moveStart/moveStop/etc.)
  6. Replay action events (fire fireSingle if queued)

Known Gaps (TBD in later phases)

  • ADS / sighted state
  • Auto-fire hold duration
  • Power armor weapon behaviors
  • Melee weapons (separate graph: MeleeBehavior)
  • Weapon equip/unequip animations for left hand and off-hand