105 lines
3.6 KiB
Markdown
105 lines
3.6 KiB
Markdown
# Headless GameServer
|
|
|
|
This target runs the authoritative `InternalGameServer` without SDL, OpenGL,
|
|
audio, Lua, or rendering dependencies. On Windows it exposes a deterministic
|
|
lockstep session through a Boost.Beast WebSocket listener.
|
|
|
|
## Build
|
|
|
|
Windows:
|
|
|
|
```powershell
|
|
cmake -S server -B server/build
|
|
cmake --build server/build --config Release --target GameServer
|
|
ctest --test-dir server/build -C Release --output-on-failure
|
|
```
|
|
|
|
Linux:
|
|
|
|
```bash
|
|
cmake -S server -B server/build -DCMAKE_BUILD_TYPE=Release
|
|
cmake --build server/build --target GameServer --parallel
|
|
ctest --test-dir server/build --output-on-failure
|
|
```
|
|
|
|
Eigen3 must either be installed or be available at
|
|
`thirdparty/eigen-5.0.0`. The headless target reads ordinary filesystem resources
|
|
only; ZIP-backed campaign loading belongs to the later content-loading
|
|
milestone.
|
|
|
|
Run until interrupted:
|
|
|
|
```bash
|
|
./server/build/GameServer
|
|
```
|
|
|
|
For a multi-configuration Windows build, the executable is normally
|
|
`server/build/Release/GameServer.exe`.
|
|
|
|
For smoke tests, `--ticks N` limits execution and `--no-sleep` skips the
|
|
real-time delay.
|
|
|
|
Start the multiplayer lockstep server:
|
|
|
|
```powershell
|
|
.\server\build\Release\GameServer.exe --campaign battle_zone_multiplayer --location uni_exterior
|
|
```
|
|
|
|
The listener defaults to `ws://0.0.0.0:8080`. Launch the Windows graphical game
|
|
afterward and select `battle_zone_multiplayer`; that campaign connects to
|
|
`ws://127.0.0.1:8080`. Other campaigns continue to use the in-process server.
|
|
|
|
The server sends one state snapshot when a player connects, then broadcasts one
|
|
numbered command bundle every 100 ms. Bundles may be empty. Destination input is
|
|
scheduled two ticks (200 ms) in the future. Tick IDs, rather than server or
|
|
client wall-clock values, define simulation time.
|
|
|
|
If `--location` is omitted, the campaign's configured start location is used.
|
|
`--campaigns PATH` selects a different campaign registry. Content paths are
|
|
resolved from the process working directory, so run from the repository root
|
|
when using the bundled `resources/` tree.
|
|
|
|
Available startup options:
|
|
|
|
```text
|
|
--campaign ID
|
|
--location ID
|
|
--campaigns PATH
|
|
--address IP
|
|
--port N
|
|
--tick-ms 100
|
|
--ticks N
|
|
--no-sleep
|
|
```
|
|
|
|
Network mode requires a 100 ms tick; another `--tick-ms` value is rejected.
|
|
The selected campaign's `networkPlayerSlots` lists pre-existing character IDs
|
|
assigned to connections in order. `networkCompatibility` is a release token
|
|
that must be changed whenever deterministic content changes; clients reject a
|
|
different token. The bundled multiplayer Battle Zone has two slots (`player`
|
|
and `player2`) and rejects additional clients. Disconnecting
|
|
releases the slot. The bot's random autonomous controller is disabled in
|
|
multiplayer.
|
|
|
|
The graphical client executes presentation behavior after building its runtime
|
|
`Location`; the headless content pass loads authoritative navigation, NPC,
|
|
interactive-object, trigger, teleport, taxi, and animation metadata. Lua and
|
|
dialogue-driven shared multiplayer behavior is not yet supported.
|
|
|
|
## Tests
|
|
|
|
CTest covers:
|
|
|
|
- repeated `LocationGameState::setup()` preserving mutable runtime state;
|
|
- ticking a prepared location with zero players;
|
|
- deterministic fixed-100 ms replay behavior;
|
|
- protocol-v2 parsing, validation, target normalization, state hashing, and
|
|
two-tick command ordering;
|
|
- a WebSocket initial-state/slot/destination/tick integration test;
|
|
- idle server startup;
|
|
- headless loading of `battle_zone_multiplayer/uni_exterior`.
|
|
|
|
The lockstep implementation currently targets identical executable and content
|
|
builds. Diagnostic state hashes detect divergence, but there is no automatic
|
|
checkpoint resynchronization or reconnect input history yet.
|