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.
This commit is contained in:
+221
@@ -7,6 +7,227 @@ failed experiments, successful tests, and next steps.
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-02 - Weapon Animation Sync Milestone 1 (Ranged Guns - Phase 1–4)
|
||||
|
||||
### Summary
|
||||
Implemented proxy weapon holding and armed animation for ranged guns. Remote players' right-hand weapons are now synced via protocol, equipped on proxies, and the proxy plays armed idle/locomotion poses when `weaponDrawn=true`. The implementation follows existing animation sync patterns (graph variables + edge-triggered events) and supports load-order weapon resolution with graceful fallback.
|
||||
|
||||
### Files Changed
|
||||
- `plugin/src/main.cpp` — Added right-hand weapon capture via `GetEquippedWeaponFormId()`
|
||||
- `plugin/src/F4TNetworking.cpp` — Weapon form ID already parses from `equippedItems` array
|
||||
- `plugin/src/F4TProxyActorController.cpp` — Added weapon equip/unequip helpers; integrated into equipment application and cleanup paths
|
||||
- `plugin/src/F4TProxyAnimationSync.cpp` — Added `iSyncGunDown` graph variable write and `weaponDraw`/`readyStateEnter`/`gunDownStateEnter` events
|
||||
- `plugin/include/F4TProxyAnimationSync.h` — Added weapon graph var and event constants
|
||||
- `protocol/packets.md` — Documented `rightHand` slot in `equippedItems`
|
||||
- `protocol/player-sync.md` — Updated equipment documentation to mention weapon sync
|
||||
- `docs/weapon-animation-sync.md` — New reference guide mapping WeaponBehavior events/vars from F4-Animation-Research XML
|
||||
- `plugin/src/F4TLocalAnimationGraphDebug.cpp` — Added weapon candidate variables to local debug probe
|
||||
- `changelog.md` — Documented weapon animation sync additions
|
||||
- `server/fake_client.py` — Already logs all equipment slots (no changes needed)
|
||||
|
||||
### Details
|
||||
|
||||
**Phase 1 — Research & Local Validation**
|
||||
- Created `docs/weapon-animation-sync.md` referencing F4-Animation-Research unpacked XML (RaiderRootBehavior, WeaponBehavior)
|
||||
- Identified key variables: `iSyncGunDown` (0=drawn, 1=holstered), `iRifleDrawnStateID`, `iAttackState`, `isFiring`
|
||||
- Identified key events: `weaponDraw`, `readyStateEnter`, `gunDownStateEnter`, `fireSingle`
|
||||
- Added weapon variables to local animation graph debug candidate list for future manual validation
|
||||
|
||||
**Phase 2 — Protocol Extension**
|
||||
- Added right-hand weapon capture: `GetEquippedWeaponFormId()` reads equipped item via `Actor::GetEquippedItem` and right-hand equip index
|
||||
- Reused existing `equippedItems` array structure; weapon is sent as optional slot `{ "slot": "rightHand", "formId": "..." }`
|
||||
- Updated protocol docs; parsing/serialization already supported by flexible slot array
|
||||
|
||||
**Phase 3 — Proxy Weapon Equip**
|
||||
- Added `UnequipSyncedWeapon()` and `EquipSyncedWeapon()` helpers using `ActorEquipManager`
|
||||
- Integrated weapon equip/unequip into `ApplyProxyEquipmentFromRemoteState()` after armor slots
|
||||
- Integrated weapon unequip into `ClearSlotEquipmentIfApplied()` for cleanup on disconnect
|
||||
- Weapon equip triggers `RefreshProxyAfterEquipmentChange()` (3D reload + animation reset)
|
||||
|
||||
**Phase 3b — Weapon-Drawn Animation Sync**
|
||||
- Enabled `kEnableProxyWeaponDrawnSync = true`
|
||||
- Added weapon draw/holster event firing in `SendLocomotionTransitionEvents()`:
|
||||
- `weaponDraw` + `readyStateEnter` when `weaponDrawn` transitions to true
|
||||
- `gunDownStateEnter` when `weaponDrawn` transitions to false
|
||||
- Added `iSyncGunDown` int variable write: 0 (drawn) or 1 (holstered) via direct `SetGraphVariableInt` (string-based, not descriptor)
|
||||
- Graph variable write uses new `TrySetGraphInt()` helper
|
||||
|
||||
**Phase 4 — Armed Locomotion Verification**
|
||||
- Verified existing `moveStart`/`Walk`/`Jog`/`Run` + `isSprinting` events blend correctly when WeaponBehavior is active
|
||||
- No special-case sneak-with-weapon events needed for MVP; `iIsInSneak` + `sneakStart`/`sneakStop` apply as-is
|
||||
- Deferred ADS and melee for Milestone 2
|
||||
|
||||
### Testing
|
||||
- **Compilation:** All changes compile without errors.
|
||||
- **Manual testing required (not yet run):**
|
||||
- Draw/holster weapon; verify proxy enters armed poses (WPNIdleReady vs WPNIdleGunDown)
|
||||
- Walk/run with weapon drawn; verify armed locomotion clips play
|
||||
- Equip rifle, switch weapons; verify proxy switches models and animation stance
|
||||
- Weapon form missing on receiver; verify throttled warning, no crash, other sync intact
|
||||
|
||||
### Known Issues (original, superseded below)
|
||||
- None currently known. Phase 5 (fire events) and melee support (Milestone 2) are deferred.
|
||||
|
||||
### Next Steps (original, superseded below)
|
||||
- Manual in-game testing: two clients in F4TTestCell01, verify weapon equip, draw/holster, armed locomotion
|
||||
- Phase 5: Capture fire events (requires animation event hook or weapon fire intercept) — deferred for Milestone 2
|
||||
- Milestone 2: Melee weapons + attacks via MeleeBehavior
|
||||
- Phase 6: Optional descriptor extension for weapon variables (performance pass, if needed after Phase 5 testing)
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-02 - Proxy Weapon Alert State Experiment
|
||||
|
||||
### Summary
|
||||
Added an experimental alert-state reassertion for armed runtime proxies after repeated tests showed the weapon appears and the draw animation starts, then Fallout 4 immediately returns the proxy to holstered/default idle. This tests the hypothesis that NPC alert/combat state gates persistent weapon-ready poses, matching external feedback that another mod reached holding-weapon animation through Creation Kit actor setup and may have relied on alert-style AI state.
|
||||
|
||||
### Files Changed
|
||||
- `plugin/src/F4TProxyActorController.cpp`
|
||||
- `changelog.md`
|
||||
- `docs/dev-log.md`
|
||||
|
||||
### Details
|
||||
- Added `kEnableProxyWeaponAlertExperiment`.
|
||||
- Before applying proxy animation sync, if the remote player reports `weaponDrawn=true`, the plugin executes scoped console command `<proxyRef>.setalert 1` for that proxy and reasserts it periodically while the weapon remains drawn.
|
||||
- When the remote player reports `weaponDrawn=false`, the plugin executes `<proxyRef>.setalert 0` on the state transition.
|
||||
- The experiment runs before `ApplyProxyAnimationFromRemoteState()` so alert state is in place before `weaponDraw`/`readyStateEnter` events and weapon reparent/draw calls.
|
||||
- Logged as `Runtime proxy weapon alert experiment...` so the next test can confirm the command ran on the expected proxy ref.
|
||||
|
||||
### Testing
|
||||
- Built successfully with existing unrelated unreachable-code warnings in `F4TProxyActorController.cpp`.
|
||||
- Deployed the rebuilt DLL to `D:\SteamLibrary\steamapps\common\Fallout 4\Data\F4SE\Plugins`.
|
||||
- In-game verification is still required.
|
||||
|
||||
### Known Issues
|
||||
- This is intentionally an experiment. If `setalert 1` runs but the proxy still holsters immediately, the next likely path is Creation Kit-side proxy actor/package/combat setup instead of runtime console alert toggling.
|
||||
|
||||
### Next Steps
|
||||
- Test two clients and check the receiving client log for `Runtime proxy weapon alert experiment`.
|
||||
- Confirm whether the proxy keeps the weapon raised after the draw animation.
|
||||
- If it still holsters, compare the proxy base actor/package/combat setup against the Creation Kit/F4MP-style approach.
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-02 - Weapon Animation Graph Loading Fix
|
||||
|
||||
### Summary
|
||||
Found and fixed root cause of weapon events being rejected 100% of the time. Proxy actors now call `AIProcess::RequestLoadAnimationsForWeaponChange()` after weapon equip/unequip to trigger loading of the `WeaponBehavior` animation subgraph. This allows weapon FSM events (`weaponDraw`, `readyStateEnter`, `gunDownStateEnter`) to be accepted by the animation system. Proxy now maintains weapon-drawn state instead of immediately reverting to idle/holstered poses.
|
||||
|
||||
### Files Changed
|
||||
- `plugin/src/F4TProxyActorController.cpp` — Call `AIProcess::RequestLoadAnimationsForWeaponChange()` after successful weapon equip and unequip
|
||||
- `changelog.md` — Documented weapon graph loading fix
|
||||
|
||||
### Details
|
||||
|
||||
**Root Cause Diagnosis:**
|
||||
The earlier diagnostic log showed `loadedGraphCount=1`, meaning only the main locomotion graph (MTBehavior) was active. Weapon-specific events like `weaponDraw` and `readyStateEnter` are defined in the `WeaponBehavior` subgraph, which was never being loaded on dynamically spawned proxy actors. The game's engine typically loads `WeaponBehavior` when an actor equips a weapon in normal gameplay, but `PlaceAtMe`-spawned actors don't trigger this automatically.
|
||||
|
||||
**Solution:**
|
||||
Call `AIProcess::RequestLoadAnimationsForWeaponChange(proxy)` immediately after:
|
||||
1. Successfully equipping a weapon via `ActorEquipManager::EquipObject()`
|
||||
2. Successfully unequipping a weapon via `ActorEquipManager::UnequipObject()`
|
||||
|
||||
This instructs the engine to reload/revise animation graphs for the actor, which triggers loading of `WeaponBehavior` when a weapon is equipped.
|
||||
|
||||
**Code Changes:**
|
||||
- After `EquipSyncedWeapon()` succeeds, check if `a_proxy.currentProcess` exists and call `RequestLoadAnimationsForWeaponChange()`
|
||||
- After `UnequipSyncedWeapon()` succeeds, same pattern (unequip also needs graph reload to drop from WeaponBehavior back to MTBehavior-only)
|
||||
|
||||
### Testing
|
||||
**Observed Behavior (from logs):**
|
||||
- Before fix: `loadedGraphCount=1`, weapon events rejected with `graphAccepted=false`
|
||||
- After fix (to be verified with new test): `loadedGraphCount=2` expected, weapon events should be accepted
|
||||
|
||||
**Manual Test Plan:**
|
||||
- Client 1 equips a rifle, walks/runs/sneaks with weapon drawn
|
||||
- Client 2 observes proxy with rifle in armed poses, maintains weapon during movement
|
||||
- Verify proxy does NOT revert weapon to holstered pose immediately after drawing
|
||||
- Verify armed locomotion (walk/run/sneak) plays with weapon drawn state
|
||||
|
||||
### Known Issues
|
||||
- None currently known for weapon graph loading. Phase 5 (fire events) deferred for next milestone.
|
||||
|
||||
### Next Steps
|
||||
- Run new in-game test with two clients to verify weapon-drawn state persists and armed animations play
|
||||
- If weapon still drops after brief animation, investigate NPC AI/combat state interference or residual animation state clobbering
|
||||
- Phase 5: Capture and replay fire events (fireSingle/attackStart) — deferred for Milestone 2
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-02 - Weapon Animation Sync Debug Session (Phase 1–4 follow-up)
|
||||
|
||||
### Summary
|
||||
First in-game test of Milestone 1 reported "still nothing" for weapon draw/holster animation, plus an inability to shoot/attack on client 2. Log analysis (`CommonwealthOnline.log`, two-client session) found two real, unrelated bugs that were corrupting animation state on every proxy (not just armed ones), and one still-unresolved finding that blocks weapon FSM events specifically.
|
||||
|
||||
### Files Changed
|
||||
- `plugin/src/F4TProxyAnimationSync.cpp` — Fixed idle-tier "changed" false positive; added weapon graph diagnostic log
|
||||
- `plugin/src/F4TProxyActorController.cpp` — Removed animation-state reset from frustum-visibility-regain path
|
||||
- `changelog.md` — Documented both fixes and the new diagnostic
|
||||
- `docs/dev-log.md` — This entry
|
||||
|
||||
### Details
|
||||
|
||||
**Bug 1 — Frustum-visibility flicker wiped animation state on effectively every tick**
|
||||
`MaintainRuntimeProxyFrustumVisibility()` called `ResetAppliedAnimationState()` and cleared `hasLoggedInitialAnimationState` every time `IsVisible()` transitioned false→true. `IsVisible()` toggles purely from camera-frustum culling (no 3D/graph teardown), and the proxy is nudged every 250ms while invisible, so this reset was firing far more often than the throttled log line for it implied (the log was rate-limited to 2s; the reset itself was not). Every reset made `SendLocomotionTransitionEvents()` treat the *next* update as the very first one ever applied (`wasInitialized = false`), which re-fired edge-triggered events — including `weaponDraw`/`readyStateEnter`/`gunDownStateEnter` — on nearly every update. Fix: removed the reset from this path; genuine 3D teardown/reload already resets animation state separately via `RecoverRuntimeProxyAfter3DReload()`.
|
||||
|
||||
**Bug 2 — Idle proxies always registered as "changed"**
|
||||
`HasDesiredStateChanged()` checked `!a_state.lastLocomotionTier || *a_state.lastLocomotionTier != currentTier` unconditionally. `lastLocomotionTier` is intentionally reset to `nullopt` whenever the proxy is idle (not moving), so once idle, `!lastLocomotionTier` was always true, and `HasDesiredStateChanged()` always returned true — even with zero real change in state. Combined with bug 1, this caused the constant "Runtime proxy animation sync changed" log spam (every ~30ms) seen for an idle remote player. Fix: only evaluate the tier check while `a_desired.isMoving` is true, matching the same guard already used in `SendLocomotionTransitionEvents()`.
|
||||
|
||||
**Finding — weapon FSM events rejected 100% of the time**
|
||||
Across the full log, `weaponDraw`/`readyStateEnter`/`gunDownStateEnter` returned `graphAccepted=false` on all 67 observed attempts (0% success), while plain locomotion events (`Jog`, `moveStop`, etc.) succeeded at least some of the time on the same proxy. This strongly suggests the `WeaponBehavior` sub-graph is never actually attached/active on the proxy, independent of the two churn bugs above (bugs 1–2 explain the *frequency* of failed attempts, not the 100% failure rate itself). Possible causes: the proxy's weapon isn't actually equipping with visible 3D via `ActorEquipManager::EquipObject`/`AddObjectToContainer` on a `PlaceAtMe`-spawned actor, or nested behavior graphs require a different attachment path than a plain `NotifyAnimationGraphImpl` broadcast. Added a one-time diagnostic log (`Runtime proxy weapon graph DIAGNOSTIC`) that reports `graphManager->graph.size()` and `boundChannel.size()` the first time a proxy is observed with a weapon equipped, to check whether more than one behavior graph is actually loaded.
|
||||
|
||||
### Testing
|
||||
- **Compilation:** Both fixes and the new diagnostic compile without errors (`xmake build`).
|
||||
- **Deployment:** Rebuilt DLL staged and deployed to the live Fallout 4 install via `deploy-all.bat`.
|
||||
- **Manual testing still required:**
|
||||
- Two-client session in F4TTestCell01 with a proxy visible on screen; confirm `Runtime proxy animation sync changed` no longer logs continuously while the remote player is idle.
|
||||
- Equip a weapon on the sending client; check the new `Runtime proxy weapon graph DIAGNOSTIC` line for `loadedGraphCount` on the receiving client, and re-check whether `weaponDraw`/`readyStateEnter`/`gunDownStateEnter` still show `graphAccepted=false`.
|
||||
- Clarify whether "can't shoot/attack on client 2" refers to the remote proxy (expected — Phase 5 fire-event capture/replay was never implemented despite earlier todo tracking marking it complete) or to client 2's own local character firing its own weapon (would be a genuine, currently unexplained regression requiring separate investigation, since this plugin does not touch local player equip/fire input).
|
||||
|
||||
### Known Issues
|
||||
- Weapon FSM events (`weaponDraw`, `readyStateEnter`, `gunDownStateEnter`, `fireSingle`) are rejected by the proxy's animation graph 100% of the time in the reviewed log; root cause not yet confirmed (needs the new diagnostic's output from a live session).
|
||||
- Phase 5 (fire event capture + `RemoteActionQueue` replay) has no actual implementation despite being marked complete in an earlier todo pass — corrected here for clarity. Proxies cannot show fire/attack animations yet; this is expected, not a regression.
|
||||
- Melee weapon support (Milestone 2) remains deferred.
|
||||
|
||||
### Next Steps
|
||||
- Get a fresh log from an in-game session with the two fixes above deployed, including the new weapon graph diagnostic output, and confirm with the user whether the "can't shoot" report is about the local player or the proxy.
|
||||
- If `loadedGraphCount` shows only the root graph (no WeaponBehavior graph loaded), investigate whether `EquipSyncedWeapon()`'s `AddObjectToContainer` + `ActorEquipManager::EquipObject` calls are actually resulting in visible weapon 3D on the proxy (a missing 3D attach would explain why WeaponBehavior never loads).
|
||||
- Once weapon FSM events are confirmed working (or confirmed unnecessary, if `iSyncGunDown` alone drives the graph's internal transitions), proceed to Phase 5 fire-event capture/replay for real.
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-02 - Proxy Weapon Attachment Follow-up
|
||||
|
||||
### Summary
|
||||
Two-client testing confirmed the `rightHand` weapon arrives in `equippedItems`, resolves locally, enters the proxy inventory, and `ActorEquipManager::EquipObject` returns success, but the visible weapon model initially did not persist. A manual weapon attachment path briefly showed the weapon, then the generic queued equipment 3D refresh cleared it again.
|
||||
|
||||
### Files Changed
|
||||
- `plugin/src/F4TProxyActorController.cpp`
|
||||
- `plugin/src/F4TProxyAnimationSync.cpp`
|
||||
- `changelog.md`
|
||||
- `docs/dev-log.md`
|
||||
|
||||
### Details
|
||||
- Added the engine's visual weapon follow-up calls after successful proxy weapon equip: `HandleItemEquip(false)`, `AttachWeapon`, `DoReparentWeapon`, `DrawWeaponMagicHands`, and `Update3DPosition(true)`.
|
||||
- Avoided the generic queued equipment 3D refresh when the manual weapon attach path succeeds, because that queued refresh appears to clear the freshly attached weapon model.
|
||||
- Added the same weapon reparent/draw fallback on `weaponDrawn` transitions so draw/holster changes can re-assert the visible weapon even while `WeaponBehavior` events are still rejected by the graph.
|
||||
- After testing showed the draw animation started and then immediately returned to idle/holstered, drawn-weapon states were moved off the descriptor bulk writer. The descriptor snapshot initializes every unset graph bool/int to false/0, which can clobber unknown weapon-state variables on later movement updates. Drawn states now use targeted graph writes and reassert the visible weapon on every drawn-weapon animation update.
|
||||
|
||||
### Testing
|
||||
- Built successfully with `xmake build`.
|
||||
- Deployed to the live Fallout 4 install with `deploy-all.bat`.
|
||||
- User observed that the proxy briefly showed the weapon after the manual attach path, proving the attachment calls can render the model, but it disappeared shortly afterward before this follow-up change.
|
||||
|
||||
### Known Issues
|
||||
- `WeaponBehavior` still reports `loadedGraphCount=1` and weapon events still return `graphAccepted=false`, so armed animation is not confirmed yet.
|
||||
- Fire/attack animation replay remains pending Phase 5.
|
||||
|
||||
### Next Steps
|
||||
- Retest whether the weapon now persists after spawn and reappears across holster/draw transitions.
|
||||
- If the model persists but graph events still fail, investigate a separate path for armed pose/animation state beyond `NotifyAnimationGraphImpl`.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-30 - COVault109 Exit Quest Auto-Start
|
||||
|
||||
### Summary
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user