Prérequis : Node 22 ou plus.
npm ci
npm run dev # rechargement à chaud (node --watch)
npm start # production
npm test
npm run typecheck
npm run lint
Ou avec Docker :
docker compose up -d
Déploiement sur le serveur : make deploy. Le serveur doit avoir un clone du repo. La cible passe par l'environnement ou la ligne de commande (SERVER_USER=... SERVER_HOST=... APP_INSIDER_PATH=... make deploy, BRANCH vaut master par défaut). make help liste les commandes. Le serveur porte un docker-compose.prod.yml non versionné (Traefik, domaine, PUBLIC_URL), empilé sur docker-compose.yml.
L'application répond sur le port 8080 par défaut. Les joueurs ouvrent l'adresse de la machine qui héberge le serveur sur leur téléphone (même réseau ou tunnel), tapent leur prénom et rejoignent. Le premier arrivé est l'hôte : il lance la partie, peut retirer un joueur et relancer une manche.
Variables d'environnement :
PORT: port d'écoute (8080)MIN_PLAYERS: joueurs minimum pour lancer (4, mettre 2 pour tester seul avec deux navigateurs)TRAITOR_OPTIONAL: variante "il n'y a pas de Traître" (true, mettrefalsepour la désactiver)TIMER_MS: durée du sablier en millisecondes (300000)WORDS_FILE: liste de mots, un par ligne (words/famille.csv)PUBLIC_URL: adresse affichée au salon pour rejoindre (défaut : l'adresse ouverte par le navigateur)
L'état de la partie et les identités sont en mémoire : un redémarrage du serveur renvoie tout le monde à l'écran d'accueil.
Une manche sur téléphone se déroule ainsi :
- Chacun ouvre l'adresse, tape son prénom, rejoint. Le premier arrivé est l'hôte et lance la partie quand tout le monde est là
- Chacun découvre son rôle en retournant sa carte, une barre de temps se vide en cinq secondes, puis confirme qu'il l'a vue. Le Maître du jeu est annoncé à tous, il choisit le mot ou en tire un au hasard
- Tout le monde retourne la même carte "Le mot" en même temps : le Maître et le Traître y lisent le mot, les Citoyens une phrase neutre. La carte se recache après cinq secondes pour tous, rien ne trahit qui a vraiment lu. Chacun confirme ensuite qu'il a regardé, tout le monde voit la progression
- Le Maître ou l'hôte lance le chrono de cinq minutes. Questions fermées, réponses oui, non, je ne sais pas. Si le temps s'écoule, tout le monde perd
- Pendant l'enquête, le Traître n'a plus le mot : il l'a lu une fois au rituel, son écran est identique à celui d'un Citoyen. Seul le Maître garde le mot affiché. Quand le mot est trouvé, le Maître désigne le trouveur (l'hôte seulement si le Maître est hors ligne). Discussion, puis premier vote : le trouveur est-il le Traître ? Chacun choisit puis valide son vote, modifiable jusqu'au dernier votant. Majorité stricte, la partie s'arrête si elle est atteinte
- Sinon second vote : qui est le Traître ? Le plus pointé révèle son rôle, le trouveur départage une égalité. Avec la variante, on peut pointer "Pas de Traître"
Si l'hôte se déconnecte, n'importe quel joueur peut reprendre la main, à n'importe quel moment de la partie. Seul le téléphone de l'hôte joue les sons : départ du chrono, plus que 30 secondes, temps écoulé, fin de manche. L'hôte peut couper le son depuis la barre de phase.
Règles détaillées et décisions de gameplay : docs/adr/0001-regles-du-jeu.md.
Le moteur de jeu pur vit dans src/engine/ (createGame, apply, view). src/server/ l'adapte au transport socket.io, public/js/ est le client sans framework. Un seul événement state porte tout ce qu'un joueur a le droit de voir. Le design est celui du handoff docs/design/handoff-2026-09-21/, la spec des écarts est docs/specs/2026-09-21-refonte-mobile-design.md.
- Règles implémentées :
docs/adr/0001-regles-du-jeu.md - Conception du moteur :
docs/specs/2026-09-17-moteur-de-jeu-design.md - Conception du branchement :
docs/specs/2026-09-17-branchement-design.md - Décisions d'architecture :
docs/comite-2026-09-17-architecture-cible.md - Checklist avant une partie sur téléphone :
docs/checklist-mobile.md - Audit initial :
docs/audit-2026-09-17.md
- Node 22, ESM
- Express 5 (coquille et statiques)
- Socket.io 4
- Client vanilla ESM sans bundler, CSS maison (tokens du handoff design), polices Oswald et IBM Plex Sans auto-hébergées













