# Étude serveur multijoueur temps réel ## Statut Étude non normative pour `0.2.0-0-pre.2.fix.1`. Ce document complète l'inventaire initial. Il ne choisit pas encore une stack serveur, un crate WebSocket ou une fréquence de tick unique. ## Objectif Séparer clairement : - transport réseau ; - protocole de session ; - synchronisation d'état ; - simulation authoritative ; - services Web persistants. Un WebSocket fournit un canal bidirectionnel ; il ne résout pas à lui seul la synchronisation multijoueur. ## Plan de contrôle et plan de données ### Control plane Responsabilités plausibles : - authentification ; - matchmaking ; - création/allocation de partie ; - roster ; - invitation/join/leave ; - ready/start/end ; - sélection d'une instance realtime ; - reprise de session. Ces opérations peuvent passer par HTTP(S), WebSocket ou une combinaison, sans être exécutées dans la boucle de simulation. ### Realtime data plane Responsabilités plausibles : - accepter les connexions de joueurs ; - associer connexion, joueur et session ; - recevoir les inputs/commands ; - sequencer les messages ; - maintenir le tick/cycle de simulation ; - faire évoluer l'état authoritative ; - diffuser snapshots et deltas ; - détecter pertes/timeouts ; - gérer reconnexion et resynchronisation ; - appliquer backpressure/rate limits ; - produire observability et health. ## Modèles de synchronisation Aucun modèle unique ne convient à tous les jeux. ### Input authoritative Le client envoie principalement ses inputs. Le serveur : 1. valide l'input ; 2. l'applique à la simulation ; 3. avance l'état ; 4. publie l'état ou son delta. Approprié à de nombreux jeux compétitifs. ### State replication Le serveur publie : - snapshots périodiques ; - deltas entre snapshots ; - revision/tick associé ; - éventuellement ack/last-applied revision. Le client reconstruit un état local de présentation. ### Prediction / reconciliation Pour réduire la latence perçue : - le client prédit localement ; - conserve les inputs non confirmés ; - reçoit l'état serveur ; - corrige/rejoue si nécessaire. À réserver aux jeux qui en ont besoin. ### Rollback Particulièrement pertinent pour certains jeux de combat : - historique court d'états ; - inputs retardés ou prédits ; - rollback/re-simulation. Ce modèle ne doit pas contaminer le runtime de tous les jeux. ## Contrats techniques candidats ### Envelope réseau Champs conceptuels possibles : - protocol version ; - message type ; - session id ; - player id/connection id si nécessaire ; - sequence ; - server tick ; - client tick/time ; - payload. Le format exact n'est pas encore décidé. ### Snapshot Doit permettre : - état complet cohérent ; - revision/tick ; - application atomique côté client ; - point de reprise après resync. ### Delta Doit préciser : - base revision ; - target revision ; - mutations ; - comportement si la base manque. Un delta manquant doit conduire à une resynchronisation contrôlée, pas à une divergence silencieuse. ## Reconnexion et resynchronisation Cas à traiter : - coupure courte ; - suspension mobile ; - changement de réseau ; - client trop en retard ; - trou dans les séquences ; - restart d'une instance serveur. États conceptuels possibles : ```text Disconnected Connecting Joining Synchronized Resynchronizing Leaving ``` Le jeu ne doit pas confondre « socket ouvert » et « état de gameplay synchronisé ». ## Rooms, instances et scaling Pour plusieurs parties simultanées : - une room/session possède une autorité unique à un instant donné ; - les connexions sont routées vers l'instance responsable ; - l'instance peut héberger plusieurs rooms selon charge ; - la distribution des rooms peut évoluer indépendamment du protocole client ; - les données persistantes ne doivent pas être écrites dans la DB à chaque tick sans nécessité. À plus grande échelle, il faudra étudier : - session placement ; - shard/region ; - sticky routing ; - handoff/migration ; - recovery après crash ; - autoscaling ; - limites par instance. ## Interest management Pour un petit Snake 2 joueurs, diffuser tout l'état peut être acceptable. Pour une map plus grande/MMORPG, il faut pouvoir limiter les données à : - zone visible ; - proximité ; - équipe ; - objets pertinents ; - fréquence adaptée au type d'entité. L'interest management appartient au service realtime/game server, pas au renderer client. ## Persistence Séparer : ### État éphémère - positions ; - velocities ; - animation/state machine ; - projectiles ; - tick courant. ### État durable - compte ; - progression ; - inventory ; - résultat de match ; - rewards ; - classement. Le durable est persisté à des frontières métier appropriées, pas mécaniquement à chaque frame. ## Sécurité / anti-cheat Principes candidats : - ne pas faire confiance à une position envoyée directement par un client compétitif ; - valider les actions et contraintes de jeu côté serveur ; - rate limit ; - protéger join/session tokens ; - empêcher replay/double-submit d'actions sensibles ; - enregistrer suffisamment de données pour diagnostiquer une divergence ou fraude. ## Observability Le realtime nécessite au minimum des dimensions dédiées : - connexions actives ; - rooms actives ; - joueurs/session ; - tick duration ; - tick lag ; - queue/backpressure ; - messages/s ; - bytes/s ; - reconnects ; - resyncs ; - dropped/invalid inputs ; - snapshot/delta sizes ; - errors par protocole/version. Le logging par domaines devra pouvoir distinguer transport, session, sync et simulation. ## Technologies Le choix exact reste volontairement ouvert. Candidats à étudier ultérieurement selon le POC serveur : - HTTP(S) pour control plane/API ; - WebSocket pour data plane bidirectionnel ; - gRPC pour backend-to-backend ou services structurés ; - WebRTC uniquement si un besoin P2P/media le justifie. Le framework ne doit pas imposer une technologie unique à tous les services. ## Pressure test rapide ### Snake 2 joueurs Peut probablement fonctionner avec : - tick modéré ; - inputs directionnels ; - état authoritative ; - snapshot/delta simple ; - interpolation limitée ; - reconnect/resync. ### Racing Exigera potentiellement : - tick plus fréquent ; - prediction/reconciliation ; - interpolation ; - lag compensation selon gameplay ; - snapshots/deltas optimisés. ### Fighting 1v1 Peut nécessiter : - input synchronization très stricte ; - rollback netcode ou stratégie équivalente ; - historique court déterministe. ### MMORPG Exigera potentiellement : - zones/shards ; - interest management ; - sessions longues ; - persistence structurée ; - chat/presence ; - recovery/scaling. ## Questions ouvertes pour le futur POC serveur - Axum + Tokio + WebSocket suffit-il pour le premier service realtime ? - Une room est-elle une task, un actor, un shard ou une structure pilotée par scheduler ? - Quelle cadence de tick pour chaque genre ? - Quel codec : JSON de debug, bincode/postcard/protobuf/autre en production ? - Quelle frontière entre types de protocole partagés et logique serveur ? - Comment versionner le protocole sans coupler toutes les apps ? - Comment tester déterminisme, perte de paquets logique, reconnexion et resync ? - Quand introduire Redis/NATS/Kafka ou autre coordination, si jamais nécessaire ? Ces choix appartiennent à la future planification/POC, pas à cette étude de réservation.