Files
shadow-over-bishkek001/server/README.md
T

3.6 KiB

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:

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:

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:

./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:

.\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:

--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.