Un jeu de mots fléchés multijoueur dans le navigateur ! Chaque partie est hébergée par le navigateur de son créateur. Le site peut être publié sur GitHub Pages, sans serveur Node.js en production.
Fini les parties à 4 autour d'un bureau à dicter vos mots à votre collègue. Vous trouvez tout les mots ? Vous êtes le meilleur ? Prouvez le !
- Limite de joueurs augmentée à 9 !
- Utilise les grilles 20 minutes (https://github.com/tcoupin/mots)
- Permet de rejoindre en cours de partie (https://github.com/Drestin/mots)
- Parties indépendantes avec liens d'invitation et connexions WebRTC
- Hébergement statique sur GitHub Pages
- Gestion des grilles à thème
- Fixes permettant de récupérer plus de grilles issues de 20 minutes.
- Support mobile et tablette
- Détection automatique d'un mot en ligne ou colonne
Node.js 22 ou supérieur est nécessaire uniquement pour les outils de développement et de compilation :
npm ci
npm startLe site local est accessible sur http://localhost:8080. Pour choisir un autre port, lancez npm run build puis npx http-server dist -p 8082 -c-1.
- Créez une partie, choisissez un pseudo et un personnage, puis cliquez sur « Jouer ! ».
- Copiez le lien d'invitation et partagez-le avec vos amis (9 joueurs maximum).
- Lancez la grille avec le bouton de démarrage ou
!startdans le chat. - L'hôte garde son onglet ouvert pendant toute la partie. Les joueurs peuvent rejoindre une partie déjà commencée.
Les invités qui rechargent leur onglet retrouvent leur joueur et leurs points s'ils reviennent dans les 30 secondes. Une interruption de connexion déclenche des tentatives de reconnexion pendant 20 secondes. Fermer ou recharger l'onglet de l'hôte termine la partie : il n'y a ni migration automatique de l'hôte, ni sauvegarde permanente. Les navigateurs mobiles peuvent suspendre un onglet en arrière-plan.
Chaque nouvelle partie charge une grille choisie au hasard dans le catalogue local. Les invités reçoivent la grille choisie par l'hôte, sans en tirer une autre. Si le catalogue est vide, une petite grille originale sert de repli. L'hôte peut toujours importer un fichier .mfj ou .json avec le sélecteur « Grille ». Le bouton « Grille de depart » restaure la grille originale.
Pour télécharger ou actualiser toutes les grilles disponibles :
npm run fetch:grids
npm run buildLe script utilise le catalogue officiel configuré dans GRID_PROVIDER dans conf.json, télécharge les fichiers dans public/grids et génère public/grids/index.json. Il valide les grilles avant de les publier dans le catalogue, effectue trois téléchargements simultanés et réutilise les fichiers déjà valides. Il peut donc être relancé après une interruption. Les entrées du fournisseur répondant HTTP 404 sont signalées comme indisponibles et ne figurent pas dans le catalogue local. Les autres échecs sont signalés avec un code de sortie non nul ; les grilles réussies restent utilisables.
Dans un environnement avec proxy HTTP, Node.js 24 permet d'utiliser NODE_USE_ENV_PROXY=1 npm run fetch:grids. Le téléchargement est un outil de préparation du site : aucun serveur Node.js n'est nécessaire pendant une partie.
Les fichiers locaux et leur catalogue sont copiés dans dist/ à la compilation. Ajoutez les changements de public/grids/ au dépôt avant de publier sur GitHub Pages. Le build ne contacte pas le fournisseur et ne télécharge rien automatiquement. Vérifiez les droits du fournisseur avant de redistribuer ses grilles. Les réponses sont présentes dans les assets publics du site, conformément au modèle de confiance des parties entre amis.
Les fichiers importés doivent contenir les données du format historique : nbcaseshauteur, nbcaseslargeur, grille, definitions, et éventuellement force, legende, spountzH, spountzV. Exemple minimal :
{
"nbcaseshauteur": 2,
"nbcaseslargeur": 3,
"grille": ["zzz", "aAB"],
"definitions": [["Deux lettres"]],
"force": 1
}Les fichiers .mfj peuvent aussi utiliser une unique affectation var gamedata = { ... }; contenant uniquement des valeurs littérales. Aucun JavaScript importé n'est exécuté. Les formats utilisant des fonctions ou plusieurs instructions nécessitent une conversion préalable. Taille maximale : 1 Mo, dimensions maximales : 50 x 50.
La commande !grid JJMMAA charge le fichier correspondant depuis le site lui-même. Sans numéro, !grid choisit une autre grille locale au hasard. Aucune requête de grille n'est envoyée au fournisseur depuis le navigateur : les restrictions CORS ne s'appliquent plus. Une grille absente ou invalide ne remplace pas la partie en cours.
- Dans les paramètres du dépôt, ouvrez Pages, puis choisissez GitHub Actions comme source.
- Poussez les modifications sur
masteroumain, ou déclenchez manuellement le workflow « Deploy GitHub Pages ». - Le workflow installe les dépendances, exécute les tests, compile le site et publie uniquement
dist/.
Les chemins d'assets et les liens d'invitation fonctionnent aussi sous un préfixe de dépôt, par exemple https://username.github.io/mots/. Les identifiants de partie sont dans le fragment #room=... et ne nécessitent aucune réécriture de routes. Le fichier conf.json est utilisé uniquement par le script de téléchargement, pas par le navigateur. Les fichiers historiques du serveur sont conservés comme référence ; leurs dépendances ne font plus partie de l'installation.
Le site est statique, mais la connexion entre navigateurs utilise encore des services externes :
- Signalisation : le service public PeerJS par défaut permet aux navigateurs de se trouver. Sa disponibilité et ses quotas ne sont pas garantis par ce projet.
- STUN : la configuration initiale utilise
stun:stun.l.google.com:19302pour établir des connexions directes. - TURN : aucun relais n'est préconfiguré. Certains réseaux d'entreprise, VPN et réseaux mobiles ne pourront pas se connecter sans relais TURN. GitHub Pages ne fournit pas ce service.
Configurez PeerJS et les serveurs ICE dans public/peer-config.js, puis recompilez le site. Une signalisation personnalisée peut être définie avec les options PeerJS host, port, path et secure. En production HTTPS, utilisez un service de signalisation sécurisé.
window.MOTS_PEER_OPTIONS peut être un objet ou une fonction asynchrone retournant les options PeerJS. Une fonction permet de demander des identifiants TURN temporaires via un mécanisme fournisseur prévu pour le navigateur. La configuration ICE correspondante ressemble à ceci :
{
config: {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'turn:relay.example.org:3478', username: temporaryUsername, credential: temporaryCredential }
]
}
}Ne placez jamais de clé d'administration ou de secret TURN permanent dans le dépôt, la configuration publique ou les assets compilés. Les identifiants temporaires utilisés par WebRTC restent visibles aux participants. Si votre fournisseur impose un endpoint pour émettre ces identifiants, cet endpoint est une dépendance externe supplémentaire : GitHub Pages ne peut pas le fournir. Pour vérifier un relais configuré, utilisez temporairement config.iceTransportPolicy: 'relay' et testez des joueurs sur des réseaux différents.
Le lien donne accès à la partie : partagez-le uniquement avec les joueurs souhaités. L'hôte détient les réponses et décide des scores. Ce modèle est destiné aux parties entre amis, pas aux compétitions avec protection contre la triche.
npm test
npm run build
npx playwright install chromium
npm run test:browserLes tests couvrent les règles, l'isolation des parties, les doublons, les imports sans exécution de code et de vraies connexions WebRTC locales entre navigateurs Chromium. Le serveur de signalisation Node.js utilisé par les tests est uniquement un outil de développement ; il n'est pas déployé sur Pages. Les tests locaux ne prouvent pas la connectivité entre deux réseaux Internet ni le fonctionnement d'un relais TURN : ces vérifications restent à faire avec votre service configuré.
Les images des "petits monstres" utilisées dans le projet ont été réalisées par le talentueux Buatoom
Toute contribution au projet est la bienvenue ! N'hésitez pas à remonter tout bug ou suggestions via Github

