# World State Packet Host-authoritative time and weather sync for the Commonwealth Online prototype. ## Authority - The server tracks a `worldStateHostPlayerId` for the session. - The first connected client becomes host. When the host disconnects, the server reassigns host to the lowest remaining `playerId` and broadcasts `worldStateHost`. - Only the current host sends `worldState` packets. - The Python relay validates the sender and broadcasts to all other clients. Promoted hosts keep their already-synced local time and weather; reassignment should not change world state for remaining clients. ## worldStateHost Packet Sent in `welcome` (initial host) and broadcast when the host disconnects: ```json { "type": "worldStateHost", "worldStateHostPlayerId": 2, "serverTime": 1780212128.301 } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `type` | string | yes | Must be `"worldStateHost"` | | `worldStateHostPlayerId` | integer | yes | Connected player ID that is now world-state host | | `serverTime` | number (double) | no | Relay timestamp | The `welcome` packet also includes optional `worldStateHostPlayerId` so new joiners know the current host immediately. ## Packet Format ```json { "type": "worldState", "playerId": 1, "gameHour": 14.25, "gameDaysPassed": 12.5, "weatherFormId": "00123456", "clientTime": 1780212128.301, "serverTime": 1780212128.301 } ``` ## Field Definitions | Field | Type | Required | Description | |-------|------|----------|-------------| | `type` | string | yes | Must be `"worldState"` | | `playerId` | integer | yes (server) | Injected by server; identifies the sending host | | `gameHour` | number (float) | yes | In-game hour of day, `0.0`–`24.0` | | `gameDaysPassed` | number (float) | yes | In-game days passed global | | `weatherFormId` | string | no | 8-character hex `TESWeather` form ID; omitted or `""` when host is indoors | | `clientTime` | number (double) | no | Sender Unix epoch seconds | | `serverTime` | number (double) | no | Relay timestamp added by server | ## Send Cadence (Host) - About 1 Hz heartbeat while connected - Immediate send when `weatherFormId` changes - Immediate send when `gameHour` or `gameDaysPassed` jumps beyond a small threshold (wait, sleep, console time changes) ## Client Apply Rules - **Time:** non-host clients snap local calendar globals when host values differ beyond threshold. - **Weather:** non-host clients apply forced weather only when the local player is in an exterior cell. - Missing optional fields use safe defaults on receive. ## Backward Compatibility Older clients that do not send or parse `worldState` continue to work. Transform sync is unchanged.