Réseau temps réel · C++20
R-Type
Rendre un shoot'em up à 4 joueurs jouable avec 300 ms de latence et 15 % de pertes.
Projet de groupe Epitech (G-ING-500). J'y ai conçu et écrit la partie réseau.
- C++20
- Asio
- UDP
- CMake
- vcpkg
- GoogleTest
01Le projet
Un remake coopératif du shoot'em up d'arcade, sur un moteur maison : ECS, rendu par lots, audio synthétisé. Le serveur fait autorité : il simule la partie et la diffuse aux clients en UDP.
Le problème du réseau dans un jeu d'action : les paquets arrivent en retard, dans le désordre ou pas du tout. Sans traitement, les ennemis se téléportent et son propre vaisseau répond avec un temps de retard. Ma partie consistait à rendre tout ça invisible.
02Démo
Essayez le netcode
Cliquez sur la simulation puis pilotez avec ↑/↓ (ou les boutons). En pointillés : la position réelle sur le serveur. À gauche, le vaisseau répond avec un aller-retour de retard et l'ennemi saute d'un état reçu au suivant. À droite, le vaisseau répond tout de suite et l'ennemi glisse, affiché un peu dans le passé.
03Ma partie
Ce que j'ai réalisé
Le protocole RTGP
Spécification complète d'un protocole binaire sur UDP, rédigée comme une RFC : en-tête, numéros de séquence, accusés de réception et renvoi des messages fiables, détection des doublons, snapshots complets et deltas, poignée de main et keep-alive.
La couche réseau du moteur
Lecture et écriture d'octets avec vérification des bornes, adresses IPv4 indépendantes d'Asio, socket UDP asynchrone et thread réseau dédié avec files d'entrée et de sortie, comptage de la bande passante.
Prédiction et réconciliation
Le vaisseau du joueur bouge tout de suite, avec la même fonction que le serveur (en entiers, donc des résultats identiques au bit près). À chaque état reçu, le client rejoue les entrées pas encore confirmées ; l'écart restant est lissé pour que le vaisseau ne saute jamais.
Interpolation des autres entités
Les ennemis et les autres joueurs sont affichés légèrement dans le passé, entre deux états connus. Le délai s'adapte à la gigue et aux pertes mesurées (de 67 à 400 ms), et même les explosions sont retardées pour tomber là où l'ennemi est dessiné.
Les outils de mesure
netbench, un relais UDP qui ajoute latence et pertes à la demande, et les mesures de bande passante et d'erreur de prédiction selon la qualité du réseau.
04Bilan
Ce que j'en retiens
- Concevoir un protocole avant de le coder, et l'écrire assez précisément pour qu'un coéquipier l'implémente sans moi.
- Raisonner en ticks plutôt qu'en millisecondes, et rendre la simulation déterministe pour que client et serveur tombent d'accord.
- Mesurer au lieu de supposer : chaque réglage du délai d'interpolation a été validé sur des réseaux simulés.