Skip to content

Games stage 4: connect the artists, theme rounds, bracket battles - #62

Merged
madeofpendletonwool merged 2 commits into
mainfrom
mad-783-games-stage-4
Oct 9, 2026
Merged

madeofpendletonwool merged 2 commits into
mainfrom
mad-783-games-stage-4

Conversation

@madeofpendletonwool

Copy link
Copy Markdown
Owner

Stage 4 of Phase 10 (MAD-783), the last one: queue games. These are Game night games played through the queue, across songs, while the rounds keep going. ADR 0015 has a new "Stage 4" section.

How queue games work

  • They run beside the rounds. They don't take the round slot. A room runs one connect or theme game at a time, plus one bracket (game_running, 409, otherwise).
  • API: they're sent as game.queue and driven under /rooms/{id}/games/queue: start, enter, withdraw, hint, close. Starting one needs the Start rounds permission.
  • Holding songs: migration 00027 adds queue_items.game_held and front_at.
    • Theme and bracket entries are held out of the play order until the game plays them.
    • Then they go to the front, after songs put back and before the fair order.
    • queue.Service.Hold and PlayNext do this under the room's queue lock.
    • Games live in memory, so the server releases every held song when it starts.
  • Entering: you enter one of your waiting songs, or the first song you queue after a game opens is entered for you. That way the normal search-and-add flow works with no picker.
  • Scoring: each game's points are kept as a round of its kind, so they count toward the night's scores and Trivia Champ.

MAD-794 Connect the artists

  • Picking the pair: two artists the room knows (tonight's songs, then its favourites) that are 3 to 5 links apart in the cached music graph.
    • The engine explores out to 3 hops and up to 800 artists, counting similarity either way round.
    • If that finds nothing, it asks the sources about a few of the room's artists and tries again.
    • If there's still no pair, it says so plainly instead of guessing.
  • Links: every queued song is checked against its team's chain. It links if its artist is similar to the chain's last artist. Songs that don't link show up as misses, with the reason. The chain plays in normal fair order, so the chain is the playlist.
  • Hints: a hint names an artist on a shortest path from where the chain is now.
  • Scoring:
    • A link scores 200, or 100 once the chain has had a hint.
    • A chain that gets there gives everyone who linked it 300 more.
    • With 2 teams (you join the smaller one on your first song), the shortest finished chain wins another 300.
  • The shortest path is only shown at the end.

MAD-795 Theme rounds

  • Prompts come from data the server can check (new pure quiz.Theme):
    • era: before 1985, the 90s, or a single year
    • liner notes: a cover, a song that samples something, a live recording, a producer credited tonight
    • beat map: over 140 BPM, slow (95 BPM or under), a big quiet-to-loud build
    • tags: a sad song, or a genre from tonight's artists
  • Checking entries: each entry is checked when it's entered and comes back yes, no with a note ("Not a cover, as far as we know"), or unknown. Without liner notes, "no cover" counts as unknown, not no. Every entry still plays.
  • Playing: when entries close, the block goes to the front in entry order. Once every entry has played, hearts decide: the most-hearted wins, and ties share the win.
  • Scoring: an entry that fits scores 200, an unknown 100, and the winner 500 more.

MAD-796 Bracket battles

  • Entries: 4, 8 or 16 songs, two per person, with an optional theme.
  • The draw: games.Draw shuffles entries into the smallest power of two that fits, with byes for the leftover slots.
  • Matches:
    • Each match puts both songs at the front, back to back, and hearts decide; a tie goes to a coin toss.
    • Matches are spaced an hour over the room's breaks per hour, with at least one normal song between them.
    • A winner's song is queued again for its next match with queue.Service.Again, since a queue item only plays once.
    • A song taken out of the queue loses by walkover.
  • Short versions: each song starts at its loudest section and is cut after 90 s, via the new playback.Engine.Seek and Cut. A cut song ends as finished, not skipped.
  • Scoring: a match win scores 300, and the final another 700.
  • The night's bracket:
    • It's kept on the night (nights.bracket) and shown in the recap.
    • The champion gets a Bracket Champion award.
    • The champion is a candidate for song of the night: it takes a tie for the most hearts, but never beats a song with more hearts.

Web

  • Phones: a card per queue game over now playing (it hides while a round is up). It shows:

    • connect: your chain, hints and misses
    • theme: the prompt, your entry and whether it fits
    • bracket: entries, the current match and how your songs are doing

    You can enter one of your waiting songs from the card, or jump to search.

  • Big screen:

    • connect: the chain grows link by link, labelled with how close each step is
    • theme: the entries with their fit marks, then the hearts and a crown
    • bracket: the bracket between matches, with the winner animated on, and a "vs" bar while a match plays
  • Starting games: a "Queue games…" dialog in the room menu, with options for teams, theme, bracket size and short versions.

  • Lanes and recaps: songs a game holds are marked "In a game" in lanes, and the recap shows the bracket.

Also

  • Adding a waiting enum value made oapi-codegen prefix the display-pairing status constants (DisplayPairingStatusStatusWaiting/Paired). I updated the two uses.

Not done here

  • A restart drops queue games in progress, including a bracket that spans the night. Matches already played are kept, so the recap still has the bracket as it stood.
  • I haven't clicked through the new screens in a browser; I've only run the checks below.

Testing

  • go test -race ./... passes and golangci-lint reports 0 issues. New tests cover:
    • connect, solo and with teams, with links, misses, hints and scoring
    • theme rounds (holds, the block order, fits, hearts) and auto-entry
    • the bracket draw with byes, a full bracket with short versions and a re-queued winner, and walkovers
    • theme fit checks
    • the song-of-the-night tie-break
  • Web: pnpm typecheck, pnpm lint, pnpm test (210 tests, including new ones for lib/queue-games) and pnpm build pass.

🤖 Generated with Claude Code

madeofpendletonwool and others added 2 commits October 8, 2026 21:35
Queue games run through the queue, across songs, beside the rounds: one
connect or theme game and one bracket per room, sent as game.queue and
driven under /rooms/{id}/games/queue.

- Theme and bracket entries are held out of the play order
  (queue_items.game_held) and put at the front (front_at) when the game
  plays them; queue.Service does it under the room's queue lock.
- Connect the artists picks two of the room's artists 3-5 links apart in
  the cached music graph, checks each queued song as a link, gives hints
  and races two teams.
- Theme prompts and their checks are pure (quiz.Theme): era, liner notes,
  beat map and tags, with unknowns let through.
- Brackets draw with byes, play matches back to back spaced by the
  room's breaks per hour, queue winners again, cut short versions at the
  peak, and keep the night's bracket for the recap. The champion takes a
  song-of-the-night tie and a Bracket Champion award.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A card for each queue game over now playing: the chain and a hint for
  connect the artists, the prompt, your entry and its fit for a theme
  round, and entries, the match up now and your standing in a bracket.
  Enter one of your waiting songs, or the next one you queue counts.
- The big screen grows the chain link by link with how close each step
  is, shows a theme's entries with their fit marks and hearts, and draws
  the bracket between matches, with the winner moving on.
- A Queue games dialog from the room menu starts them: teams, theme,
  bracket size and short versions.
- Songs a game holds are marked in lanes; the recap shows the night's
  bracket and the Bracket Champion award.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@madeofpendletonwool
madeofpendletonwool merged commit 95e15cd into main Oct 9, 2026
5 checks passed
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