Files
Commonwealth-Online-Public/protocol/player-sync.md
T
andrew 8c09e91534 Add basic movement state to transform packets
Add optional movement-state fields (isMoving, isSprinting, isSneaking, isJumping, weaponDrawn, movementSpeed) to transform packets and wire them end-to-end. Plugin changes: extend F4TNetworking API and RemotePlayerState, derive movement speed/jump state on the game-thread, validate values, include fields when formatting transform JSON, and add throttled remote movement-state logging. main.cpp adds sampling, speed/vertical calculations, jump hold logic, and change-detection to avoid extra sends. Networking parsing (F4TNetworking.cpp) reads optional booleans/floats safely, preserves backwards compatibility, and clears movement-state logs on disconnect. Proxy controller includes a TODO note for future animation use. Server and docs: update protocol and packet docs, dev-log, server README, and fake_client.py to parse/display optional fields safely. Also add several .cursor rule files for coding, documentation, protocol, project overview, and testing guidance. This milestone prepares the data model for later animation/behavior work while keeping existing relay behavior unchanged.
2026-06-02 13:27:40 +12:00

4.7 KiB

Player Sync

Player synchronization is the first major technical goal for Fallout 4 Together. The current implementation is still a local networking prototype.

Current Implemented Flow

Fallout 4 Plugin ↔ Local Python Server ↔ Other Clients
        ↓
Plugin Remote Player State

The Fallout 4 plugin currently reads the local player's transform and sends it to the local Python server. Normal movement sends are throttled separately from local movement logs: while the player is moving, the plugin targets roughly 10 Hz and skips sends until position or rotation changes meaningfully. The server assigns a playerId, adds serverTime, and broadcasts transform packets to other connected clients.

The Fallout 4 plugin also receives server packets on a background networking thread. It stores its assigned playerId, stores remote transform state by remote playerId, and removes remote state when disconnect packets arrive. server/fake_client.py remains a lightweight test receiver for the same packet lifecycle.

The plugin's game-thread proxy actor controller can now read a copied snapshot of this remote-player state and move the single placed test proxy actor F4TProxyRemotePlayer01REF in F4TTestCell01. The networking thread still does not touch Fallout 4 actors or references.

Current Remote Player State Model

The plugin and fake client store remote players by playerId.

Each remote player state entry tracks:

playerId
x
y
z
angleZ
movementType
cellId
worldspaceId
clientTime
serverTime
isMoving
isSprinting
isSneaking
isJumping
weaponDrawn
movementSpeed
lastReceivedLocalTime

Required transform packet fields are type, playerId, x, y, z, angleZ, and cellId. worldspaceId, movementType, clientTime, and serverTime are optional; interior test cells may omit worldspaceId. Movement state fields are also optional and default to not moving, not sprinting, not sneaking, not jumping, weapon holstered, and speed 0.0 when missing.

This model proves the data shape and lifecycle before spawning remote actors. For the current visual milestone, the controller represents only one remote player and chooses the lowest available playerId if more than one remote player exists.

Implemented

  • The plugin sends local player transform packets.
  • Normal transform sends are independent from movement logging and are thresholded to avoid packet-per-frame traffic.
  • The plugin receives welcome packets and stores its assigned playerId.
  • The plugin receives broadcast transform packets.
  • The plugin ignores transform packets for its own assigned playerId.
  • The plugin stores remote player state by playerId.
  • The plugin receives disconnect packets and removes remote player state.
  • The server assigns incrementing playerId values.
  • The server sends welcome packets.
  • The server adds playerId and serverTime to transform packets.
  • The server broadcasts transform packets to other connected clients.
  • The fake client stores remote player state by playerId.
  • The server broadcasts disconnect packets.
  • The fake client removes disconnected remote players from its state table.
  • The plugin moves the single placed test proxy actor from a thread-safe remote-player snapshot on the game-thread update path.
  • Normal proxy movement is smoothed toward the latest received target, while cell_change, worldspace_change, and teleport transforms snap directly to avoid slow movement across large discontinuities.
  • Transform packets now include basic movement state data for future animation work, but the proxy actor does not apply animations from that state yet.

Transform Cadence

Normal local movement currently uses three separate rates:

  • Network sends target roughly 10 Hz while the player is moving.
  • Sends are skipped until position changes by about 3 game units or rotation changes by about 0.02 radians.
  • Local movement logs stay much slower, around once per second, so Fallout4Together.log remains readable.

cell_change, worldspace_change, and teleport movement types bypass the normal send interval and are sent immediately. The receiving plugin still stores remote transform state on the networking thread and moves actors only from the game-thread proxy controller.

No Fallout 4 remote actor is dynamically spawned yet. No animation graph sync or animation application is implemented yet.

Planned Later

  • Add one proxy actor per remote player after the single-proxy test is stable.
  • Dynamically spawn remote actors only after placed-proxy movement is stable.

Not Required Yet

  • Full animation graph sync
  • Combat sync
  • Inventory sync
  • Quest sync
  • Dialogue sync
  • Settlement sync
  • Accurate physics sync
  • Public networking or matchmaking