Dans un jeu en réseau, personne ne voit exactement le même moment
Le jeu en réseau me fait tripper comme problème de programmation. Tout ce qu’un système distribué essaie normalement de cacher apparaît directement à l’écran : messages en retard, état divergent, reprise et confiance limitée dans le client.
Le serveur garde une version autoritaire du monde. À chaque tick, il lit les commandes reçues, avance la simulation, résout les collisions et produit un nouvel état. Les clients envoient des entrées — avancer, tourner, tirer — plutôt qu’une position finale. Sinon un client modifié pourrait simplement annoncer « je suis derrière le mur » ou « j’ai touché ».
client A ── input #381 ──→ serveur tick 902 ── snapshot 902 ──→ A, B, C
client B ── input #144 ──↗ état autoritaire
UDP convient souvent aux mises à jour fréquentes parce qu’il n’attend pas la retransmission d’un vieux paquet avant de livrer le suivant. Le jeu ajoute ses propres numéros de séquence, accusés et priorités. Une commande « rejoindre la partie » doit être fiable; une position vieille de 200 ms peut être jetée si une plus récente est arrivée. TCP livrerait tout dans l’ordre, mais un paquet perdu peut retenir les suivants au moment où le monde a déjà changé.
Avec 100 ms d’aller-retour et un serveur à 20 ticks par seconde, attendre la confirmation avant de bouger ajouterait au moins deux ticks et semblerait lourd. Le client applique donc immédiatement son entrée à une simulation locale. Il conserve les commandes non confirmées avec leur numéro.
Quand le serveur renvoie « position officielle après input 381 », le client :
- remplace sa base par la position officielle;
- retire les commandes jusqu’à 381;
- rejoue 382, 383 et les suivantes;
- corrige visuellement le petit écart sur quelques images.
C’est la prédiction client et la réconciliation. La simulation doit être assez déterministe pour ne pas dériver sans cesse. Les flottants, l’ordre des collisions ou une carte différente peuvent produire des résultats différents; le serveur tranche toujours.
Les autres joueurs ne peuvent pas être prédits aussi directement, puisque je ne connais pas leurs prochaines commandes. Le client garde quelques snapshots et affiche le monde légèrement dans le passé, par exemple 100 ms, en interpolant entre deux positions connues. Ce délai volontaire donne un mouvement fluide malgré l’irrégularité des paquets. Si aucun nouveau snapshot arrive, il peut extrapoler brièvement, puis arrêter avant que le personnage traverse un mur.
Le tir pose un choix d’équité. Sur l’écran du joueur, la cible était au centre il y a 100 ms. Au moment où la commande arrive, elle a bougé sur le serveur. Un mécanisme de compensation de lag peut conserver un historique court, replacer les joueurs à l’heure estimée du tir et tester l’impact, tout en limitant le recul permis. Sinon une très vieille commande pourrait toucher quelqu’un rendu depuis longtemps à couvert.
La bande passante impose des deltas. Plutôt qu’envoyer tout le monde, le serveur transmet les objets pertinents et les champs changés depuis un snapshot reconnu. Si la base du delta manque, il faut redemander un état complet. Les snapshots portent un numéro et une empreinte de version de carte pour éviter d’appliquer une différence au mauvais monde.
Je testerais avec perte, désordre et latence artificiels :
- 100 puis 250 ms d’aller-retour;
- 1 %, 5 % et 10 % de paquets perdus;
- paquets livrés dans le désordre;
- pause complète de deux secondes;
- client qui annonce des entrées impossibles ou trop rapides.
Le serveur limite le rythme des commandes, valide les déplacements et ne transmet pas les informations que le joueur ne devrait pas connaître. Cacher un adversaire uniquement dans l’affichage ne suffit pas si sa position complète est déjà envoyée au client.
Quand tout fonctionne, on oublie les paquets. La pratique applicable bien au-delà du jeu est de nommer l’état autoritaire, numéroter les messages et décider pour chacun s’il faut le rejouer, le dédupliquer ou le jeter. La fluidité vient ensuite de prédictions qu’on sait corriger, pas de l’espoir que tous les messages arrivent à temps.