63 lines
4.2 KiB
Markdown
63 lines
4.2 KiB
Markdown
# Multiplayer - plan and status
|
|
|
|
Multiplayer is only available for users of a server (not in the standalone file).
|
|
|
|
## Decisions
|
|
|
|
- Modes: **versus** (every player a master with an own heart), **coop** (every player an own master,
|
|
together against AI masters and/or the humans) and a **coop campaign of 20 missions**.
|
|
- 2 to 4 players per match; free slots can be AI masters.
|
|
- The match **pauses while a player is missing** (connection lost); a player who **leaves** is replaced by an AI.
|
|
- The humans (hero waves of the Order) as a third party (can be switched off), chat, alliances/teams.
|
|
- Coop is "separate but helpful": own heart, gold, mana, research and creatures; allies never fight each
|
|
other, their creatures help each other, gold can be sent, allied ground can be walked; a fallen heart only
|
|
knocks out that player (who may keep watching); the allies win when all enemies have fallen.
|
|
- Lobby: an open list of matches under *Multiplayer* in the title menu; the host chooses mode, map, AI slots,
|
|
humans on/off and teams; logged-in users join; the match starts when everybody is ready.
|
|
|
|
## Architecture: deterministic lockstep
|
|
|
|
Every client runs the same simulation (the same WASM module, so floating point results are identical).
|
|
The server does not simulate; it relays:
|
|
|
|
1. Clients send their **commands** (dig, build, cast, hand, orders, ...) to the server.
|
|
2. Every 100 ms the server sends **turn N**: the commands of all players for that turn.
|
|
3. Each client applies turn N and simulates two fixed steps of 50 ms. Turns arrive in order; a client waits
|
|
for the next turn, so a missing player stalls everybody - exactly the "pause while missing" rule.
|
|
4. Clients send a **checksum** of the game state every few seconds; a mismatch (desync) is reported.
|
|
|
|
Only the commands travel over the network, so bandwidth is tiny and no game state has to be serialised
|
|
per turn. Fog of war, particles and the camera are local and not part of the shared state.
|
|
|
|
## What is there already
|
|
|
|
- **Per-master state** (`game.rs`): every master has his own gold, mana, hand, research, payday, flag,
|
|
core... `Game::switch_to(side)` puts one master in the active fields, the simulation walks through all
|
|
masters step by step. A single player game has no stored masters and is unaffected.
|
|
- **Commands** (`commands.rs`): every order a player gives is an `Act` (`Dig`, `Room`, `Tower`, `Trap`,
|
|
`Cast`, `Flag`, `Pickup`, `Drop`, `Slap`, `Attack`, `Guard`, `CancelOrders`, ...) wrapped in a
|
|
`Command { side, seq, act }`. Creature targets are *ids*, so they mean the same on every client.
|
|
The tools in `main.rs` only queue commands now - nothing touches the world directly.
|
|
- **Steps**: the simulation runs in fixed steps of `STEP` = 50 ms (`Game::update` feeds real time into
|
|
them, `Game::apply_turn(cmds, steps)` is the lockstep entry point). Commands are applied at step
|
|
boundaries, so single player and a match run exactly the same path. Particles, effects and the camera
|
|
keep running in real time: they are local and not part of the shared state.
|
|
- **Who speaks**: messages, hints and interface sounds belong to the master who is being processed
|
|
(`Game::speaking`); what another master orders never shows up on my screen.
|
|
- Savegames, tests and the standalone file are unchanged: `cargo test --release` covers the command path
|
|
(including "the same actions on both paths build the same world").
|
|
|
|
## Steps
|
|
|
|
| # | Step | Status |
|
|
|---|---|---|
|
|
| A | Simulation per master: gold, mana, research, rooms, hand, flag, traps, payday... per side; up to four masters (red, green, blue, yellow) | built |
|
|
| B | All player actions as commands (`Command` + `Game::apply`), single player uses the same path; fixed time step | built |
|
|
| C | Server: lobby and match relay over WebSocket (axum), turns, pause on disconnect, AI takeover on leave, chat | next |
|
|
| D | Client: *Multiplayer* menu (lobby, create, join, ready, teams), WebSocket bridge in `dc_plugin.js`, chat, gold sending | planned |
|
|
| E | Alliances and coop rules, AI masters for free and abandoned slots | planned |
|
|
| F | Coop campaign: 20 missions with story (EN/DE) | planned |
|
|
|
|
Still open on the way to C: player owners (today side 1 is the humans' and 2/3 the rivals' - four
|
|
player sides need their own `Owner`s), the turn/turn-boundary client loop, and the state checksum.
|