Casino MINUIT
Casino entre amis, jetons fictifs : quinze jeux multijoueurs en temps réel, six en 3D, jouables par un simple lien.
En bref
- Problème
- Jouer à un casino entre amis à distance, par un simple lien, sans serveur à louer ni application à installer, sur un PC ordinaire, même sans droits administrateur ni carte graphique correcte.
- Ce que j’ai réalisé
- Quinze jeux, dont six en 3D, servis par un serveur Node.js sans dépendance npm : WebSocket écrit selon la RFC 6455, SQLite, hasard tiré côté serveur et vérifiable, lanceur Windows en double-clic et lien fixe Cloudflare.
- Résultat
- 1 155 commits1 155 commits en quinze jours actifs, 216 fichiers de tests dont 39 scénarios de bout en bout en réseau, roulette 3D passée de 17,5 à 59,7 images par seconde sans carte graphique.
- Rôle
- Conception, architecture, orchestration de la réalisation et vérification, seul.
- Équipe
- Projet individuel
- Statut
- Terminé
- Liens
- Démo
Le casino, écran par écran
Captures d’un serveur de démonstration local : 14 joueurs inventés, jetons fictifs, aucun argent réel. L’écran TV est montré avec son adresse locale masquée. Les écrans de l’Armurerie sont des visuels de démonstration : noms et rendus d’armes façon CS2, propriété de leur éditeur.
L’entrée et le hall
, ouvrir la capture complèteLa porte d’entrée L’écran d’entrée, portes art déco : code de la salle, nom de joueur, avatar, couleur, mot de passe facultatif ; en pied, « jetons fictifs, aucun argent réel ».
, ouvrir la capture complèteLe hall, vu par une joueuse Deux des quatre familles de jeux en cartes (Les Tables, Les Originaux), qui est dans la salle et à quelle table, et le classement en direct de la soirée.
Profil et vie de salle
, ouvrir la capture complèteLe profil d’une joueuse Patrimoine, courbe du solde de la soirée (qui finit en flèche sur un coup à +11 875 jetons aux Mines), résultats par jeu et succès débloqués.
, ouvrir la capture complèteLe Tableau d’honneur Les sept records de la salle en chiffres à volets (plus gros coup, plus gros multiplicateur, plus longue série…), puis les records jeu par jeu.
, ouvrir la capture complèteLa Roue du destin L’hôte lance la Roue du destin (« Qui a le gage ? ») : elle tourne en plein écran chez tous, avec l’avatar de chaque joueur en ligne.
, ouvrir la capture complèteLe podium de fin de soirée La remise des prix, jouée au même instant chez tous les joueurs : podium doré sous les rideaux, classement complet et titres de la soirée (le Banquier, le Pigeon du tournoi, le Flambeur…).
Hôte et écran TV
, ouvrir la capture complèteLe registre public des gestes de l’hôte « Ce que l’hôte a fait ce soir » : chaque réglage, bot assis ou défi lancé par l’hôte s’inscrit dans un registre lisible par tous les joueurs.
, ouvrir la capture complèteL’écran TV, scène « Les gros coups » La page spectatrice pour vidéoprojecteur : horloge en direct, tableau d’honneur et carrousel des gros coups de la soirée. Adresse masquée sur la capture ; le code à quatre chiffres est celui de la démonstration ; le bloc « Dernier drop » reprend un visuel de démonstration de l’Armurerie.
Au téléphone
, ouvrir la capture complèteLe hall au téléphone Compte à rebours du tournoi, solde, réglette sociale et cartes de jeux empilées : le hall tient sur un écran de téléphone.
, ouvrir la capture complèteMines, joué au doigt Trois diamants trouvés, le multiplicateur grimpe à ×1,47 et le bouton propose d’encaisser 14,70 jetons.
, ouvrir la capture complètePlinko en 3D, au téléphone La même planche en 3D tient dans la paume : planche en haut, commandes au pouce en dessous, une bille vient de tomber dans la case ×6,70 pendant que d’autres rebondissent.
Les tables
, ouvrir la capture complèteBlackjack en 3D, la donne est faite Table Émeraude en 3D : quatre mains distribuées, chacune avec son total devant sa place, le croupier reste sur 17.
, ouvrir la capture complèteRoulette européenne en 3D, la table complète Le cylindre, le tapis avec la piste des annonces (voisins du zéro, orphelins, tiers), les statistiques des derniers tirages et les joueurs à la table.
, ouvrir la capture complèteRoulette en 3D, la bille se pose sur le 20 Gros plan du cylindre en 3D : la bille se pose sur le 20 noir, la table annonce les gagnants du tour et leurs gains.
, ouvrir la capture complèteLa Machine de Minuit, ligne gagnante Quatre trèfles alignés sur la ligne 2 : la ligne s’illumine et le gain s’affiche, sous le jackpot commun qui grossit à chaque mise du casino.
Les originaux
, ouvrir la capture complèteLa Fusée, encaissements en parachute Le multiplicateur grimpe à ×1,98 ; deux joueurs sont déjà descendus en parachute, un troisième vient d’encaisser à ×1,91 ; en bas à gauche, l’encart « Équité vérifiable » affiche l’empreinte SHA-256 de la graine.
, ouvrir la capture complètePlus ou Moins, trois bonnes réponses d’affilée Un Valet de pique au centre, et pour chaque choix la probabilité exacte et le multiplicateur qui en découle : ×2,81 après trois bonnes réponses, 140,98 jetons à encaisser.
, ouvrir la capture complèteL’Armurerie, l’upgrader Mode Upgrade de l’Atelier : une arme est misée à 62,59 % de chances contre une cible à ×1,50 ; l’aiguille s’arrête dans l’arc doré, la cible est gagnée et le tirage (190 890 sur 1 000 000) reste vérifiable. Visuels de démonstration : noms et rendus d’armes façon CS2, propriété de leur éditeur.
, ouvrir la capture complèteL’Armurerie, l’étal des caisses L’Armurerie s’ouvre sur son étal : les derniers drops de la salle, les quêtes du soir et le niveau du joueur, puis les caisses avec leur prix en jetons et les cotes par rareté. Visuels de démonstration : noms et rendus de caisses et d’armes façon CS2, propriété de leur éditeur.
Entre potes
, ouvrir la capture complètePile ou Face en duel, la pièce tournoie Défi relevé entre deux joueurs pour un pot de 400 : la pièce d’or tournoie en 3D au-dessus de la table, « Rien ne va plus… ».
, ouvrir la capture complèteLa Grande Roue en 3D, faites vos jeux 54 cases et six mises, de 1 contre 1 à 42 contre 1, avec le retour affiché pour chacune ; quatre joueurs ont posé leurs jetons, la roue part dans 15 secondes.
, ouvrir la capture complètePoker Hold’em, l’abattage Fin de main : une quinte au Valet rafle le pot contre une paire de 8 ; deux bots de l’hôte, étiquetés « BOT », se sont couchés.
, ouvrir la capture complèteLe Derby de Minuit, photo-finish Arrivée au ralenti en sépia : Tartiflette Turbo l’emporte d’une courte tête devant Mamie Nitro, sous les yeux de toute la salle, au même instant sur chaque écran.
Les jeux de Minuit
, ouvrir la capture complèteMenteur !, c’était vrai Un joueur crie « Menteur ! » sur trois As ; on compte sous les gobelets : il y en avait bien trois, c’est lui qui perd un dé.
, ouvrir la capture complèteLes Douze Coups, le gong a sonné « MINUIT ! » : le gong vient de sonner à un instant tiré par le serveur, et le temps de réaction du joueur s’affiche, 548 ms, mesuré côté serveur.
, ouvrir la capture complèteLe Coffre, la révélation Enchère scellée : chaque joueur n’a vu qu’un dé ; les trois dés se retournent et le coffre s’ouvre sur sa vraie valeur, 900 jetons.
Sommaire10 sections
Contexte
Projet personnel mené seul, de fin septembre à octobre 2026 : un casino entre amis, jouable à distance par un simple lien. L’hôte lance le casino sur son PC Windows ; une fenêtre affiche un lien et un PIN à partager. Les amis ouvrent le lien dans Chrome, Edge ou Firefox, sans rien installer, et se retrouvent dans la même salle. La contrainte était de tourner sur un PC ordinaire, même sans droits administrateur ni carte graphique correcte, et de rester fluide.
Les jetons sont fictifs : rien ne s’achète, rien ne se retire, aucun objet réel n’est gagné. Les captures de cette fiche viennent d’un serveur de démonstration local, avec des joueurs inventés et des soldes fictifs. Le dépôt compte 1 155 commits du 3 au 19 octobre 2026, soit quinze jours actifs ; les premiers travaux datent de fin septembre.
Ce qu’on y joue
Le hall range quinze jeux en quatre familles. Les Tables : Blackjack (une à cinq places, bots et paris annexes), Roulette (européenne, française ou américaine) et La Machine de Minuit (cinq rouleaux et un jackpot commun à toute la salle). Les Originaux : La Fusée (jeu de crash), Mines, Plinko, Plus ou Moins et L’Armurerie, une ouverture de caisses façon Counter-Strike dont les visuels d’armes sont montrés ici à titre de démonstration. Entre potes : Poker Texas Hold’em No-Limit, Le Derby de Minuit (course de six chevaux), La Grande Roue et Pile ou Face en duel. Les Jeux de Minuit : Menteur ! (dés menteurs façon Perudo), Les Douze Coups (réflexe au gong) et Le Coffre (enchère scellée). Six jeux ont une vue 3D en plus de la 2D : Blackjack, Roulette, La Fusée, Plinko, Pile ou Face et La Grande Roue. La plupart se jouent aussi en solo hors ligne ; Poker, Menteur !, Les Douze Coups et Le Coffre demandent la salle en réseau.
Un compte a un pseudo, un avatar, une couleur, un mot de passe facultatif haché en scrypt, un code de reprise et une liste « Mes appareils ». Le portefeuille est tenu par le serveur, avec « se refaire » et les dons. Le profil montre les statistiques, la courbe du solde et les saisons ; s’y ajoutent les succès, le cabinet des trophées, les records en panneau à volets, les défis flash, le chat, huit réactions et le tiroir « Potes ». La fin de soirée enchaîne tournoi, podium joué au même instant chez tous, titres, gage et récapitulatif. L’hôte dispose d’une Roue du destin, d’un rassemblement, d’une page d’hôte (lien, PIN, réglages, bots, journal) et d’un écran TV pour vidéoprojecteur, avec QR code. Le rendu se choisit entre Auto, 3D et 2D, avec un mode animations réduites, des raccourcis clavier et une mise en page qui descend jusqu’au téléphone.
Architecture
Le casino tourne désormais sur un VPS, derrière un reverse proxy nginx en HTTPS ; la version à tunnel reste décrite ci-dessous.
Les navigateurs des joueurs passent par un lien fixe : un Worker Cloudflare redirige vers le tunnel du moment, ou affiche « Le casino est fermé pour l’instant » ; son secret est comparé en temps constant. Le tunnel mène au serveur Node.js (version 22.13 ou plus), qui tourne sur le PC de l’hôte sans aucune dépendance npm. Il sert les fichiers statiques en liste blanche, avec une CSP stricte et l’en-tête X-Frame-Options ; son WebSocket est écrit à la main selon la RFC 6455. Les jeux sont des modules chargés à chaud : un module qui plante ne fait pas tomber le serveur. Les données vivent dans SQLite, par node:sqlite, avec des transactions de tour et des sauvegardes atomiques. Un journal JSONL enregistre les événements, et un analyseur recalcule chaque paiement.
Le client est en JavaScript sans framework ni étape de build. La 2D est en DOM et Canvas ; la 3D repose sur Three.js r160, chargée seulement à l’entrée d’une table 3D, avec des textures procédurales et un seul contexte WebGL. Three.js et un générateur de QR code sont les seules bibliothèques tierces. Le texte venu du réseau est inséré en nœuds texte, sans innerHTML. Les sons sont synthétisés et la voix du croupier vient de la synthèse vocale.
Côté sécurité : PIN de salle verrouillé par source après des essais ratés, clé d’hôte séparée, détection locale de l’hôte, validation stricte des entrées, mots de passe hachés en scrypt, jetons de session conservés en empreintes et révocation appareil par appareil.
Un hasard tiré par le serveur, et vérifiable
Tous les tirages se font côté serveur, avec crypto.randomFillSync, crypto.randomInt et un mélange de Fisher-Yates ; des tests vérifient qu’aucun module de jeu n’appelle Math.random. Pour La Fusée, l’empreinte SHA-256 de la graine est publiée avant le vol et la graine est révélée après : c’est l’encart « Équité vérifiable », en bas à gauche de l’écran de jeu.
Le serveur est autoritaire : le navigateur n’envoie que des intentions. Les cartes cachées, les cartes privées, les mines et le point d’explosion ne sont jamais envoyés avant l’heure, et des tests inspectent chaque message pour le vérifier. Dans la salle, chaque geste de l’hôte sur un jeu (réglage, bot assis, défi lancé) s’inscrit dans un registre que tous les joueurs peuvent lire.
La même bille sur tous les écrans
Les animations sont cadencées sur l’horloge du serveur. À la roulette, le serveur tire d’abord le numéro ; une physique déterministe, partagée par le serveur et les clients, cherche ensuite une trajectoire de bille qui aboutit à ce numéro et la code en trace. La vue 2D et la vue 3D rejouent la même trace : la bille tombe dans la même case, au même instant, sur chaque écran. Le même principe sert à la Roue du destin, au Derby et aux batailles de caisses.
L’argent fictif compté comme du vrai
Les montants sont des centimes entiers. Les tests vérifient un invariant de conservation des jetons. Les positions ouvertes au moment d’un redémarrage sont remboursées. L’analyseur du journal rejoue chaque paiement avec la version archivée du moteur de jeu. Le portefeuille est tenu par le serveur : le profil affiche le patrimoine, la courbe du solde de la soirée, les résultats jeu par jeu et les succès ; le Tableau d’honneur garde les records de la salle, annoncés une fois le coup montré.
Fluide sans carte graphique, lanceur qui marche partout
Un gouverneur de qualité adapte le rendu 3D à la machine. En 1920 × 1080 sans accélération matérielle, la roulette 3D est passée de 17,5 à 59,7 images par seconde, et La Fusée de 32 à 53–58. La 3D tient aussi sur un téléphone, les commandes au pouce sous la planche.
Le lanceur Windows se lance en double-clic : il trouve Node, même en version portable. Un bug a été résolu sur ce lanceur : sous Windows, sélectionner du texte dans la console figeait le programme. L’affichage a été déplacé dans un processus séparé, et une sentinelle surveille le fil principal.
Tests et mesures
216 fichiers de tests automatisés, dont 39 scénarios de bout en bout en réseau. Plus d’une centaine de scénarios navigateur tournent dans Chrome headless, pilotés par le protocole DevTools, de 1 à 20 joueurs et jusqu’au format téléphone. Le lanceur est testé en conditions réelles. Le harnais de test est écrit maison.
Chiffres clés, comptés sur les fichiers suivis par git, hors Three.js, générateur de QR code et deux fichiers de données générés :
- Code applicatif JavaScript : ≈ 86 200 lignes (serveur ≈ 28 800, socle client ≈ 23 800, jeux ≈ 33 600) ; modules serveur de jeux et de fonctionnalités : 21 ; CSS : ≈ 14 100 lignes.
- Code de test : ≈ 125 000 lignes, plus que le code applicatif.
- Documentation Markdown : 374 fichiers, ≈ 60 000 lignes.
- Dépendances npm du serveur : 0.
Ce que je referais autrement
Cinq défauts d’affichage sont connus et n’étaient pas corrigés au 30 octobre 2026, date des captures :
- Au téléphone (390 px de large), le podium de fin de soirée chevauche son titre.
- Au téléphone, le patrimoine de « Mon profil » est coupé.
- Au téléphone, les compteurs de la vitrine à trophées débordent.
- L’historique du Derby est reçu par le client, mais jamais affiché.
- La « Carte de la soirée » n’affiche rien.
Aucune capture du podium ni du profil au téléphone ne figure donc dans la visite. L’Armurerie reprend des noms et des rendus d’armes façon CS2, propriété de leur éditeur : ses captures sont montrées en visuels de démonstration.
Compétences BUT mobilisées
| Compétence | Niveau | Ce que le projet montre, et preuve |
|---|---|---|
| RéaliserRéaliser un développement d’application | Niveau 3 | Développer de bout en bout une application client-serveur en temps réel.Preuve : Serveur Node.js sans dépendance npm (HTTP, WebSocket RFC 6455, SQLite) et client JavaScript sans framework : quinze jeux, dont six en 3D avec Three.js. |
| OptimiserOptimiser des applications | Niveau 2 | Mesurer et améliorer les performances d’un rendu.Preuve : Gouverneur de qualité adaptative : roulette 3D de 17,5 à 59,7 images par seconde et La Fusée de 32 à 53–58, en 1920 × 1080 sans accélération matérielle. |
| AdministrerFaire évoluer et maintenir un système informatique communicant en conditions opérationnelles | Niveau 3 | Déployer et sécuriser un service joignable depuis l’extérieur.Preuve : Lanceur Windows qui trouve Node ; Worker « lien fixe » ; PIN de salle verrouillé par source, clé d’hôte séparée, mots de passe en scrypt, révocation par appareil. |
| GérerGérer des données de l’information | Niveau 2 | Concevoir et exploiter la persistance et le journal d’une application.Preuve : SQLite par node:sqlite avec transactions de tour et sauvegardes atomiques ; journal JSONL rejoué par un analyseur qui recalcule chaque paiement ; centimes entiers sous invariant de conservation. |
| ConduireConduire un projet | Niveau 2 | Mener seul un projet, de la conception à la livraison.Preuve : 1 155 commits du 3 au 19 octobre 2026, 374 fichiers de documentation Markdown, 216 fichiers de tests. |











