Améliorations du calcul du ping

Pour commencer, je vais vous expliquer certains termes que je vais régulièrement utiliser, et que vous pourriez ne pas connaître :
Client et serveur : chaque console, périphérique mobile, PC ou Mac est un client. Les clients se connectent à un serveur dédié qui héberge la partie. Le serveur traite l'ensemble des données générales de la partie (l'emplacement des joueurs, l'état du cercle, quels coffres sont actifs, etc.). Le serveur a aussi la responsabilité de mettre à jour les informations de tous les clients quand l'état de la partie change.
Paquet : un paquet est un bloc de données qui sont envoyées via le réseau, soit du client au serveur, soit du serveur au client. C'est la façon dont les clients et le serveur communiquent les uns avec les autres. Dans Fortnite (et dans l'UE4), nous utilisons ces paquets pour calculer les temps de latence.
Image (ou frame en anglais) : du côté du serveur, une image détermine à quelle fréquence le serveur effectue ses tâches (vérifier le transfert des paquets, mettre à jour l'état de la partie et envoyer des mises à jour aux clients). Du côté des clients, une image détermine à quelle fréquence l'affichage est mis à jour à l'écran. Le nombre d'images par seconde, abrégé en IPS, représente la fréquence de rafraîchissement, à savoir combien d'images sont traitées par le serveur ou le client chaque seconde. Ainsi, quand on dit qu'un client tourne à 60 IPS, cela signifie qu'il affiche 60 images chaque seconde.
Les bases étant posées, parlons du ping !
L'ancienne méthode de calcul du ping des paquets
Lorsque la plupart des gens évoquent le « ping », ils parlent du temps que met un paquet envoyé par le client pour aller jusqu'au serveur, puis du temps que met le serveur à répondre, ou vice-versa. On parle aussi dans ce cas de temps aller-retour, ou TAR. Cela fournit aux joueurs l'information qui les intéresse le plus : combien de temps il faut pour qu'ils reçoivent des mises à jour du serveur, et combien de temps il faut pour que le serveur reçoive leurs mises à jour. Plus la valeur de ping d'un joueur est élevée, plus il risque de voir des bizarreries dans le jeu, comme des joueurs qui semblent se téléporter, être éliminé sans comprendre ce qui arrive ou ressentir un temps de latence lorsqu'ils interagissent avec des coffres ou d'autres objets.Nous affichons le ping en millisecondes, et plus la valeur est faible, mieux c'est. Si vous habitez juste à côté d'un centre de données qui abrite nos serveurs, vous pourriez même avoir un ping inférieur à 10 ms ! En revanche, si vous jouez sur un serveur qui est situé de l'autre côté du monde, votre ping pourrait être de 100 ms ou plus.
Mais en ce qui concerne la communication entre clients et serveur, il y a plus bien de choses qui entrent en considération que le temps que mettent les paquets à faire l'aller-retour. Dans Fortnite, nous vérifions généralement si de nouveaux paquets sont arrivés une fois par image, tant sur le serveur que sur les clients. Cela signifie qu'il peut y avoir un délai d'une image complète entre le moment où un paquet arrive et le moment où le client ou le serveur s'en aperçoit, s'il arrive juste après la vérification d'arrivée des nouveaux paquets. De plus, il faut aussi un peu de temps pour lire le paquet et mettre à jour l'état de la partie en fonction des données qu'il contient.
Un petit diagramme pour illustrer la chose :
Les flèches noires du client et du serveur représentent le temps. Dans cet exemple, le serveur et le client sont parfaitement synchronisés et fonctionnent à la même fréquence (nombre d'images traitées par seconde). Les lignes verticales noires représentent le début de chaque image, les points bleus indiquent à quel moment le client ou le serveur vérifient si de nouveaux paquets sont arrivés pour traitement et les lignes orange indiquent à quel moment le client et le serveur envoient des paquets. Les lignes pointillées violettes représentent un paquet qui transite via Internet.
Voici dans quel ordre les choses se passent :
- Le client envoie un paquet au serveur.
- Le serveur reçoit le paquet envoyé par le client.
- Le serveur vérifie si de nouveaux paquets sont arrivés. C'est à ce moment-là que le serveur voit le paquet envoyé par le client. Remarquez sur le paquet est resté là presque toute une image sans être traité, car il est arrivé juste après que le serveur a vérifié si des paquets étaient arrivés.
- Le serveur envoie une réponse au client pour confirmer sa bonne réception.
- La réponse du serveur arrive sur le client.
- Le client lit la réponse du serveur.
Pour la valeur que nous affichons, nous faisons la moyenne entre cette valeur calculée pour des paquets sur plusieurs secondes, afin d'avoir une valeur cohérente.
Dans la pratique, malheureusement, ce n'est pas aussi précis que nous le voudrions. Cela ne prend pas en compte le temps entre l'arrivée des paquets et leur traitement effectif, et la valeur de ping affichée est souvent faussée. Le problème, c'est que la plupart des plateformes ne permettent pas de savoir quand ce traitement sera effectivement réalisé, et nous ne savons donc pas quel temps précis il faut soustraire.
Notre méthode de calcul du ping des paquets dans la 7.30
Pour la 7.30, nous avons eu une idée et nous voulions tester une autre méthode : et si nous ne prenions en compte que les paquets qui ont mis le moins de temps à aller du client au serveur et obtenir une réponse ? La théorie, c'était que les paquets qui mettent le moins de temps seraient ceux qui sont traités immédiatement, et que nous pourrions ainsi ignorer le délai d'attente de traitement, puisqu'il serait proche de zéro. Nous avons donc utilisé les 25% des paquets les plus rapides pour notre calcul du ping, parce que cela nous semblait le bon équilibre entre choisir les plus rapides et avoir suffisamment de données pour avoir une valeur réaliste.Qu'est-ce qui n'a pas marché ?
Après la sortie de la 7.30, nous avons reçu de nombreux rapports de joueurs signalant qu'ils avaient un ping inférieur à dix, voire même de 0. Si c'était vrai, nous enverrions les paquets plus vite que la vitesse de la lumière. Bien que le moteur UE4 soit fantastique, il n'en est pas encore là ! À l'évidence, il y avait un problème quelque part.Ce problème provenait en partie de la nouvelle méthode de calcul du ping. Le revoici, pour référence :
Le problème, c'était la soustraction du temps d'attente de traitement par le serveur. En ne prenant en compte que les paquets les plus rapides, nous en retirions beaucoup trop. Si un paquet est traité par le serveur dès qu'il arrive, il ne faut que quelques millisecondes pour le traiter et renvoyer une réponse. Et une image serveur peut être jusqu'à 5 fois plus longue !
Voici un diagramme de ce à quoi ça ressemble :
Ce client a une fréquence de rafraîchissement très supérieure au serveur. Nous ne prenons en compte que les paquets verts, ceux qui arrivent juste avant que le serveur ne s'aperçoive de leur présence. Dans ce cas, le serveur est plus rapide que son taux de rafraîchissement imposé, et il est en veille au début de l'image avant de vérifier si de nouveaux paquets sont arrivés.
La ligne rouge, c'est ce que nous retirons en prenant en compte le temps de rafraîchissement du serveur, mais nous devrions en réalité soustraire la ligne orange. C'est donc beaucoup trop de temps retiré, et c'est pour cette raison que certains clients voyaient s'afficher un ping de 0.
En utilisant notre ancienne méthode, qui prend en compte une plus grande variété de paquets, cela reste un problème. Toutefois, nous avons plus de chance de prendre en compte des paquets qui ont beaucoup attendu avant d'être traités, et ils compensent les paquets pour lesquels nous avons trop soustrait de temps.
Plans pour l'avenir
Nous avons des plans pour les futures mises à jour qui permettront d'afficher une valeur de ping plus précise. Je l'ai dit plus tôt :
« Le problème, c'est que la plupart des plateformes ne permettent pas de savoir quand ce traitement sera effectivement réalisé, et nous ne savons donc pas quel temps précis il faut soustraire. »
Mais par chance, Linux le permet ! Comme nos serveurs fonctionnent exclusivement sous Linux, nous pourrons changer la méthode de calcul du ping à l'avenir par celle-ci :
Ping = Temps du trajet du paquet du client jusqu'au serveur + temps mis par le paquet envoyé par le client entre son arrivée et l'envoi d'une réponse - temps d'image client à ce point.
Cela évite de devoir essayer de deviner combien de l'image serveur il fallait soustraire. Nous pensons que ce système permettra d'avoir des valeurs plus précises, mais nous avons encore beaucoup de tests à faire.
Nous envisageons aussi la possibilité de vérifier plus souvent l'arrivée de paquets sur le client, ce qui permettrait de supprimer la partie « temps d'image client à ce point » de la formule.
Ces deux modifications combinées devraient nous permettre d'afficher des valeurs de ping plus précises.
Conclusion
J'espère que cela vous a aidé à comprendre comment nous calculons le ping et comment nous travaillons à améliorer la méthode. Lorsque nous affichons ce genre d'informations, il est essentiel qu'elles soient précises : afficher des valeurs incorrectes peut être pire que de ne pas en afficher du tout. Il est important que les joueurs soient au courant quand ils ratent un tir si c'est parce qu'ils ont mal visé ou si c'est parce qu'ils ont un problème de latence ou de mauvais ping, pour pouvoir corriger le problème.
Je surveillerai les commentaires si vous avez des questions, et j'essaierai d'y répondre. Merci d'avoir pris le temps de me lire !