Document teams, gold sending, spectators and editor co-op runs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-05 19:59:43 +01:00
1 parent fc9c49d4ca
commit 2dbd9039fb
2 files changed
+41 -8

No files matched your search

+6 -2
View File
@@ -117,8 +117,12 @@ Ctrl+Z/Y undo/redo, Ctrl+C/V copy/paste the selected block, Delete removes it, C
save; *Published* adds the campaign to the list every logged-in player sees and can open (as a save; *Published* adds the campaign to the list every logged-in player sees and can open (as a
copy) and play. Server API: `/api/campaigns`, `/api/public/campaigns` (see `server/src/main.rs`). copy) and play. Server API: `/api/campaigns`, `/api/public/campaigns` (see `server/src/main.rs`).
- **Co-op**: the campaign last opened in the editor can be played in a co-op match (Multiplayer, - **Co-op**: the campaign last opened in the editor can be played in a co-op match (Multiplayer,
*Editor campaign*), one mission per match; missions need a map of at least 72x72 and a goal besides *Editor campaign*); missions need a map of at least 72x72 and a goal besides rival masters. The run
rival masters. See `docs/MULTIPLAYER.md`. goes on over several missions: after a win the host starts the next mission (the branch of the reached
goal, or *next mission*) for everybody, after a defeat the same one again. Every player takes his five
strongest creatures and a fifth of his gold along; the host keeps the progress (missions done, chosen
branches, run seed). The room list shows the campaign's name and the current mission. See
`docs/MULTIPLAYER.md`.
## File format (`src/campaign_doc.rs`) ## File format (`src/campaign_doc.rs`)
+35 -6
View File
@@ -76,8 +76,37 @@ per turn. Fog of war, particles and the camera are local and not part of the sha
message); the relay keeps it in the room and adds it to the `start` message (room updates only show message); the relay keeps it in the room and adds it to the `start` message (room updates only show
`"editor": true`). Every client builds the mission with `campaign::start_editor_coop_mission(doc, i, seed)` from `"editor": true`). Every client builds the mission with `campaign::start_editor_coop_mission(doc, i, seed)` from
the room's shared seed (rival masters of the map and the Rivals goal are left out, like in built-in co-op), the room's shared seed (rival masters of the map and the Rivals goal are left out, like in built-in co-op),
then the usual co-op setup. Block scripts run from side 0 in the fixed step. When the mission ends, the match then the usual co-op setup. Block scripts run from side 0 in the fixed step.
ends and the players go back to the lobby; there is no branching to a next mission and no progress is stored. - **Editor campaign runs over several missions**: when a mission ends, the host's end dialog offers *Next mission*
(won: the branch of the reached goal, `CampaignDoc::next_mission_choice` with `Game::match_goal_done`) or *Try
again* (lost: the same mission); the others see "waiting for the host" and may leave. The host sends
`{"t":"next","mission":i,"seed":run_seed,"carry":[[side,Carry],..]}`; the relay checks that he is side 0 and that
the mission exists, resets the turn clock, drops pending orders and sends `next` (seed, sides, teams, AI seats,
carry, no campaign) to every client. The clients keep the campaign of the `start`, drop turns of the old mission
and build the new one with `start_editor_coop_mission(doc, i, run_seed)`, then `campaign::apply_coop_carry`.
The carry (`campaign::coop_carry_from`, computed by the host from the shared final world) is per master: his
five strongest creatures and 20% of his gold, like the single-player `Carry`. The host stores the progress
(missions done, chosen branches, run seed) in local storage under `dc.coop_editor_progress` (campaign name ->
`CampaignProgress`). A run ends when no next mission fits co-op.
- **Teams in versus**: on the Match page every seat has a team A-D (default: a team of its own), set with
`{"t":"set_team","team":n}` for the own seat; the host may add `"side"` for a free or AI seat. Only before the
start. Room updates carry `team` per seat, the room list `teams`, and `start` a `teams` list in the order of
`sides` (`Game::set_teams`). Masters of one team are allies exactly like co-op partners (`Game::allied`: no
attacks, their creatures help each other, a tower spares them, the fog shows the team mates' ground, creatures
and towers). AI seats take part in teams as well.
- **Fallen hearts**: a master whose soul core falls is out (`Game::out_sides`, shared state, in the checksum). His
creatures fight on without a heart (no economy: no mana, no new creatures, no payday), the creatures in his hand
are put down, the core tiles become floor and his orders are ignored. The player watches: no fog, free camera,
chat; the match goes on for the others (`Game::spectating`, local only).
- **End of a match**: decided only from shared state (`Game::check_match_end`), so every client stops in the same
step: a versus match is over when only one team has masters (or AI seats) left - that team wins, the others lose;
if all seats are one team, the humans' gate is the enemy. A mission (co-op) is lost when every heart fell, and
won by its goals (mana springs count for any master). The checksum only mixes in *whether* the world still runs.
- **Gold for allies**: `Act::SendGold { to, amount }` (100, 500, 1000 or all), in the creature overview and the
pause menu (the ally button switches between allies). It runs in the fixed step on every client, never sends
more than the sender has nor more than the receiver's treasury takes; the receiver gets a message and a sound.
- **Room list**: rooms show what they play - versus, the built-in co-op mission, or the editor campaign's name and
the title of its current mission (`campaign`, `title` in `rooms` and `room`).
- **Shared simulation side**: the shared part of a step (waves, units, towers, rivals, dwarves) runs with the - **Shared simulation side**: the shared part of a step (waves, units, towers, rivals, dwarves) runs with the
first master switched in on every client; only the end check and the fog use the local master. first master switched in on every client; only the end check and the fog use the local master.
@@ -89,12 +118,12 @@ per turn. Fog of war, particles and the camera are local and not part of the sha
| B | All player actions as commands (`Command` + `Game::apply`), single player uses the same path; fixed time step | 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, ping | built | | C | Server: lobby and match relay over WebSocket (axum), turns, pause on disconnect, AI takeover on leave, chat, ping | built |
| D | Client: *Multiplayer* menu (lobby, create, join, seats, ready), WebSocket bridge in `dc_plugin.js`, chat, ping | built | | D | Client: *Multiplayer* menu (lobby, create, join, seats, ready), WebSocket bridge in `dc_plugin.js`, chat, ping | built |
| E | Alliances and co-op rules, AI masters for free and abandoned seats | partly built: co-op alliance and AI seats work; free teams in versus and sending gold are missing | | E | Alliances and co-op rules, AI masters for free and abandoned seats | built: co-op alliance, teams A-D in versus, sending gold, fallen hearts as spectators, AI seats |
| F | Co-op campaign: 20 missions with story (EN/DE) | partly built: co-op matches reuse the single player missions that fit the master areas (`coop_mission_indexes`); no own co-op missions or story yet | | F | Co-op campaign: 20 missions with story (EN/DE) | partly built: co-op matches reuse the single player missions that fit the master areas (`coop_mission_indexes`); no own co-op missions or story yet |
Still open: teams/alliances in versus, sending gold to allies, own co-op campaign missions with story; still to be | G | Editor campaigns in co-op over several missions (branches, carry, host progress), campaign names in the room list | built |
checked against the decisions above: a fallen heart only knocking out that player (who may keep watching), and how
savegames treat a running match. Still open: own co-op campaign missions with story; how savegames treat a running match.
## Masters and sides ## Masters and sides