La mise en réseau multijoueur dans des jeux semi-naux comme Half-Life et Counter-Strike a nécessité la résolution de défis techniques profonds qui continuent d'influencer le développement des jeux en ligne aujourd'hui. Construite à l'origine comme une modification du moteur Quake de Valve, Counter-Strike est devenue un titre autonome qui exige une haute précision, une faible latence et un gameplay résistant aux tris. L'architecture de réseau développée pour ces titres – fondée sur un modèle client-serveur, une fiabilité personnalisée par rapport à UDP et une compensation sophistiquée des laps de temps – a établi un repère pour les tireurs multijoueurs en temps réel.

Modèle client-serveur en détail

La Half-Life et la Counter-Strike ont mis en place une architecture client-serveur stricte où le serveur maintient un contrôle faisant autorité sur l'état du jeu. Chaque action du joueur – qu'il se déplace, tourne ou recharge – doit être validée par le serveur avant qu'elle n'affecte la simulation.

Serveur autorisé

Sur le moteur GoldSrc de Valve (et plus tard Source), le serveur exécute la simulation physique complète, la détection de collision, les règles de jeu et la logique AI. Les clients envoient des commandes brutes d'entrée (p. ex., touches ou mouvements de souris) au serveur, mais ils n'influencent jamais directement le monde. Le serveur traite ces entrées, met à jour l'état et diffuse les nouvelles positions, santé, événements et instantanés d'entités à tous les joueurs.

Traitement des entrées des clients

Chaque client recueille chaque image et le charge dans une structure de commande qui comprend des vecteurs de mouvement, des angles de vue, des états de bouton et un horodatage. Ces commandes sont envoyées au serveur sous forme de datagrammes UDP. Le serveur fait la queue des commandes entrantes, les exécute dans la bonne séquence en fonction de l'ordre de tic et les applique à la simulation autorisée. Pour aplanir la latence variable, le serveur traite simultanément les commandes de plusieurs clients pendant chaque étape de temps fixe. Toute commande arrivant trop tard ou hors de l'ordre est soit supprimée, soit rééchelonnée, selon son importance.

Transport réseau: Pourquoi UDP et fiabilité personnalisée

La demi-vie et la contre-strike reposent principalement sur UDP (User Datagram Protocol) pour l'échange de données en temps réel, le choisissant par rapport à TCP malgré les avantages garantis de TCP pour la livraison et la commande. La décision a été motivée par le besoin de faible latence et la capacité de récupérer rapidement de la perte de paquets.

Échanges entre les PDU et les TCP

TCP fournit une livraison fiable et en ordre, mais il introduit des frais généraux importants : il nécessite des remerciements, une retransmission de paquets perdus et une fenêtre de congestion qui peut causer un blocage de la tête de ligne. Dans un jeu de tir rapide, même un petit retard causé par l'attente d'une retransmission d'un paquet perdu peut ruiner l'expérience de gameplay. UDP, par contre, offre un modèle de livraison de meilleur effort sans commande ou retransmission intégrée. L'application d'envoi contrôle exactement ce qui quitte le réseau et quand, minimisant les frais généraux.

Manipulation et séquençage des pertes de paquets

Le code réseau GoldSrc implémente sa propre couche de fiabilité en plus de l'UDP. Des messages critiques (tels que des résultats de tir d'arme ou des décès de joueurs) sont envoyés par un canal fiable qui permet de transmettre des séquences de paquets et de requêtes si les reconnaissances ne sont pas reçues dans un délai d'attente. Des mises à jour moins critiques – comme des changements de position ou un état d'animation – sont envoyées de façon irréalisable, permettant au système de déposer des clichés plus anciens en faveur de nouveaux. Les numéros de séquence sont attachés à chaque paquet afin que le récepteur puisse détecter les datagrammes perdus ou hors de l'ordre et soit jeter des données inexistantes ou demander une réenvoi. Cette approche hybride a permis à Half-Life et à Counter-Strike de maintenir un gameplay réactif même sur les connexions à bande passante et à haute latence de la fin des années 1990 et du début des années 2000.

Pour un examen plus approfondi de l'évolution du réseau de jeux en temps réel, la présentation GDC 2001 de Valve par Yahn Bernier fournit un aperçu complet des techniques utilisées dans Half-Life: Méthodes de compensation de latence dans la conception et l'optimisation du protocole en jeu client/serveur.

Lisser le jeu de jeu sur les réseaux irréalisables

Même avec UDP et fiabilité personnalisée, les joueurs éprouvent une latence variable, une perte de paquets et une jitter. Pour maintenir l'illusion de la réponse instantanée et des vues du monde cohérentes, Half-Life et Counter-Strike ont mis en œuvre trois techniques critiques : la prédiction côté client, la réconciliation serveur et l'interpolation des entités.

Prédiction à l'échelle client et rapprochement des serveurs

Sans prédiction côté client, chaque action du joueur serait soumise à une latence aller-retour : vous cliquez sur la souris, la commande voyage vers le serveur, le serveur le traite et le résultat se déplace en arrière. Pour un jeu comme Counter-Strike, où les temps de réaction sont mesurés en millisecondes, ce délai serait inacceptable. La prédiction côté client permet au client local de simuler immédiatement l'effet de sa propre entrée (par exemple, aller de l'avant ou tirer) avant que le serveur le confirme. Le client exécute une copie du monde du jeu et le met à jour en utilisant les mêmes règles de mouvement et de physique que le serveur.

Cependant, la prédiction du client peut s'écarter de l'état faisant autorité du serveur en raison du décalage, de la perte de paquets ou des différences dans la simulation. La réconciliation du serveur corrige ces écarts. Chaque fois que le serveur envoie un instantané de l'état du jeu, le client compare les positions du serveur avec son propre état prédit. S'il y a un décalage, le client déplace en douceur ses entités locales vers les positions du serveur, corrigeant les erreurs sans mettre en péril la téléportation. Cette combinaison de prédiction et de réconciliation fait que Counter-Strike se sente réceptif même lorsque le joueur a un ping élevé.

Interpolation des entités

Parce que le serveur n'envoie des mises à jour qu'à une fréquence fixe (le taux de tic), le client reçoit des instantanés discrets. L'interpolation de l'entité remplit les lacunes en rendant les positions de l'objet à la fois entre les deux dernières prises de vue reçues, en utilisant des moyennes pondérées basées sur les chronomètres. Cela crée un mouvement fluide et continu même lorsque le serveur ne met à jour que 20 ou 66 fois par seconde.

Indemnisation pour les armes à charbon

L'une des caractéristiques les plus innovantes du netcode de Counter-Strike est la compensation de décalage pour les armes hitscan (rifles, pistolets, fusils snipers).Comme les balles voyagent instantanément dans les machines hitscan, le serveur doit décider si un tir en fonction de la position de la cible au moment où le tir a été tiré, pas quand le serveur l'a traité. Si un joueur a 100 ms de latence et vise un ennemi, au moment où le serveur reçoit la commande, l'ennemi peut avoir déménagé à un autre endroit.

La solution Valve stocke une courte histoire de la position de chaque joueur pour les cent dernières millisecondes sur le serveur. Lorsque le serveur reçoit une commande de tir, il vérifie la position de la cible au moment où le client du tireur les a vus (appariement de l'horodatage dans la commande). Le serveur effectue alors la détection de frappe par rapport à cette position historique, plutôt que par rapport à l'état actuel. Cette méthode – appelée compensation de décalage – réduit dramatiquement l'inconvénient d'un ping plus élevé. Cependant, elle introduit également le risque de «dépannage derrière les murs» si l'historique stocké est trop long ou si l'horloge du serveur n'est pas synchronisée.

Une ventilation détaillée de cette technique se trouve dans Gaffer on Games, où Glenn Fiedler explique les méthodes similaires utilisées dans les tireurs multijoueurs.

Taux de cliquetis et fréquence de mise à jour

Le taux de tic du serveur détermine la fréquence de traitement des entrées et des snapshots. Au début de Counter-Strike 1.6, le taux de tic du serveur par défaut était d'environ 20 Hz (20 mises à jour par seconde) sur les serveurs officiels, tandis que les serveurs compétitifs ont souvent augmenté à 33 ou même 100 Hz en utilisant des paramètres personnalisés.

Taux de cliquetis du serveur (sv tickrate)

Le taux de tic est directement lié à la taille de l'étape de simulation du serveur. À 33 Hz, chaque tic représente environ 30 ms de temps de jeu. Le serveur exécute toutes les commandes en attente, exécute la physique, traite les dommages, et envoie un instantané complet à tous les clients chaque tic. Un taux de tic plus élevé signifie une détection de frappe plus précise et un mouvement plus fluide, mais il augmente également la charge sur le processeur et le réseau du serveur.

Paramètres d'interpolation des clients (lemp)

Du côté client, un paramètre d'interpolation appelé (ou ) contrôle la distance dans le temps que le client rend le jeu pour compenser le retard réseau. Les clients doivent choisir une valeur lerp qui équilibre l'équilibre loyal avec réactivité. Un lerp réduit la latence visuelle mais peut causer des jitters si les paquets sont perdus; un lerp élevé lie les irrégularités réseau mais ajoute un retard constant à ce que le joueur voit.

La largeur de bande et l'optimisation des données

La demi-vie et la contre-strike ont été conçues pour les connexions Internet de leur époque (56k modems à haut débit précoce). Pour garder la bande passante gérable, le netcode a utilisé plusieurs techniques d'optimisation.

Compression Delta

Le serveur n'envoie pas l'état complet du jeu avec chaque instantané. Il envoie plutôt un instantané de base après qu'un joueur se connecte, et les instantanés suivants sont compressés par le delta : seuls les changements (deltas) depuis le dernier instantané reconnu sont transmis. Cela réduit considérablement la taille de chaque mise à jour. Par exemple, si un joueur reste immobile, le serveur peut envoyer seulement une mise à jour minuscule indiquant aucune modification de position. Si un joueur allume une arme, le delta inclut le nouveau nombre de munitions et l'état flash de muselière, mais pas l'ensemble du tableau d'armes.

Mises à jour des taux variables

Les événements critiques comme les dommages, les tueries et les tirs d'armes sont envoyés immédiatement en utilisant le canal fiable, tandis que les mises à jour de position courantes sont envoyées au taux de tic en utilisant le canal peu fiable. Le serveur ajuste également dynamiquement le taux de mise à jour en fonction de la bande passante disponible et de la qualité de la connexion client. Si un client subit une perte de paquets, le serveur peut réduire la fréquence des mises à jour non essentielles ou passer à un canal plus fiable pour les données critiques.

Architecture anti-chaleur (VAC et au-delà)

Bien qu'ACC soit avant tout un système de numérisation et de détection côté serveur, sa conception repose sur le code net du serveur. Les chèques qui modifient la mémoire du client ou injectent des paquets doivent contourner les vérifications de validation du serveur. ACC fonctionne en parallèle avec le code net par :

  • Vérifier que les exécutables et les DLLs du client correspondent aux bonnes versions connues.
  • Détecter les modèles comme l'utilisation de l'objectifbot en analysant les statistiques de précision des prises envoyées au serveur.
  • Banner des comptes qui sont capturés en utilisant des signatures de triche connues.

L'autorité du serveur empêche de nombreux tricheurs : un wallhack ne peut révéler que ce qui est déjà envoyé au client (le serveur envoie toutes les positions de l'entité, de sorte que les wallhacks sont atténués par la logique de « visibilité » du serveur et en limitant les données que les clients reçoivent sur les ennemis lointains).

Pour en savoir plus sur l'historique et les capacités d'ACC, consultez .

Héritage et influence sur le Netcode moderne

Les techniques de réseautage mises en place dans Half-Life et Counter-Strike ont établi un modèle qui est toujours suivi par presque tous les principaux tireurs en ligne. Les jeux modernes tels que Overwatch, Valorant et Call of Duty utilisent la prédiction côté client, la réconciliation serveur, la compensation de la latence, la compression delta, et les mises à jour basées sur les tiques. La documentation open-source de Valve et les discussions GDC ont aidé à éduquer toute une génération de développeurs de jeux.

L'influence s'étend au-delà des tireurs. Combattre les jeux, les titres de stratégie en temps réel, et même les jeux de course ont adopté des architectures client-serveur ou pair-à-pair similaires avec prédiction et retour. Les problèmes de base (latence, perte de paquets, tricherie) restent les mêmes, et les solutions développées pour Half-Life et Contre-Strike fournissent un point de départ robuste pour tout jeu en réseau.

Pour un aperçu technique de la façon dont Source netcode gère la réplication et la prédiction des entités aujourd'hui, reportez-vous à Documentation de réseau source multijoueur de Valve.

En résumé, le réseau multijoueur de Half-Life et de Counter-Strike n'était pas seulement un produit de son temps, mais une réalisation fondamentale qui a démontré comment offrir un gameplay en ligne réactif, équitable et évolutif. En conciliant les optimisations de performance avec une autorité serveur rigoureuse, Valve a créé une expérience que des millions de joueurs profitent encore aujourd'hui – et qui continuera d'informer comment les jeux connectent les gens sur Internet.