Use authoritative FO4 animation variable names

Replace previously guessed graph variable names/types with the real FO4 humanoid movement behavior names (from MTBehavior.hkx) and update syncing logic accordingly. F4AnimationDescriptor now lists only the variables F4T drives (Speed, SpeedSmoothed, IsSprinting, bInJumpState, iIsInSneak) to avoid clobbering graph state; Direction is intentionally not written. Enable proxy sneak sync using the INT32 iIsInSneak, change SpeedSampled -> SpeedSmoothed, and update all Set/Get calls and diagnostic logging to the new names. Fix jump detection by relying on the actor IsJumping() API (removing the noisy vertical-speed heuristic that produced false positives and caused proxies to remain in jump state). Changes touch descriptor, proxy sync, puppet, main logic, and related docs to explain the rationale and testing notes.
This commit is contained in:
2026-06-05 15:29:31 +12:00
parent 5ba440ab5d
commit 6a38e7226c
7 changed files with 220 additions and 144 deletions
+13
View File
@@ -1,5 +1,18 @@
# Animation Sync Analysis: Fallout 4 Together vs TiltedEvolution
> **Resolution update (2026-06-05):** The "variable names may be wrong" hypothesis below is
> now confirmed and fixed. The real FO4 humanoid graph variable names + types were extracted
> from `MTBehavior.hkx` (unpacked in the `F4-Animation-Research` repo) and applied to the code.
> Authoritative set actually driven by F4T:
> - `Speed`, `SpeedSmoothed` (float / `VARIABLE_TYPE_REAL`)
> - `IsSprinting`, `bInJumpState` (bool / `VARIABLE_TYPE_BOOL`)
> - `iIsInSneak` (int / `VARIABLE_TYPE_INT32`, 0 = standing, 1 = sneaking)
>
> Earlier guesses (`direction`, `isMoving`, `isSneaking`, `isCrouching`, `speedSampled`,
> `speedDamped`, `SpeedSampled`) do **not** exist on this graph and silently failed. `Direction`
> exists but is movement-relative-to-facing (not world heading), so it is intentionally left
> unwritten to avoid strafing artifacts. See `docs/dev-log.md` (2026-06-05) for the change set.
## Problem Statement
Your Fallout 4 Together animations aren't working on proxy actors. You have animation sync code in `F4TProxyAnimationSync.cpp` attempting to set graph variables by name (`Speed`, `IsSprinting`, etc.), but the variables aren't being applied or synced correctly.
+102
View File
@@ -7,6 +7,108 @@ failed experiments, successful tests, and next steps.
---
## 2026-06-05 - Fix False Jump State Masking Locomotion Animation
### Summary
After grounding the graph variable names (see entry below), an in-game log
(`Fallout4Together.log`) showed locomotion variables were now correct
(`graphSpeedReadBack=true(373.0)` while running), but proxies still never showed walk/run
animation. Root cause: the local player was reporting `isJumping=true` almost continuously
while merely running, so proxies were perpetually forced into the jump state, which masks
ground locomotion.
### Files Changed
- `plugin/src/main.cpp`
### Details
- The log proved the graph layer is healthy: when moving, `recvMovementSpeed` ~545,
`computedGraphSpeed=373`, and `Speed`/`SpeedSmoothed` read back as 373 (engine not
clobbering them). `moveStart` is accepted on idle->move transitions.
- But `jumping=true` stuck on for 2.5s+ stretches during plain running. Source diagnostic:
`Local jump detection: apiJumping=false, verticalSpeed=2724.7, heldJumping=true`.
- `GetVerticalSpeed()` is `(z - prevZ) / dt`, which spikes to thousands of units/sec on flat
ground (tiny dt + z micro-jitter) - far above the 80 u/s `kJumpVerticalSpeedThreshold`,
so `derivedJumping` fired constantly. The real `IsJumping()` API was accurate (true only
on actual jumps).
- Fix: jump detection now relies solely on `a_player.IsJumping()`; removed the
vertical-speed-derived jump trigger. `verticalSpeed` is still computed and logged for
diagnostics. (`kJumpVerticalSpeedThreshold` is now unused.)
### Testing
- `xmake build` succeeds with no new warnings.
- In-game verification pending: with false jumps gone, proxies should hold the locomotion
state and play walk/run while `Speed` drives the blend; `jumping=true` should now appear
only during real jumps.
### Known Issues
- `kJumpVerticalSpeedThreshold` constant is now unused (left in place; harmless).
- Locomotion transition event names still unverified against behavior-graph `eventNames`.
### Next Steps
- Confirm walk/run now animates in-game and capture a fresh log.
- If a real jump is occasionally missed by `IsJumping()`, consider a *sane* vertical-speed
fallback (much higher threshold + clamp on dt) rather than the old raw heuristic.
---
## 2026-06-05 - Animation Graph Variables Grounded in Real Behavior Data
### Summary
Replaced the guessed FO4 animation-graph variable names with the authoritative names and
types extracted from the real humanoid movement behavior graph
(`Meshes\Actors\Character\Behaviors\MTBehavior.hkx`), unpacked to XML in the companion
`F4-Animation-Research` repo. Almost every previous graph-variable name was wrong, so
`SetGraphVariable*` calls were silently failing and proxy animation state was never applied.
### Files Changed
- `plugin/include/F4TProxyAnimationSync.h`
- `plugin/src/F4TProxyAnimationSync.cpp`
- `plugin/src/F4AnimationDescriptor.cpp`
- `plugin/src/F4TProxyPuppet.cpp`
- `docs/animation-sync-analysis.md`
### Details
- Ground truth comes from `MTBehavior.hkx` -> `hkbBehaviorGraphStringData::variableNames`
(67 entries) paired with the parallel `hkbBehaviorGraphData::variableInfos` types.
- Corrected names / types now used:
- `Speed`, `SpeedSmoothed` -> `VARIABLE_TYPE_REAL` (float). Previous code wrote
`speed`/`speedSampled`/`speedDamped`, none of which exist on this graph.
- `IsSprinting`, `bInJumpState` -> `VARIABLE_TYPE_BOOL` (bool).
- `iIsInSneak` -> `VARIABLE_TYPE_INT32` (int, 0 = standing, 1 = sneaking). Sneak was
previously modelled (incorrectly) as a bool `isSneaking`, so it never worked.
- `F4AnimationDescriptor` now lists ONLY the variables we actually drive. This matters
because `LoadAnimationVariablesToCache()` bulk-writes every descriptor variable from the
snapshot; listing extra variables would clobber graph state we do not intend to touch
(e.g. `IsPlayer`, `bAllowRotation`, `LookAt*`).
- Re-enabled `kEnableProxySneakSync` now that the correct int variable name is known.
- `Direction` is deliberately NOT written: the graph `Direction` is movement direction
relative to facing (radians), not the absolute world heading (`angleZ`) we carry. Writing
`angleZ` would make proxies strafe/moonwalk. Left at the graph default (forward) until a
relative movement direction is added to the protocol.
- Did NOT touch the network/JSON field names (`isMoving`, `isSprinting`, ...) — those are
protocol fields and stay as-is.
### Testing
- `xmake build` succeeds (only pre-existing C4702 unreachable-code warnings in
`F4TProxyActorController.cpp`, unrelated to this change).
- In-game verification still required: confirm walk/run/sprint blend, sneak pose on proxies,
and watch the `Proxy anim diag` log line for `graphSpeedReadBack`/`speedSmoothedReadBack`
now reporting `true` (variables found) instead of failing silently.
### Known Issues
- Locomotion transition EVENT names (`moveStart`, `SprintStart`, jump events, sneak events)
are unchanged and still empirically chosen; they are a separate axis from variables and
should be cross-checked against the behavior graph `eventNames` next.
- Weapon-drawn sync remains disabled; that state lives in the weapon wrapping behavior, not
`MTBehavior`, and needs its own research pass.
### Next Steps
- Verify in-game and capture a fresh `Fallout4Together.log` diagnostic.
- Cross-check the transition event names against the behavior graph `eventNames` arrays.
- If sneak works, investigate the weapon wrapping behavior for the weapon-drawn variable.
---
## 2026-06-05 - Jump Animation Fix (Correct Event Names)
### Issues Resolved