Add Pip-Boy state to transform sync

Adds optional `isPipboyOpen` to transform packets, remote player state, proxy animation logging, and fake client/player samples. Updates protocol and architecture docs to describe the new Pip-Boy open/raising/closing state and related movement-state handling.
This commit is contained in:
2026-06-30 16:00:07 +12:00
parent 4b8f5246c4
commit 4ed671464e
18 changed files with 196 additions and 19 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ The current system is still a local prototype, but the Fallout 4 plugin now has
both send and receive paths:
1. The Fallout 4 plugin reads local player transform data.
2. The plugin derives basic movement state and captures visible equipped
2. The plugin derives basic movement/menu state and captures visible equipped
apparel and player appearance snapshots on the game-thread polling path, then
sends them as optional data on transform packets.
3. The plugin sends transform packets to the Python relay server. The default
+112
View File
@@ -9,6 +9,118 @@ failed experiments, successful tests, and next steps.
---
## 2026-06-30 - Pip-Boy Third-Person Behavior Investigation
### Summary
Traced why no Pip-Boy animation plays on the proxy and established the engine-level root cause from the F4-Animation-Research unpack. Replaced the guessed graph events with the authoritative third-person Pip-Boy graph variables.
### Files Changed
- `plugin/include/F4TProxyAnimationSync.h`
- `plugin/src/F4TProxyAnimationSync.cpp`
- `changelog.md`
- `docs/dev-log.md`
### Details
- Log analysis: `isPipboyOpen=true` reaches the receiver (`recvPipboyOpen=true`), so capture/relay/storage are correct. Every guessed Pip-Boy event (`PipboyOpen`, `PipBoyOpen`, `pipboyOpen`, `Pipboy_Open`) returned `graphAccepted=false`, and the idle scan found `0` Pip-Boy idle forms.
- Searched `F:\Repos\F4-Animation-Research\unpacked`. The Pip-Boy raise/use animation set is **first-person only** (`Character\_1stPerson\Behaviors\Pipboy.hkx`, `Character\_1stPerson\Animations\Pipboy\*`).
- The third-person root graph (`Character\Behaviors\RaiderRootBehavior.xml`, used by the humanoid proxy) exposes only limited Pip-Boy data:
- `PipboyOffsetAnimationGen` (`BSOffsetAnimationGenerator`) blending `Animations\PipboyOffset.hkt`, whose `fOffsetVariable` is bound to variable index 186 = `bIsFemale` (a gender-selected, effectively always-on wrist-clearance additive, not an open/close toggle).
- `pipboyUp` is variable index 289 (`VARIABLE_TYPE_BOOL`) but is **not** in `eventNames` (event index -1) and is bound to no node in this behavior.
- `bBlockPipboy` is variable index 191 (`VARIABLE_TYPE_BOOL`); `bBlockPipboyStart`/`bBlockPipboyStop` are events 785/786 but appear in `0` transitions/triggers here.
- Conclusion: the stock third-person humanoid behavior has no open/close Pip-Boy transition, so neither graph events nor idle forms can reproduce the first-person raise pose. The only third-person Pip-Boy clips are `DynamicAnims\PipboyIdle1/2/3` (wrist-glance idles) and furniture-chair flavor poses, none exposed as a behavior event/state.
- Code change: drive the real `pipboyUp` / `bBlockPipboy` bool graph variables with write + read-back diagnostics; removed the fictional event candidate list; kept `TESIdleForm` playback as a fallback only when the graph does not expose the variable.
### Testing
- Ran `xmake build`; plugin build succeeded (pre-existing C4702 warnings in `F4TProxyActorController.cpp` only).
- In-game re-test still required to confirm whether the proxy graph even exposes `pipboyUp` (`pipboyUpWritten` / `pipboyUpReadBack` in the new log line).
### Decision
- Per project owner: no Pip-Boy animation for now. A custom third-person animation may be authored later when an animator is available.
- Removed the proxy Pip-Boy animation-trigger code (guessed events, `pipboyUp`/`bBlockPipboy` variable writes, and the `TESIdleForm` fallback) and their now-unused helpers/includes. Kept the lightweight `isPipboyOpen` state sync (capture, relay, storage, and diagnostics) so a future custom animation has the signal available. Rebuilt successfully.
### Known Issues
- A faithful third-person "using Pip-Boy" pose is not reachable from the stock behavior graph; achieving it would require custom animation work (porting the first-person raise to a third-person additive/idle plus a behavior hook).
### Next Steps
- Revisit only if a custom third-person Pip-Boy animation is authored; the `isPipboyOpen` flag is already available to drive it.
---
## 2026-06-30 - Pip-Boy Idle Playback Fallback
### Summary
Diagnosed the first in-game Pip-Boy sync attempt and added an idle-form fallback for proxy playback.
### Files Changed
- `plugin/src/F4TProxyAnimationSync.cpp`
- `changelog.md`
- `docs/dev-log.md`
### Details
- `CommonwealthOnline.log` showed `isPipboyOpen=true` reached the receiver, so capture and relay worked.
- The proxy rejected every diagnostic `NotifyAnimationGraph` Pip-Boy event candidate, matching the broader observation that raw locomotion graph events also return `graphAccepted=false` on the current proxy.
- Added a `TESIdleForm` scan for Pip-Boy-related idle records and a fallback that tries `AIProcess::PlayIdle` for open/close matching idles when graph event notification fails.
- Fixed idle-state change detection so missing locomotion tier does not make stationary proxy animation state log as changed every frame.
### Testing
- Ran `build.bat`; plugin build succeeded.
- In-game confirmation is still needed to see whether a matching Pip-Boy idle exists and returns `played=true` on the runtime proxy.
### Known Issues
- The fallback depends on loaded `TESIdleForm` records whose editor ID, anim event, or anim file includes `pip` and `open`/`close`.
- If no playable idle is found, the next step is using extracted HKX/AnimTextData to identify the actual Pip-Boy subgraph or adding a purpose-built proxy idle.
### Next Steps
- Re-test with two clients, open/close Pip-Boy, and check `CommonwealthOnline.log` for `Runtime proxy Pip-Boy idle candidate` and `played=true/false` lines.
---
## 2026-06-30 - Pip-Boy State Animation Sync
### Summary
Added a backward-compatible Pip-Boy state flag to transform sync so remote proxies can detect when another player opens or closes the Pip-Boy and attempt matching graph events.
### Files Changed
- `plugin/include/F4TRemotePlayerState.h`
- `plugin/include/F4TNetworking.h`
- `plugin/include/F4TProxyAnimationSync.h`
- `plugin/src/F4TNetworking.cpp`
- `plugin/src/F4TProxyActorController.cpp`
- `plugin/src/F4TProxyAnimationSync.cpp`
- `plugin/src/main.cpp`
- `server/fake_client.py`
- `server/fake_player.py`
- `protocol/packets.md`
- `protocol/player-sync.md`
- `docs/protocol.md`
- `docs/protocol-phase2-extensions.md`
- `docs/architecture.md`
- `server/README.md`
- `changelog.md`
- `docs/dev-log.md`
### Details
- Added optional `isPipboyOpen` to transform packets, remote-player state, fake-client output, and fake-player payloads.
- Captured local Pip-Boy activity from the C++ polling path using the Pip-Boy menu and `PipboyManager` state, so open/close changes trigger immediate transform sends.
- Added proxy-side edge detection for `isPipboyOpen` and a small diagnostic candidate event list for Pip-Boy open/close graph events.
- Logged graph acceptance for each candidate event so extracted HKX `AnimEventinfo` or Pip-Boy subgraph data can replace the diagnostic list once the real event names are confirmed.
### Testing
- Ran `python -m py_compile server\fake_client.py server\fake_player.py`; syntax check passed.
- Ran `build.bat`; plugin build succeeded.
- Build still reports pre-existing unreachable-code warnings in `F4TLocalAnimationGraphDebug.cpp` and `F4TProxyActorController.cpp`.
- In-game two-client confirmation is still required to verify which Pip-Boy event name, if any, the current proxy graph accepts.
### Known Issues
- The proxy Pip-Boy graph event names are still diagnostic candidates, not confirmed names from extracted HKX data.
- The first pass mirrors state/pose attempts only; it does not replicate the Pip-Boy UI screen on the remote actor.
### Next Steps
- Open and close Pip-Boy with two connected Fallout 4 instances and check `CommonwealthOnline.log` for `isPipboyOpen` send/receive state and `graphAccepted` results.
- Use `F4-Animation-Research/extracted` `AnimTextData` / `AnimEventinfo` or Pip-Boy subgraph data to replace failed candidate event names.
---
## 2026-06-29 - Late-Join Appearance Snapshot Fix
### Summary
+2
View File
@@ -26,6 +26,7 @@ This document describes the Phase 2 protocol extensions to support actor state f
"isSneaking": false,
"isJumping": false,
"weaponDrawn": false,
"isPipboyOpen": false,
"movementSpeed": 180.5,
"clientTime": 1717424000.123,
"serverTime": 1717424000.456,
@@ -66,6 +67,7 @@ This document describes the Phase 2 protocol extensions to support actor state f
| `isSneaking` | Boolean | NO | Local player is sneaking (default: false) |
| `isJumping` | Boolean | NO | Local player is jumping (default: false) |
| `weaponDrawn` | Boolean | NO | Local player has weapon drawn (default: false) |
| `isPipboyOpen` | Boolean | NO | Local player has Pip-Boy open, opening, closing, or raising (default: false) |
| `movementSpeed` | Number (float) | NO | Movement speed in game units/frame (default: 0.0) |
| `clientTime` | Number (double) | NO | Client-side timestamp (optional) |
| `serverTime` | Number (double) | NO | Server timestamp for diagnostics (optional) |
+4 -3
View File
@@ -60,7 +60,8 @@ If UDP discovery is unavailable, the plugin may fall back to probing
The protocol should be testable outside Fallout 4 before it is used inside the F4SE plugin.
`transform` packets carry position, movement state, optional `equippedItems`
apparel snapshots, and optional `appearance` snapshots for best-effort proxy
body/face visuals. The canonical field list and compatibility rules live in
`transform` packets carry position, movement/action state such as locomotion,
weapon, and Pip-Boy flags, optional `equippedItems` apparel snapshots, and
optional `appearance` snapshots for best-effort proxy body/face visuals. The
canonical field list and compatibility rules live in
[`protocol/packets.md`](../protocol/packets.md).