feature/blindtest #6

Merged
ayoub merged 9 commits from feature/blindtest into dev 2026-06-10 14:25:59 +00:00
Owner
No description provided.
ayoub self-assigned this 2026-06-10 14:25:41 +00:00
ayoub added 9 commits 2026-06-10 14:25:42 +00:00
Server:
- BlindtestRound (GameRound): neutral DJ pick (never the contributor),
  per-mode scoring (title_artist fuzzy / who_added / mixed), reveal exposes
  title/artist/submittedBy; contributor doesn't score on own track
- track submission: blindtest:submitTrack validates via YouTube oEmbed
  (exists + embeddable) and captures title/artist; per-player quota; dedup
- DJ media relay: media:control (DJ only) → media:sync broadcast (engine)
- per-room shuffled track pool; submissions count in room snapshot
- shared: blindtest payloads, gameType/tracksPerPlayer in settings
- tests: DJ neutrality, scoring per mode, fuzzy match, youtube id extraction

Client:
- YouTube IFrame player (hidden behind a spinning disc — audio only, no
  title leak), DJ transport (play/pause/restart), non-DJ follows media:sync
  with latency compensation
- lobby: game-type switch (Quiz/Blindtest), blindtest config + per-player
  track submission UI
- vote forms per mode; reveal card with title/artist/who-added

Roadmap V1 step 6 (highest technical risk). Server flow verified end-to-end
over the wire (submit→start→DJ relay→vote→reveal→score).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mixed mode (default):
- gameType is now mixed | quiz | blindtest, default "mixed"; the lobby
  interleaves quiz + blindtest rounds so modes alternate
- lobby reworked: 3-way game-type switch, quiz count and/or blindtest config
  + track submission shown per selected type

Free-text quiz questions:
- quiz supports the `free` format (e.g. maths) alongside mcq/truefalse:
  payload without choices, {text} vote, tolerant matching on acceptedAnswers
- shared QuizQuestionPayload.choices optional; reveal truth carries answer
- match util moved to game/match.ts (shared by quiz + blindtest)
- repo/seed include free + acceptedAnswers; in-code bank gains free questions
- client quiz view renders a text input for free questions

Mode-aware transitions:
- RoundTransition themed per mode (colors/label/emoji); announces the mode
  on change (quiz <-> blindtest), lighter teaser within the same mode
- custom media buckets per mode: assets/transitions/{quiz,blindtest}/ + shared
- store tracks roundModeChanged

Verified e2e: mixed game alternates quiz/blindtest to completion; free-text
scoring covered by tests (22 pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- DJ is now the track's contributor (controls their own song); their identity
  is sent only to them so "who added" stays non-trivial. The contributor
  doesn't vote and is excluded from the eligible-voters count.
- Scoring: the contributor earns nothing except in who_added/mixed, where they
  get a misdirection bonus (50) per player who guesses the wrong adder.
- Blindtest (and mixed) require >= 3 connected players: lobby disables the
  options with a hint, and game:start rejects with NEED_THREE.
- Player card is now 16:9 and full width — the video banner shows at reveal;
  DJ gets a seek bar (current/duration) to jump anywhere, plus play/pause/restart.
- Mixed game order is shuffled (no predictable quiz/blindtest alternation).

Verified e2e (3 players): guard rejects at 2, DJ id hidden from others,
misdirection scoring correct. 23 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the DJ change: the DJ is again a neutral player (never the track's
contributor), broadcast to all and counted as an eligible voter (votes blind).
The contributor is a normal voter whose vote never scores on their own track;
they only earn the who_added/mixed misdirection bonus (+50 per wrong guess).

- engine: restore single round:start broadcast + DJ-included eligible voters
- blindtest-round: restore neutral pickDj; contributor may vote (ignored in
  scoring) so the round can still end on "all voted"
- client: DJ controls + everyone (DJ included) votes; reveal message simplified

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Default game type stays "mixed", but while fewer than 3 players are connected
the lobby renders the quiz config only (Quiz highlighted, Mixed/Blindtest
disabled) instead of showing blindtest settings to a lone host. It switches
back to the stored type automatically once 3 players are present — no manual
click needed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Return to lobby (replay without recreating the room):
- lobby:return (host): reset to lobby, scores to 0, keep players + tracks
- client: end screen has "Rejouer" (host) + "Quitter"; store clears transient
  game state whenever the room goes back to lobby

Contributor has nothing to input:
- round:start carries a private `mine: true` to the contributor only (via
  RoundStart.secretPlayerId targeted emit); they're excluded from eligible
  voters. Client shows a "fais-les se tromper" card instead of the vote form.

Editable track submission:
- submitTrack ack returns trackId + youtubeId; new blindtest:removeTrack
- lobby shows submitted tracks as cards (YouTube thumbnail + title) with delete

Verified e2e (3 players): add/remove, private mine flag, return-to-lobby reset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restructure onboarding (option B):
- home is just Create / Join (code) — no name field
- name is chosen in the room: room:create/join no longer require a name;
  new player:setName event. Nameless players are hidden from the snapshot
  (players/scores/submissions) and excluded from eligible voters and the
  3-player blindtest gate until they pick a pseudo.
- PseudoScreen with live DiceBear avatar preview gates RoomPage until set
- /join/:code auto-joins then redirects to the room (seamless invite links)
- RoomCode gains a "copier le lien" button (origin/join/CODE)

Verified e2e: nameless players excluded from the room until setName.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- game:end now carries the played blindtest tracks (title/artist/youtubeId/
  url/submittedByName); the end screen lists them as cards with a YouTube
  open link so players can recover/export the songs
- who_added vote no longer lets you pick yourself (filtered out)
- home page: animated halo, floating geek emojis, springy gradient title,
  hover/tap on buttons (Framer Motion) + Lucide icons
- lobby settings get Lucide icons (game type, quiz, blindtest mode, tracks,
  start)

Verified e2e: game:end includes the track list with links.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- blindtest/mixed: the host can't start until every connected player has
  submitted their track quota — client disables the button with a hint, and
  game:start rejects with TRACKS_PENDING (authoritative)
- tracks-per-player is now a number stepper (− / + buttons + free typing,
  clamped 1..10) instead of fixed 1/2/3 buttons

Verified e2e: start rejected while a player hasn't submitted, accepted once all did.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ayoub merged commit aa386f39a2 into dev 2026-06-10 14:25:59 +00:00
ayoub deleted branch feature/blindtest 2026-06-10 14:25:59 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: ayoub/nerdware#6
No description provided.