Add serverWorldState packet and GUI controls

Introduce a server-authoritative world-state packet to control weather and time from the dev server GUI. Adds protocol docs and message type (serverWorldState), a new Weather/Time tab in dev_server_app.py, server-side broadcasting in server_core.py, and preset utilities in server/world_state_presets.py. Plugin changes (F4TNetworking.cpp, F4TWorldStateSync.*) queue and apply incoming serverWorldState on the game thread, run `set gamehour` for all clients, and run `fw <8-digit-id>` on the assigned player 1 then force the host to relay a worldState snapshot. Also includes parsing/validation of hex form IDs, logging improvements, and minimal fake client handling. This ensures consistent server-driven time/weather and documents usage and presets.
This commit is contained in:
2026-06-23 23:03:34 +12:00
parent 70933db6e5
commit 4c17e70620
14 changed files with 757 additions and 3 deletions
+1
View File
@@ -9,6 +9,7 @@ The first protocol should be simple and focused on player transform sync.
- Welcome packet
- Transform packet
- World state packet (host time and weather) — see [`world-state.md`](world-state.md)
- Server world state packet (dev GUI weather/time) — see [`server-world-state.md`](server-world-state.md)
- Disconnect packet
## Future Packet Types
+5 -1
View File
@@ -11,6 +11,7 @@ welcome
transform
worldState
worldStateHost
serverWorldState
disconnect
```
@@ -23,10 +24,12 @@ Current behavior:
server, and broadcast to other connected clients.
- `worldStateHost` is sent in `welcome` and when the host disconnects to
reassign host to the lowest remaining `playerId`.
- `serverWorldState` is sent by the server to all connected clients when the
dev server GUI sets weather or time.
- `disconnect` is sent by the server when a client disconnects.
The Fallout 4 plugin sends transform packets and receives `welcome`,
`transform`, `worldState`, and `disconnect` packets. Received transforms are
`transform`, `worldState`, `serverWorldState`, and `disconnect` packets. Received transforms are
stored as plain remote-player state. Non-host clients apply received world state
on the game thread.
@@ -39,6 +42,7 @@ welcome
transform
worldState
worldStateHost
serverWorldState
disconnect
```
+66
View File
@@ -0,0 +1,66 @@
# Server World State Packet
Server-authoritative weather and time control from the dev server GUI.
## Authority
- **Time** (`timeHHmm`): sent to **all** clients; each runs `set gamehour to HHmm`.
- **Weather** (`weatherConsoleArg`): sent to **all** clients, but only **player 1** runs `fw <8-digit-id>`. Player 1 should also be the world-state host so the usual `worldState` relay updates other clients.
## Packet Format
Time-only (all clients):
```json
{
"type": "serverWorldState",
"timeHHmm": "1900",
"serverTime": 1780212128.301
}
```
Weather (all clients receive; only player 1 acts):
```json
{
"type": "serverWorldState",
"weatherConsoleArg": "00148c45",
"weatherFormId": "00148C45",
"serverTime": 1780212128.301
}
```
## Field Definitions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | yes | Must be `"serverWorldState"` |
| `timeHHmm` | string | no | 24-hour clock value for `set gamehour to HHmm` |
| `weatherConsoleArg` | string | no | Exact argument for `fw` on player 1 (8-digit lowercase hex) |
| `weatherFormId` | string | no | Relay form ID used in host `worldState` broadcast |
| `serverTime` | number (double) | no | Relay timestamp |
## Client Apply Rules
- **Time:** all clients apply `set gamehour to HHmm` on the game thread.
- **Weather:** only the client with assigned `playerId == 1` runs `fw <weatherConsoleArg>`.
- Weather commands are scheduled on the F4SE game thread from the network receive path.
- After player 1 runs `fw`, the world-state host immediately relays `worldState` with `weatherFormId`.
Edit `server/world_state_presets.py` so each preset uses the exact `fw` ID that works in your console (for example `0000015e`).
## Preset Weather Console Args
| Label | Default `fw` arg |
|-------|------------------|
| Clear | `00148c3c` |
| Cloudy | `00148c42` |
| Overcast | `00148c43` |
| Fog | `00148c44` |
| Rain | `00148c45` |
| Radstorm | `00148c47` |
| Glowing Sea | `001b9779` |
## Backward Compatibility
Older clients that do not handle `serverWorldState` ignore the packet safely.