Salon de jeu prêt
Sièges, tours, coups validés par 4 gardes serveur (assis ? phase ? tour ? débit ?) puis diffusés groupés en une seule microtâche — l'arbitrage reste côté serveur.
Un salon de jeu prêt à l'emploi (coups, gardes, tick), un netcode sérieux (interpolation, prédiction, compensation de latence, lockstep déterministe), une persistance Redis/SQL — et le même langage de composants côté serveur (*.server.mjs).
Sièges, tours, coups validés par 4 gardes serveur (assis ? phase ? tour ? débit ?) puis diffusés groupés en une seule microtâche — l'arbitrage reste côté serveur.
Démo mesurée : à 200 ms de latence, le saut d'affichage moyen passe de ≈6,0 px à ≈1,5 px (÷4) et le taux de touche de 0 % à 100 % (interpolation + prédiction + rembobinage).
*.server.mjs parle le même dialecte composants que le client — un contrat typé optionnel partage view/moves entre app.game et sock.game sans dupliquer les types.
Un coup, une garde, une diffusion — game.next() passe la main au siège occupé suivant.
app.game 'morpion', seats: 2 state: (game)-> { grille: Array(9).fill(null) } moves: jouer: (game, player, p)-> throw new Error('case occupée') if game.state.grille[p.i]? game.state.grille[p.i] = player.id game.next()
Simulation locale — une simple minuterie rejoue partie.next() ici, aucun serveur réel.
Chiffres issus de la doc et du banc de la démo netcode — méthodologie complète dans docs/24-mjs-serveur.md.
Boucle à fréquence fixe (jusqu'à 60 Hz) et un diff par joueur — seuls les champs changés partent sur le fil.
Index spatial optionnel — chaque joueur ne reçoit que les entités dans son rayon de requête.
µ.predict applique l'intention en local, puis rejoue par-dessus l'état serveur après chaque mise à jour.
def.histo + partie.rembobiner valident un tir contre la position que le tireur voyait vraiment.
def.mode: 'lockstep' — le serveur ne relaie que les ordres ; µ.det garde sin/cos/atan2 reproductibles.
Adaptateurs fournis (Memory/File/Bridge/Redis/SQL), débounce intégré, chargés avant même l'écoute.
Hérité de MJS-WS — un salon (le chat d'une partie, par exemple) peut garder un journal borné pour les retardataires.
Coups appliqués immédiatement côté client (µ.predict), calés puis rejoués à la moindre correction serveur.
| Critère | MJS-Serveur | Colyseus | Meteor | Serveur maison |
|---|---|---|---|---|
| Netcode fourni | ✓ | partiel, via plugins | non (sync DDP) | à écrire |
| Déterminisme (lockstep) | ✓ | non natif | non natif | variable |
| Persistance | ✓ | via plugins | MongoDB seul | à construire |
| Contrat typé bout en bout | ✓ | schéma typé, pas les coups | non | variable |
| Intégration front réactive | ✓ | écouteurs manuels | ✓ | variable |
Chiffres indicatifs, donnés pour être honnêtes, pas promotionnels.
Une commande pour récupérer le framework.
npm install mjs-frameworkLe cœur + seulement les modules utiles :
mjs.config.json"runtime": ["socket", "schema", "smooth", "game", "interp", "predict", "det", "lockstep", "optimistic"]