Add isCrouching to network, state and animation systems; enable proxy jump syncing with a jump-hold debounce and update animation descriptor and server tooling. Key changes: - Networking: F4TNetworking.h/cpp: added a_isCrouching, include "isCrouching" in transform packets and parsing, and logging. - Remote state: F4TRemotePlayerState.h: added isCrouching field. - Proxy animation: F4TProxyAnimationSync.*: added crouch fields, enabled jump sync, implemented ApplyJumpHoldState and jump hold timing, wrote crouch/jump bools into descriptors when available, updated event firing and logs. - Animation descriptor: F4AnimationDescriptor.cpp: added isJumping and isCrouching to bool variable list. - Local detection: main.cpp: added isCrouching in movement state, stubbed GetCrouchState(), adjusted jump hold timing and included crouch in outgoing transform calls. - Server/dev tooling: server/dev_server_app.py, fake_client.py, fake_player.py, README.md: added crouch reporting, toggle UI/control and fake client support for crouch, and updated docs/logging. - Docs: docs/dev-log.md updated with notes on jump/crouch fixes and testing. Rationale: ensure remote players can report crouch state and make jump animations transition reliably by debouncing jump state on proxies and writing available graph bools; also provide dev-server controls and fake-client support for testing.
264 lines
10 KiB
Markdown
264 lines
10 KiB
Markdown
# Server
|
|
|
|
This folder is for the external multiplayer test server.
|
|
|
|
The current server is a local-only TCP test server. It listens on
|
|
`127.0.0.1:7777`, accepts one or more clients, reads newline-separated JSON
|
|
packets, assigns incrementing `playerId` values, sends `welcome` packets, adds
|
|
`playerId` and `serverTime` to transform packets, broadcasts transform packets
|
|
to every other connected client, and broadcasts disconnect packets when clients
|
|
disconnect.
|
|
|
|
Transform packets may include optional movement-state fields such as
|
|
`isMoving`, `isSprinting`, `isSneaking`, `isJumping`, `isCrouching`, `weaponDrawn`, and
|
|
`movementSpeed`. The server preserves these fields automatically because it
|
|
broadcasts the original transform packet after adding server-owned fields.
|
|
|
|
This is still a local prototype. It does not make Fallout 4 multiplayer
|
|
playable yet.
|
|
|
|
## Run
|
|
|
|
Terminal server:
|
|
|
|
```bash
|
|
cd server
|
|
python server.py
|
|
```
|
|
|
|
Developer GUI server:
|
|
|
|
```bash
|
|
cd server
|
|
pip install -r requirements.txt
|
|
python dev_server_app.py
|
|
```
|
|
|
|
Then launch Fallout 4 through F4SE and move the player. The plugin should send
|
|
local player transform packets, and this server should print matching
|
|
`transform` packets.
|
|
|
|
In the developer GUI, the Fake Clients tab can create simple synthetic TCP
|
|
clients for local relay testing. Click `Start Server`, then click
|
|
`+ Add Fake Client`. Each fake client connects to `127.0.0.1:7777`, receives a
|
|
server-assigned `playerId`, appears in both GUI client tables, and sends one
|
|
idle transform per second for `F4TTestCell01`.
|
|
|
|
Select a fake client row to use the movement controls:
|
|
|
|
- `Set Idle`: returns the selected fake client to idle mode. It keeps its
|
|
current position, sends non-moving transforms once per second, and reports
|
|
`movementSpeed=0.0`.
|
|
- `Walk To Player`: makes the selected fake client walk in a straight line
|
|
toward the lowest connected real client with a valid transform snapshot. The
|
|
target point is offset by +150 units on X so the fake client does not stand
|
|
inside the real player. While moving, it sends normal transform packets at
|
|
about 10 Hz with `isMoving=true`; when it reaches the stop distance, it
|
|
returns to low-rate idle keep-alive transforms.
|
|
- `Walk Circle`: makes the selected fake client move continuously around a
|
|
simple circle in `F4TTestCell01`, sending normal moving transforms at about
|
|
10 Hz.
|
|
- `Jump Once`: sends a short normal-movement jump arc with `isJumping=true`,
|
|
then restores the fake client's ground Z and resumes the current script.
|
|
- `Toggle Sneak`: toggles the fake client's persistent `isSneaking` flag. It
|
|
does not move the fake client by itself.
|
|
- `Leave Cell`: sends a `cell_change` transform to fake cell `DEADBEEF` and
|
|
keeps the fake client connected in a low-rate `Left Cell` mode.
|
|
- `Return To Cell`: sends a `cell_change` transform back to `0B000F99`, restores
|
|
`worldspaceId=""`, and returns the fake client to `Idle`.
|
|
- `Teleport Test`: sends one `movementType=teleport` transform to a
|
|
deterministic test-cell offset, then returns the fake client to `Idle`.
|
|
|
|
These controls are developer test tooling only. They do not change the network
|
|
protocol, server relay behavior, or Fallout 4 plugin behavior.
|
|
|
|
If the server is not running, the plugin should log a warning and Fallout 4
|
|
should continue launching normally.
|
|
|
|
## Structure
|
|
|
|
- `server.py`: thin terminal launcher for the local test server.
|
|
- `server_core.py`: reusable `FalloutTogetherServer` core for networking,
|
|
lifecycle control, packet relay, stats, client snapshots, and log callbacks.
|
|
- `client_session.py`: `ClientSession` state model for connected clients.
|
|
- `dev_server_app.py`: PySide6 developer GUI that starts/stops the reusable
|
|
server core, displays logs, shows live stats, and lists connected clients.
|
|
- `fake_player.py`: GUI fake-player test tooling. It owns background synthetic
|
|
TCP clients that connect through the normal server socket, send transform
|
|
packets, and run simple dev movement scripts such as Idle and Walk To Player.
|
|
- `fake_client.py`: lightweight receiver for testing welcome, transform, and
|
|
disconnect packets without launching a second Fallout 4 instance.
|
|
- `requirements.txt`: optional Python dependencies for the desktop developer
|
|
GUI.
|
|
|
|
The reusable server core exposes methods intended for a future desktop dev
|
|
server UI:
|
|
|
|
- `start()`
|
|
- `serve_forever()`
|
|
- `stop()`
|
|
- `is_running()`
|
|
- `get_clients()`
|
|
- `get_stats()`
|
|
- `add_log_listener()`
|
|
- `remove_log_listener()`
|
|
|
|
`get_clients()` and `get_stats()` return snapshot dictionaries, not live
|
|
internal server state. Log listeners receive the same useful console messages
|
|
that the terminal launcher prints today.
|
|
|
|
## Current Test Flow
|
|
|
|
Terminal 1:
|
|
|
|
```bash
|
|
cd server
|
|
python server.py
|
|
```
|
|
|
|
Terminal 2:
|
|
|
|
```bash
|
|
cd server
|
|
python fake_client.py
|
|
```
|
|
|
|
Then launch Fallout 4 through F4SE and move the player.
|
|
|
|
Alternative GUI flow:
|
|
|
|
```bash
|
|
cd server
|
|
pip install -r requirements.txt
|
|
python dev_server_app.py
|
|
```
|
|
|
|
Click `Start Server`, then run `python fake_client.py` or launch Fallout 4
|
|
through F4SE. You can also click `+ Add Fake Client` to create a GUI-managed
|
|
synthetic client that sends an idle transform once per second. Select a fake
|
|
client row and click `Set Idle`, `Walk To Player`, `Walk Circle`, `Jump Once`,
|
|
`Toggle Sneak`, `Leave Cell`, `Return To Cell`, or `Teleport Test` to control
|
|
its dev script/action. Click `- Remove Selected` to disconnect it cleanly.
|
|
|
|
Expected behavior:
|
|
|
|
- The server assigns a `playerId` to each connected client and sends each client
|
|
a `welcome` packet.
|
|
- The server receives transforms from the Fallout 4 plugin.
|
|
- The server adds `playerId` and `serverTime` to each transform packet before
|
|
broadcast.
|
|
- The server preserves optional movement-state fields on transform packets.
|
|
- The server broadcasts those transform packets to connected clients except the
|
|
sender.
|
|
- `fake_client.py` receives broadcast transform packets.
|
|
- `fake_client.py` stores remote player state by `playerId`.
|
|
- GUI fake clients connect as ordinary external TCP clients, receive a
|
|
`welcome` packet, store their assigned `playerId`, and send idle transforms
|
|
for cell `0B000F99`.
|
|
- GUI fake clients can be switched between `Idle` and `Walk To Player` scripts
|
|
from the Fake Clients tab.
|
|
- GUI fake clients can also run `Walk Circle`, `Left Cell`, and one-shot jump,
|
|
sneak toggle, return-to-cell, and teleport test actions from the Fake Clients
|
|
tab.
|
|
- Walk To Player uses `FalloutTogetherServer.get_clients()` snapshots to find
|
|
the lowest non-fake client with a valid last transform, then walks gradually
|
|
toward that player with a simple straight-line movement test.
|
|
- When a client disconnects, the server removes that client and broadcasts a
|
|
`disconnect` packet with the departed `playerId` to the remaining clients.
|
|
- `fake_client.py` removes disconnected players from its in-memory
|
|
`remote_players` table.
|
|
|
|
The fake client exists so broadcast behavior can be tested before coordinating a
|
|
second Fallout 4/F4SE instance. It stores remote player transform state only; it
|
|
does not spawn remote actors or send movement.
|
|
|
|
## Validation
|
|
|
|
From inside this folder:
|
|
|
|
```bash
|
|
python -m py_compile server.py server_core.py client_session.py fake_client.py dev_server_app.py fake_player.py
|
|
```
|
|
|
|
Then run the terminal server:
|
|
|
|
```bash
|
|
python server.py
|
|
```
|
|
|
|
In another terminal, run:
|
|
|
|
```bash
|
|
python fake_client.py
|
|
```
|
|
|
|
To validate the developer GUI instead of the terminal launcher:
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
python dev_server_app.py
|
|
```
|
|
|
|
Click `Start Server`, then connect `fake_client.py` or the Fallout 4 plugin.
|
|
To validate GUI fake clients, click `+ Add Fake Client` and confirm the fake
|
|
client appears in the Fake Clients table and Connected Clients table with an
|
|
assigned player ID. Select the fake client, click each Fake Clients action, and
|
|
confirm the Script, Cell ID, Position, and console log output update as expected.
|
|
Click `Walk To Player` with no real Fallout 4 client connected and confirm the
|
|
GUI logs that no real player target is available. Click `- Remove Selected` and
|
|
confirm it disconnects.
|
|
|
|
For in-game validation, launch Fallout 4 through F4SE and confirm the plugin
|
|
connects, receives a `welcome` packet, sends transforms, and receives relayed
|
|
remote transforms or disconnect packets when another client is connected. In
|
|
`F4TTestCell01`, select a GUI fake client and click `Walk To Player`; the fake
|
|
client should walk smoothly toward the real player's latest transform offset and
|
|
then stop near that offset. Test `Walk Circle`, `Jump Once`, `Toggle Sneak`,
|
|
`Leave Cell`, `Return To Cell`, and `Teleport Test` while watching the proxy to
|
|
confirm movement, jump/sneak state, cell mismatch holding, return, and teleport
|
|
snap behavior.
|
|
|
|
## Implemented
|
|
|
|
- Start local server
|
|
- Accept client connections
|
|
- Assign server-owned player IDs
|
|
- Send welcome packets
|
|
- Receive transform packets
|
|
- Add server timestamps
|
|
- Preserve optional transform fields
|
|
- Broadcast transforms to other connected clients
|
|
- Broadcast disconnect packets
|
|
- Handle disconnect cleanup
|
|
- Reusable server core with thread-safe client/stat snapshots
|
|
- Log callbacks for future server console UI
|
|
- PySide6 developer server GUI with live logs, stats, connected-client table,
|
|
and a Fake Clients tab that can spawn idle synthetic TCP clients
|
|
- GUI-managed fake clients that receive welcome packets and send idle transforms
|
|
- Fake Clients tab movement controls for `Set Idle` and `Walk To Player`
|
|
- GUI-managed fake clients that can walk gradually toward a real Fallout 4
|
|
client using normal transform packets
|
|
- Fake Clients tab dev scripts/actions for `Jump Once`, `Toggle Sneak`,
|
|
`Walk Circle`, `Leave Cell`, `Return To Cell`, and `Teleport Test`
|
|
|
|
## Working In Fake Client Only
|
|
|
|
- Receiving welcome packets
|
|
- Receiving transform broadcasts
|
|
- Storing remote player state
|
|
- Removing disconnected remote players
|
|
|
|
## Planned Later
|
|
|
|
- Additional fake client scripts such as Walk Square, Follow Player, Sprint
|
|
Toggle, Weapon Drawn Toggle, Disconnect After Delay, and multi-fake-player
|
|
choreography
|
|
- Gameplay synchronization
|
|
- Authentication
|
|
- Public matchmaking
|
|
- Anti-cheat
|
|
- Persistence
|
|
- Quest state
|
|
- Settlement state
|
|
- Large-scale world simulation
|