Boom! Headshot!

Sommaire


Le réseau dans les jeux vidéos
  • 1. Introduction
  • 2. TCP vs UDP
  • 3. La fiabilité avec UDP (à paraitre)
  • ?. Spoilers...

Alors que je travaillais sur mon troisième jeu multijoueur, je me suis fait la réflexion qu'il serait intéressant de partager mes connaissances sur le sujet.

Bienvenue donc dans cette série d'articles dédiés au réseau et aux protocoles employés dans le jeu vidéo.

World of Warcraft, Rocket League, Starcraft, League of Legend, soupire Fortnite, Unreal Tournament, j'en passe et des meilleurs.
Tous ces jeux ont quelque chose en commun, la possibilité de jouer avec d'autres personnes, que ce soit en compétition ou en coopération.

Mais vous vous êtes sûrement déjà posé la question, "au fait, comment ça se passe tout ça ?", et c'est une question bien légitime, comment cela fonctionne lorsque vous déplacez une unité pour que ce déplacement se répercute chez les autres joueurs ? Que se passe-t-il entre le moment où vous cliquez avec la souris et le moment où le joueur que vous venez d'abattre d'un headshot se mette à crier de rage ?

Avant de présenter les mécanismes mis en place par tous ces jeux, il est nécessaire de faire un rappel sur les réseaux connectant les ordinateurs, dont notamment le plus connu de tous, Internet.

Le réseau mondial

The internet is not a big truck. It's a series of tubes.
Ted Stevens

As to the internet being a "series of tubes"… I suppose it is, in the sense the solar system is series of rocks, the ocean is a series of lakes and rivers joined together, and a building is a series of walls.
Brian Dunlap

Ne dites plus Internet, mais les internets.
Frédéric Martel

Internet c’est avoir toute la sagesse et toute la bassesse du monde au bout des doigts.
Benoît Gagnon

The Internet is for porn.
Trekkie Monster

Il ne faut pas croire tout ce qu'on peut lire sur Internet.
Sir Isaac Newton

Internet, ou les internets[1], est un réseau mondial, regroupant lui-même des millions d'autres réseaux publics et privés appartenant à des centaines de pays et d'entreprises différents.

Il est composé de plusieurs millions de routeurs à travers le monde, dont le rôle est de relayer les données qui transitent vers le bon destinataire.

Il ne faut pas le confondre avec ce qu'on appelle communément le Web, qui est la partie d'internet accessible à travers un navigateur comme Chrome ou Firefox[2], à l'aide le plus souvent du protocole HTTP(S).

Dans le domaine du jeu vidéo, c'est assez différent, on accède alors à la plus grande partie d'internet, celle qui est destinée aux échanges entre ordinateurs, cela apporte quelques différences notables en terme de communications, par exemple un serveur Web va le plus souvent communiquer des informations d'affichages (à l'aide des langages de description[3] HTML et CSS) et faire transiter les données textuellement[4]. Quant à un serveur de jeu, lui va le plus souvent faire transiter des informations logiques et en binaire.

Cette différence est expliquée par des contraintes plus strictes. Une page Web qui charge en une demi-seconde ou en deux secondes n'est pas bien grave alors que l'information que vous venez de tirer soit transmise à votre ennemi en 20 ou en 200 millisecondes change complètement l'expérience de jeu.

Avant de reparler des contraintes liées au jeu vidéo, il serait bon de parler d'abord de la façon dont les données s'échangent sur internet.

Tout d'abord, sur Internet vous allez être confronté au protocole IP[5], celui-ci décrit notamment la façon dont les données sont découpées en paquets.
Un paquet est un ensembles de donnés (une suite d'octets) accompagnées d'un (ou plusieurs) en-tête définissant les informations nécessaires à l'acheminement du paquet en question jusqu'à l'ordinateur cible.

Le fonctionnement est celui-ci : un ordinateur transmet un paquet IP contenant l'adresse (la fameuse adresse IP) de l'ordinateur de destination au routeur auquel il est connecté. Celui-ci, lui-même connecté à plusieurs autres routeurs, va transmettre le paquet à un de ses voisins (qu'il va choisir selon beaucoup de facteurs, comme la proximité avec la destination, le temps de réponse, etc.).
C'est une sorte de course de relais qui se déroule en quelques millisecondes.

Il est d'ailleurs possible de voir les points de passage empruntés pour contacter une adresse de destination avec la commande traceroute (ou tracert sous Windows).

lynix@Malcolm:~# traceroute -6 google.com
traceroute to google.com (2a00:1450:4007:816::200e), 30 hops max, 80 byte packets
 1  vss-5b-6k.fr.eu (2001:41d0:2:d4ff:ff:ff:ff:fd)  0.476 ms  0.593 ms  0.702 ms
 2  2001:41d0:0:5:3::182 (2001:41d0:0:5:3::182)  0.349 ms  0.434 ms  0.429 ms
 3  2001:41d0:0:5:2::22 (2001:41d0:0:5:2::22)  0.505 ms 2001:41d0:0:5:2::20 (2001:41d0:0:5:2::20)  0.672 ms 2001:41d0:0:5:2::34 (2001:41d0:0:5:2::34)  0.477 ms
 4  * * *
 5  * * *
 6  google.as15169.fr.eu (2001:41d0::171)  4.425 ms google.as15169.fr.eu (2001:41d0::832)  4.094 ms google.as15169.fr.eu (2001:41d0::171)  4.497 ms
 7  2001:4860:0:1015::1 (2001:4860:0:1015::1)  4.839 ms  4.579 ms 2001:4860:0:1017::1 (2001:4860:0:1017::1)  5.245 ms
 8  2001:4860:0:1::1b1b (2001:4860:0:1::1b1b)  4.238 ms 2001:4860:0:1::1b19 (2001:4860:0:1::1b19)  4.334 ms 2001:4860:0:1::1b1b (2001:4860:0:1::1b1b)  4.327 ms
 9  par10s33-in-x0e.1e100.net (2a00:1450:4007:816::200e)  4.018 ms  4.205 ms  4.201 ms

Ne vous y fiez pas, les routes (chemins empruntés par les paquets) changent continuellement, il peut arriver bien des choses sur un réseau de la taille de la planète entière, et les routeurs réévaluent continuellement leurs voisins pour assurer la pérennité et la performance du réseau.

Une des conséquences importantes de ce mécanisme est que vous n'avez aucune assurance que vos paquets arriveront dans l'ordre d'envoi, ou même qu'ils arriveront tout court. Il est également possible qu'ils arrivent corrompus (avec des données différentes de celles d'origine) ou que tout se passe bien mais qu'ils arrivent plusieurs fois.
En pratique ces problèmes sont rares, mais sur les milliers de paquets qu'une application est amenée à faire transiter, il est certain que cela va se produire.

Cela étant dit le protocole IP n'est pas directement utilisé, il est directement encapsulé notamment par deux autres protocoles dont vous avez déjà certainement entendu parler : TCP et UDP.[6]

Ces deux protocoles ajoutent tous les deux une gestion des ports logiciels, un nombre non-signé sur 16bits (entre 0 et 65535) permettant au système d'exploitation de savoir à quel programme un paquet est destiné (le programme ayant fait la demande au préalable de recevoir les paquets sur les ports qui l'intéressent), ainsi qu'une somme de contrôle sur 16bits qui rajoute une gestion de l'intégrité assez théorique et faible (16bits est insuffisant).

TCP, le plus connu de ces deux protocoles ajoute la notion de connexion entre deux ordinateurs ainsi que des mécanismes pour garantir l'intégrité, l'ordre et la retransmission des paquets perdus, de plus il abstrait la notion de paquet derrière un flux[7], autrement dit c'est du tout ou rien et le destinataire reçoit ce que vous écrivez tant que la connexion subsiste.

UDP à côté est une surcouche très fine au protocole IP, qui n'ajoute donc rien de plus que la gestion des ports et de la somme de contrôle (dont le calcul n'est obligatoire qu'en IPv6 !), il vous permet donc d'envoyer des paquets d'un ordinateur à l'autre sans avoir besoin d'établir de connexion mais vous n'avez donc aucune garantie supplémentaire par rapport aux paquets IP.

Alors, selon-vous, lequel de ces deux protocoles domine le jeu vidéo et est très souvent la seule option viable pour du temps réel ?

Contre toute attente, c'est bien l'UDP, et nous allons voir pourquoi dans le second chapitre.


  1. Techniquement plus correct mais supplanté par l'usage, un peu comme RRID en C++. #rtsittrist ↩︎

  2. #teamopera ↩︎

  3. Parce que non, HTML et CSS ne sont pas des langages de programmation. ↩︎

  4. Si on met de côté la compression et le chiffrement possible. ↩︎

  5. Pour Internet Protocol, no shit Sherlock. ↩︎

  6. Techniquement TCP/IP et UDP/IP, mais presque personne ne les appelle comme ça. ↩︎

  7. Comme stdin (std::cin) par exemple. ↩︎