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.
187 lines
7.0 KiB
Markdown
187 lines
7.0 KiB
Markdown
# 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/<Type>/* 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/<Type>/)
|
|
|
|
| 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
|