[ <- RETOUR ]

┤ 04 / 06 :: BLINDTEST ├

Blindtest

Blind test musical multijoueur en temps réel : salons privés, défi du jour, collection de vinyles et Activité Discord.

blindtest.oliwr.win ->github.com/SwerkF/blindtest ->

Stack

  • React
  • Fastify
  • WebSocket
  • Prisma
  • Bun

Ce que j'ai fait

Un blind test à jouer entre amis, directement dans le navigateur ou comme Activité Discord. On choisit un pseudo et un avatar, on crée un salon (avec mot de passe si besoin) et on partage le code. Chaque manche joue un extrait de 30 secondes : il faut trouver l'artiste et le titre dans un seul champ libre, et l'année en bonus.

Trois modes : classique, animé (morceaux rapprochés d'AnimeThemes et d'AniList) et album, où la pochette floutée se dévoile peu à peu. N'importe quelle playlist Deezer peut servir. Le défi du jour propose 10 titres de 20 secondes, les mêmes pour tout le monde, avec un seul essai.

Avec un compte Discord, on gagne des boosters de vinyles (après une partie, avec le défi du jour, les succès ou un retour accepté) et on se construit une collection publique, avec amis, historique et classement.

blindtest :: architecture

┌ React ┐

Vite + nginx

WebSocket

┌ Fastify ┐

Bun

SQL

┌ SQLite ┐

Prisma

blindtest :: v0.6

3 modes de jeu

28 fichiers de tests

103 commits

>> Points techniques

  • Temps réel en WebSocket natif (@fastify/websocket) : une socket par partie, une autre par utilisateur pour la présence, les invitations et les notifications.
  • Réponses normalisées (accents, ponctuation, parenthèses) puis comparées par distance de Levenshtein, avec une tolérance réglable.
  • Anti-triche : pendant une manche, le client ne reçoit que l’extrait audio, jamais le titre ni l’artiste. Tirages de boosters côté serveur avec node:crypto.
  • Défi du jour déterministe : les titres sont classés par un hash du jour, la même sélection pour tous sans rien stocker, et une contrainte d’unicité en base limite à un essai.
  • Ouverture de booster en deux temps : tirage hors transaction, puis réclamation par une mise à jour conditionnelle, pour éviter le double paiement sur un catalogue d’environ un million de titres.
  • Chronos alignés sur l’heure du serveur, envoyée par WebSocket, pour corriger les horloges clients décalées.