Skip to content

feat: rematch button after a game 🤖 - #8911

Closed
reactormonk wants to merge 1 commit into
mtgred:masterfrom
reactormonk:rematch-button
Closed

reactormonk wants to merge 1 commit into
mtgred:masterfrom
reactormonk:rematch-button

Conversation

@reactormonk

@reactormonk reactormonk commented Nov 2, 2026 •

Copy link
Copy Markdown

Closes #7594.

What

A Rematch button on the end-of-game box. The icon in front shows the opponent's state:

  • ? opponent still in the game, hasn't asked
  • ✓ opponent wants a rematch (clicking accepts)
  • ✘ opponent left (button disabled)

Once both players have asked, the finished game is closed through close-lobby! as usual (stats, replay), and both players land in a fresh, unstarted lobby with:

  • the same options (format, room, title, timer, spectator settings, …), password (already-hashed value copied as-is), and tournament keys (:time-extension, :excluded?)
  • the same sides and player order, so the creator is still host and can Swap sides as normal
  • decks reloaded from the db using :original-players (started games only keep a stripped deck, and a player who rejoined mid-game, e.g. after a refresh, has none in :players). Deleted, no-longer-legal or wrong-side decks (after /swap-sides) are left empty so the player picks again; precon/chimera games skip the lookup.
  • spectators carried over (they get no button)
  • replay restoration keys not copied, so a rematch of a restored replay starts fresh

Rematches are refused while game creation is paused (:block-game-creation), with the same toast as :lobby/create. Repeat clicks are ignored, and the button is hidden in replays.

Ties now show the end-of-game box too (new game_win-tie string), and strip-state sends stats once :end-time is set instead of only when there's a :winner. So ties can be rematched as well.

Implementation notes

  • :rematch-requests is a set of sides on the old lobby, exposed via lobby-keys. Sides rather than uids, since uids are stripped from the public view. Leaving the game withdraws your request.
  • register-new-lobby! is split out of try-create-lobby so normal creation and rematch share registration, tournament scheduling and broadcasts.
  • Client: when an unstarted :lobby/state arrives while a board is loaded, the old board is cleared with leave-game!.
  • Translations: game_rematch for every locale with a populated ui.ftl; game_win-tie everywhere game_win-* exists (not ko). ca/de/es files are empty and fall back to English. Machine-quality translations, so native-speaker review welcome.

Testing

  • lein eftest: 3765 tests, 0 failures. New tests: web.game-test covers the handler (one request keeps the game open and posts once, the second opens the rematch lobby, late clicks and unfinished games are no-ops); web.lobby-test covers rematch-lobby (options/password/spectators/tournament keys copied, replay keys dropped, deck reload/rejoined player/illegal/missing/wrong side, precon) and withdrawing a request on leave.
  • npm run cljs:release: 0 warnings.
  • Manual run in docker compose with three accounts (two players plus a spectator): password-protected casual game, concede, rematch request/accept flow, decks preselected in the new lobby, rematch starts with the right decks, ✘ after the opponent leaves, spectator moved along and sees the board on start.
  • Tie end-of-game box: checked that public-states carries :reason "Tie" and stats. Not clicked through in a browser, since producing a tie needs both sides reaching their agenda points at once.

Both players click Rematch on the end-of-game box; once both have asked,
the finished game is closed (stats/replay saved as usual) and everyone,
spectators included, moves to a fresh lobby with the same options,
sides and reloaded decks.

Ties now show the end-of-game box too (with stats), so they can be
rematched as well.

Closes mtgred#7594
@NoahTheDuke

Copy link
Copy Markdown
Collaborator

Hi there! Before I begin looking at this, have you used any llm-based code generation tools? If so, would you please either include them in the commits or in the PR message? We ask that all llm contributions are signaled in some fashion to give reviewers maximum knowledge and affordance to choose their level of engagement with such technologies.

@reactormonk reactormonk mentioned this pull request Nov 2, 2026
@reactormonk

Copy link
Copy Markdown
Author

100% LLM - I know my way around functional and eslip, but not clojure specifically. Code works, see if it's according to your wishes.

@reactormonk reactormonk changed the title feat: rematch button after a game feat: rematch button after a game 🤖 Nov 2, 2026
@NoahTheDuke

Copy link
Copy Markdown
Collaborator

thanks for letting me know. i am not comfortable with merging any code that is built as such. if you wish to take the time to learn and understand the codebase, and you rely on llm-based tooling to help you with that, i see no issues (as seen by #8909). but submitting 100% generated code with little understanding is not a workflow i wish to tacitly endorse through merging nor do i wish to spend my own time learning code you did not have any desire to learn yourself.

thanks so much, and good luck on your next contribution.

@NoahTheDuke NoahTheDuke closed this Nov 2, 2026
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.

[Feature] Rematch button

2 participants