Contexte
S — Je voulais prouver que je pouvais livrer des surfaces collaboratives temps réel sans moteur de jeu. L’exercice : un blitz Connect-6 avec timers, multi-coups et anti-triche natif. T — Architecturer un serveur autoritaire, un client déterministe et un harnais de tests chaos qui résistent à la perte de paquets et aux rage quit.
Menaces
- Conditions de course quand les deux joueurs émettent simultanément.
- Fuites mémoire si les sockets orphelins persistent après abandon.
- Tentatives de triche via payloads altérés ou scripts de replay.
- Détection de victoire sur grille 15×15 potentiellement coûteuse CPU.
Approche
- Modélisé chaque événement (création, join, coup, timer, abandon) en contrats TypeScript partagés client/serveur.
- Intégré un moteur de règles autoritaire qui valide ordre des coups, compte et budget temps avant diffusion.
- Utilisé des rooms Socket.IO par match avec Redis pub/sub pour préparer le scale horizontal.
- Ajouté heartbeat + reconnexion exponentielle pour recycler les parties fantômes et garder des métriques fiables.
- Optimisé la détection de victoire via vecteurs mémoïsés ; worst-case <5 ms sur 225 cases.
- Instrumenté des logs structurés et dashboards Grafana pour rejouer les matchs et détecter les anomalies.
- Déployé frontend/backend séparés (Vercel + Render) afin de découpler les plans de scale.
Résultats
Le prototype tient des allers-retours <100 ms même sur mobile, encaisse la perte de paquets sans désync et aucun cheat n’a contourné la validation serveur. Le code sert maintenant de référence lors de mes audits de concurrence.
Retours d’expérience
Une UX temps réel échoue dès que la propriété de l’état est floue. En donnant la parole finale au serveur et en traitant les sockets comme des narrateurs peu fiables, j’ai gagné une empathie pour les systèmes distribués utile aux SaaS collaboratifs.
