Implemented the real server

This commit is contained in:
Vladislav Khorev committed 2026-10-30 16:37:30 +06:00
1 parent 931236bec0
commit 075750442f
22 files changed
+1130 -44

No files matched your search

+143
View File
@@ -0,0 +1,143 @@
# WebSocket Networking: First Iteration
## Scope
The first networking iteration adds a Windows-only WebSocket transport using
Boost.Asio and Boost.Beast.
The goal of this iteration is connection and replication stability. It does not
yet implement multiplayer commands, authentication, per-connection players,
state deltas, or presentation-event replication.
## Runtime Architecture
### Server
`WebsocketGameServer` wraps the headless `InternalGameServer`.
- It accepts any WebSocket connection.
- It sends the current complete game state immediately after connection.
- It broadcasts the current complete state every five seconds.
- Incoming WebSocket messages are read and discarded.
- The authoritative simulation remains on the main server thread.
- Network sessions only receive serialized state and never access
`InternalGameServer` directly.
The standalone server creates the existing fixed player ID `"player"` and does
not enable the battle-zone test bot.
### Client
`WebsocketGameClient` implements `IGameServer`.
- It connects asynchronously to `ws://127.0.0.1:8080/`.
- Received messages are queued by the network thread and applied on the game
thread from `update()`.
- It maintains an internal `InternalGameServer` replica so existing snapshot
consumers and transitional runtime-state bindings continue to work.
- `submit()` intentionally discards all commands.
- `drainEvents()` returns no events.
- Client-side save and load calls are ignored because persistence remains
server-side.
`RemoteGameServerHost` prepares local presentation resources and runtime
locations against the replicated state. It does not advance authoritative
simulation or write Lua/dialogue auxiliary state back to the server.
## Campaign Routing
The graphical game uses stable router objects for `IGameServer` and
`IGameServerHost`, allowing existing UI and runtime references to remain valid.
When `NETWORK` is defined:
- `battle_zone` uses `WebsocketGameClient` and `RemoteGameServerHost`.
- Every other campaign uses `InternalGameServer` and `LocalGameServerHost`.
The WebSocket client is created only when `battle_zone` is selected and is
destroyed when that campaign is unloaded.
## JSON Protocol
Messages use a versioned JSON envelope:
```json
{
"protocolVersion": 1,
"type": "state",
"payload": {
"schemaVersion": 1
}
}
```
The payload temporarily uses the existing `GameState::save()` representation.
The client applies it through `InternalGameServer::load()`.
Malformed JSON, unsupported protocol versions, unsupported message types, and
invalid state payloads are logged and ignored.
This temporary full-state format is expected to be replaced or separated from
the persistence schema as command handling and production replication are
implemented.
## Build Configuration
Networking is enabled only for Windows:
- `proj-windows/CMakeLists.txt` defines `NETWORK`, compiles the WebSocket client
and remote host, and links `ws2_32` and `mswsock`.
- `server/CMakeLists.txt` defines `NETWORK` for the Windows `GameServer`, compiles
the WebSocket server, and links the Windows socket libraries.
- Linux, Android, and Web builds do not define `NETWORK` and do not compile the
network transport.
The previous Web-build `NETWORK` definition was removed.
## Running
Build the server:
```powershell
cmake -S server -B server/build
cmake --build server/build --config Debug --target GameServer
```
Run it from the repository root:
```powershell
.\server\build\Debug\GameServer.exe --campaign battle_zone --location uni_exterior
```
The listener defaults to `0.0.0.0:8080`. It can be changed with:
```text
--address IP
--port N
```
Launch the Windows game and select `battle_zone`. The client connects to
`127.0.0.1:8080`. Selecting another campaign continues to use the local server.
## Verification
The implementation was verified with:
- A successful Windows graphical-game build.
- A successful Windows headless-server build.
- Server state and protocol tests.
- A WebSocket smoke test receiving the initial state and the next five-second
broadcast.
- A check that the shared `"player"` exists and the battle-zone test bot is not
created for the network server.
## Current Limitations
- All clients share the fixed player ID `"player"`.
- Client commands are not sent to the server.
- The server does not process commands.
- State is sent as a complete snapshot rather than a delta.
- There is no authentication, authorization, reconnect loop, or session identity.
- Presentation events are not replicated.
- The endpoint is hardcoded in the graphical client.
- Multiplayer Lua and dialogue behavior remains unsupported.