Commit graph

3 commits

Author SHA1 Message Date
AyoubBenziza
a9eb6098f2 feat(blindtest): contributor-as-DJ scoring, 3-player gate, 16:9 player + seek
- 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>
2026-06-10 14:30:47 +02:00
AyoubBenziza
e3315d3b35 feat: mixed games by default, free-text quiz, mode-aware transitions
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>
2026-06-10 13:41:29 +02:00
AyoubBenziza
98e06b8206 feat(blindtest): YouTube blindtest mode with neutral DJ + synced playback
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>
2026-06-10 13:02:28 +02:00