La latence de jeu détermine l'essentiel du retard ressenti par le joueur à l'écran, et elle vient rarement d'une seule cause : ce sont plusieurs couches de délai empilées les unes sur les autres. Une approche pratique consiste à diviser le travail en trois domaines : choisir un emplacement physiquement proche des joueurs, améliorer la route réseau que parcourt un paquet, et régler la boucle de tick et le flux de paquets dans le code du serveur. Cet article parcourt les trois avec des étapes réelles et applicables.
D'où vient la latence ?
Le retard que voit un joueur est en réalité la somme de plusieurs parties :
- Délai de propagation : la distance parcourue par le signal dans la fibre. La lumière se déplace dans le verre à environ 200 000 km/s, donc même 3 000 km représentent ~15 ms de base pour un aller simple. On ne peut pas l'effacer par le code ; on ne le réduit qu'en raccourcissant la distance.
- Délai de file d'attente et de traitement : le temps qu'un paquet attend dans les routeurs du trajet, dans la carte réseau du serveur et dans la boucle de jeu.
- Délai de sérialisation : le temps nécessaire pour écrire le paquet sur le lien, sensible pour de gros paquets sur une faible bande passante.
- Délai de tick : comme le serveur met à jour l'état à intervalles fixes, une entrée peut attendre le prochain tick.
L'objectif est de gagner quelques millisecondes à chaque couche que vous contrôlez, car elles s'additionnent.
1. Choisir le bon emplacement
Le gain le plus grand et le moins cher vient en général du rapprochement du serveur de votre base de joueurs. Si la plupart de vos joueurs sont en Turquie et en Europe, garder le serveur dans une région centrale comme Francfort, Amsterdam ou Istanbul économise des dizaines de millisecondes par rapport à un centre de données aux États-Unis. Une seule bonne décision peut compter plus que toutes les optimisations ultérieures réunies.
Avant de vous engager sur un emplacement, mesurez-le réellement. Pour voir l'aller-retour de base depuis la région cible :
ping -c 20 ip-serveur
mtr -rwzc 50 ip-serveur
Dans la sortie de mtr, observez la perte de paquets et les pics de latence à chaque saut ; cela permet de distinguer si le problème vient de la distance ou d'un mauvais opérateur intermédiaire. Si votre base de joueurs s'étend sur plusieurs continents, la bonne réponse est des serveurs régionaux qui dirigent chaque joueur vers le plus proche, et non un seul serveur géant.
2. Améliorer la route réseau
Même quand la distance géographique entre deux points est courte, le trafic internet suit parfois une route longue et médiocre. Avec mtr ou traceroute, vous pouvez repérer des détours inutiles ou un fournisseur de transit avec des pertes de paquets fréquentes.
- Qualité du fournisseur et du peering : choisissez un hébergeur avec de bons accords de peering qui se connecte près des FAI de vos joueurs. Même dans le même centre de données, différents fournisseurs prennent des routes différentes.
- Utilisez UDP : pour le trafic de jeu en temps réel, les garanties de retransmission et de livraison ordonnée de TCP nuisent souvent — attendre un ancien paquet de position perdu retarde le nouveau. La plupart des jeux construisent leur propre couche de fiabilité au-dessus d'UDP.
- MTU et fragmentation : gardez les paquets sous le MTU du chemin (généralement 1500 octets, plus bas avec des tunnels) pour éviter la fragmentation et le délai qu'elle ajoute.
3. Réglages du système et des sockets
Côté Linux, quelques réglages réduisent le temps pendant lequel le serveur retient un paquet. Le plus important est de désactiver l'algorithme de Nagle, qui regroupe les petits paquets et ajoute donc un délai visible au trafic interactif :
int flag = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
Pour les sockets UDP, gardez les tampons d'envoi/réception assez grands pour résister aux rafales et pilotez le socket en mode non bloquant avec epoll. Sous charge, un tampon qui déborde et perd des paquets est une cause fréquente de ping qui s'envole. Réglez les paramètres du noyau comme net.core.rmem_max selon la charge réelle, pas à l'aveugle.
4. Tick rate et boucle de jeu
Le serveur met à jour le monde à une fréquence fixe (tick rate). Une boucle à 20 Hz avance toutes les 50 ms ; 60 Hz toutes les ~16,7 ms. Un tick rate plus élevé raccourcit l'attente d'une entrée avant traitement mais augmente le coût CPU. En pratique, les jeux nerveux privilégient 30 à 60 Hz.
Ce qui compte, c'est que la boucle reste fixe et prévisible. Un pas de temps fixe propre ressemble à ceci :
const double dt = 1.0 / 30.0; // 30 Hz
double accumulator = 0.0;
double last = now();
while (running) {
double current = now();
accumulator += current - last;
last = current;
while (accumulator >= dt) {
update(dt); // avancer la simulation
accumulator -= dt;
}
flush_outgoing(); // envoyer l'état tout de suite
}
Le point critique ici est d'envoyer l'état immédiatement après update au lieu de le mettre en tampon ; sinon vous rendez le gain du tick dans une file artificielle. Déplacez aussi le travail lourd dans un tick (écritures en base de données, I/O fichier, journalisation) sur un thread séparé de la boucle principale, pour qu'une seule requête lente ne fige pas tous les joueurs.
5. Gérer la bande passante et le jitter
Aussi important que le ping brut, le jitter est la variation du délai. Un 60 ms stable est plus agréable qu'un ping qui saute sans cesse entre 20 et 120. Pour réduire le jitter :
- Réduisez les mises à jour d'état avec des deltas (n'envoyer que ce qui a changé) ; moins de données, moins de délai de sérialisation.
- Gardez un débit d'envoi par joueur stable ; les rafales soudaines gonflent les files.
- Utilisez un petit tampon d'interpolation côté client pour lisser les fluctuations réseau.
Questions fréquentes
Augmenter le tick rate réduit-il le ping ?
Pas le ping réseau directement ; le délai réseau dépend de la distance et de la route. Mais comme il raccourcit l'attente d'une entrée avant traitement, il réduit le retard total ressenti par le joueur. Être stable et bas compte plus qu'être élevé.
Dois-je utiliser UDP ou TCP ?
UDP pour le trafic position/entrée en temps réel. La livraison ordonnée de TCP nuit car attendre un ancien paquet retarde le nouveau. Là où la fiabilité est nécessaire (événements importants, par exemple), construisez votre propre couche d'accusé de réception légère au-dessus d'UDP.
Mes joueurs sont sur différents continents, que faire ?
Vous ne pouvez pas satisfaire tout le monde avec un seul serveur. Déployez des serveurs régionaux et dirigez chaque joueur vers celui au ping mesuré le plus bas ; la distance physique ne se bat pas avec du code.
Le ping de votre serveur est trop élevé ? Je peux vous aider à traquer le délai au niveau de l'emplacement, de la route réseau et de la boucle de jeu, et à le transformer en amélioration mesurable. Contactez-moi et examinons votre configuration ensemble.