Skip to content

feat: the opt-in rematch state, the lobby's auto-rematch flag and its switch (v0.21.0) - #36

Merged
cycle-five merged 1 commit into
masterfrom
version/0.21.0
Oct 16, 2026
Merged

cycle-five merged 1 commit into
masterfrom
version/0.21.0

Conversation

@cycle-five

Copy link
Copy Markdown
Owner

Design

Rematch tuning (workspace spec docs/superpowers/specs/2026-10-15-rematch-tuning-design.md, owner-approved 2026-10-15; plan docs/superpowers/plans/2026-10-15-rematch-tuning.md, Task 1).

On 2026-10-15 in prod, 13 of the 25 cancelled games lived under 60 s. Most were rematches auto-started for a lone player who was leaving. Backend v0.48.0 will:

  • make the countdown 30 s;
  • give each lobby an auto-rematch switch (off = opt-in Play Again, D1/D2/D5);
  • never start a rematch below 2 players (D3′).

This PR is the wire contract for that. Every change is additive.

Change (v0.20.0 → v0.21.0)

  • RematchCountdownState::OptIn { ready, eligible, needed, game_type } (status: "opt_in"). Ids are strings (DisplayFromStr), like Active.player_ids.
  • LobbyChange::AutoRematchChanged { enabled, changed_by } (change_type: "auto_rematch_changed"), sent inside the existing LobbyDelta.
  • LobbySnapshot.auto_rematch: bool with #[serde(default = "default_true")], so a snapshot from an older server reads as on.
  • ClientMessage::SetAutoRematch { enabled } (type: "set_auto_rematch"), with requires_lobby() == true.

Compatibility

  • Old backend + new consumers: auto_rematch defaults to true, and OptIn is never produced.
  • New backend + old frontend: OptIn cannot reach an old client. Lobbies start with auto-rematch on, and an old client has no switch to turn it off. A stray one falls into rematch-countdown.ts's default branch (spec, "Compatibility and release").

Tests

There are serde round-trips for:

  • OptIn, with string ids and the opt_in tag;
  • AutoRematchChanged, checked against exact JSON;
  • LobbySnapshot, with auto_rematch absent (reads as on) and with it present;
  • SetAutoRematch: parse, message_type() and requires_lobby().

cargo test passes (106 unit tests plus doctests), and clippy and cargo +nightly fmt are clean.

Review: there is no automated reviewer on this repo (SDLC step 7). The task was reviewed by an independent reviewer pass against the spec's exact wire names, with no findings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01THikdM3Ru6UrrVU7DMcwBY

… switch (v0.21.0)

Co-Authored-By: Claude & Lothrop (cycle.five@proton.me)
@cycle-five
cycle-five merged commit 2fa69bf into master Oct 16, 2026
1 check passed
@cycle-five
cycle-five deleted the version/0.21.0 branch October 16, 2026 05:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant