L'architecture réseau de Destiny 2 - plongée approfondie sur le jeu multijoueur

L'architecture réseau de Destiny 2 - plongée approfondie sur le jeu multijoueur

Points Clés

Points Clés

Points Clés

  • Minimiser la simulation côté serveur: Bungie a réduit la taille des instances cloud à environ 45 Mo en hébergeant uniquement l'état strictement requis par la logique de session, ce qui a permis près de 5 000 instances par serveur.

  • Déclarez avant de déployer: une discipline consistant à définir à l'avance l'état dont un script a réellement besoin (et à écarter tout le reste) est un principe d'optimisation transférable à toute architecture multijoueur.

  • Le taux de tick est un levier de coût: exécuter la logique de session côté serveur à 10 Hz au lieu d'aligner directement les fréquences de simulation client a réduit nettement les dépenses en CPU et en bande passante sans compromettre l'expérience des joueurs.

  • La réconciliation doit être conçue dès le départ: intégrer la cohérence d'état dans l'architecture dès le premier jour a évité toute une classe de bugs bloquant la progression, coûteux à traquer après le lancement.

  • Auditez ce qui s'exécute où: lorsque la logique critique pour la mission migre silencieusement vers le client sans supervision du serveur, cela crée à la fois des vecteurs d'exploitation et des risques de stabilité, faisant des audits d'architecture une partie de l'optimisation continue, et non un exercice ponctuel.

Justin Truman, aujourd’hui responsable du studio chez Bungie, a donné cette conférence à la GDC 2015 en tant que l’un des responsables techniques de Destiny, en présentant l’architecture de missions en réseau que l’équipe a construite pour prendre en charge un monde partagé fluide et toujours en ligne à l’échelle du lancement.

Indirectement, cela met en lumière des bonnes pratiques que n’importe quel studio de jeux, petit ou grand, peut appliquer pour réduire les coûts d’infrastructure cloud sans sacrifier l’expérience joueur.

Le point central : qu’est-ce que le serveur doit réellement simuler ?

L’enseignement le plus transposable de l’architecture de Destiny ne concerne ni le réseau pair à pair ni la conception du monde. C’est une question plus simple, mais plus difficile, que la plupart des équipes ne se posent pas assez tôt : que doit réellement simuler votre serveur, et qu’est-ce qui peut vivre ailleurs ?

La réponse de Bungie était l’hôte d’activité, un processus cloud allégé qui n’exécutait que l’état critique pour la mission dont dépendaient les scripts d’activité. Des choses comme savoir si une escouade avait été générée, combien d’ennemis étaient encore en vie, si un objectif avait été déclenché. Pas les trajectoires des balles. Pas l’état des animations. Pas les positions dans l’espace du monde. Cela vivait ailleurs.

Le résultat était un exécutable d’hôte d’activité d’environ 45 Mo, obtenu en prenant le binaire complet de Destiny et en supprimant tout ce qui n’était pas nécessaire pour cette couche logique précise. À 10 Hz, un seul serveur à 40 cœurs pouvait faire tourner près de 5 000 de ces instances simultanément. Comme Truman l’a expliqué, cela équivalait à environ 1 million d’utilisateurs simultanés pris en charge par seulement quelques centaines de machines, avec une marge de sécurité confortable. Une approche de serveur dédié avec simulation complète, à l’inverse, aurait nécessité quelque chose se rapprochant d’un demi-million de processus sans tête exécutant le jeu entier.

Les chiffres changent vite quand on cesse de simuler des choses qu’on n’a pas besoin de simuler.

Capteurs : un modèle pour déclarer ce dont vous avez besoin

Le mécanisme qui rendait cela possible était ce que Bungie appelait des capteurs. Avant qu’un script d’activité puisse référencer un élément d’état du jeu, il devait déclarer explicitement cette dépendance. Un script suivant une escouade d’ennemis ne stockait pas les barres de vie individuelles ni les positions dans le monde. Il suivait des faits discrets : combien sont encore en vie, ont-ils été générés, utilisent-ils cette zone de tir. C’est tout.

Cette approche fondée d’abord sur la déclaration avait un impact direct sur le coût de l’infrastructure. Comme le serveur ne conservait que ce que les scripts déclaraient formellement comme nécessaire, la surface d’état restait réduite et l’empreinte par instance restait faible. Les mises à jour de l’état des capteurs étaient envoyées de façon atomique à tous les capteurs simultanément, ce qui gardait la bande passante prévisible et écartait les incohérences d’état partiel.

Ce modèle s’applique bien au-delà de l’architecture spécifique de Destiny. Avant d’ajouter de l’état à votre serveur faisant autorité, demandez-vous : ce script ou cette logique de session en a-t-il réellement besoin ? Si la réponse est « pas vraiment, mais c’est plus simple de le mettre là », c’est là que le gonflement du serveur commence discrètement. Pour les équipes qui cherchent à réduire les coûts de vCPU et de sortie de données, un audit systématique de ce qui vit sur le serveur, et pourquoi, est souvent le point de départ le plus rentable. Le guide de profilage de serveur pour Unreal Engine d’Edgegap est un endroit pratique pour commencer cet audit.

La fréquence de tick comme levier de coût

Bungie faisait tourner ses hôtes d’activité à 10 Hz. Pas parce que 10 Hz était idéal pour chaque couche de la simulation, mais parce que la logique exécutée sur ces hôtes n’avait pas besoin de plus de rapidité. L’état des scripts de mission, le nombre de membres de l’escouade, les drapeaux d’objectif, les déclencheurs d’événements n’ont pas besoin d’être mis à jour cinquante fois par seconde. Les exécuter à une fréquence plus basse était un choix de coût délibéré, pas un compromis.

C’est un point qu’il vaut la peine d’intégrer. La fréquence de tick n’est pas une seule molette que l’on règle pour l’ensemble de son serveur de jeu. C’est une décision par couche, et la bonne réponse dépend entièrement de ce que fait cette couche. La simulation du combat et de la physique peut nécessiter des mises à jour à haute fréquence pour paraître réactive. La logique de session et l’état des scripts, souvent non. Confondre les deux et tout faire tourner à votre fréquence de tick la plus élevée est un moyen sûr de payer trop cher pour la capacité serveur.

Pour une analyse plus approfondie de la manière dont les choix de fréquence de tick influencent à la fois la précision du gameplay et le coût de l’infrastructure, le décryptage d’Edgegap sur la fréquence de tick des serveurs de jeu détaille les compromis.

La réconciliation comme architecture, pas comme réflexion après coup

L’une des leçons les plus coûteuses de Halo Reach, le prédécesseur de Destiny, était ce qui se produit quand on ne conçoit pas la cohérence d’état dès le départ. Les migrations d’hôte dans Reach provoquaient des écrans noirs, des drapeaux dupliqués, une progression cassée, des bogues difficiles à reproduire, sensibles au timing et coûteux à corriger à l’approche de la sortie.

La réponse de Bungie avec Destiny a été de traiter la réconciliation comme une préoccupation architecturale centrale plutôt que comme un problème à corriger script par script. Comme l’hôte d’activité faisait toujours autorité sur l’état déclaré, tout nouvel hôte de simulation physique recevant un appel de réconciliation pouvait être automatiquement ramené à un état de simulation cohérent. La logique de réconciliation réutilisait les mêmes chemins de code que les mises à jour normales de l’état. Ce n’était pas un cas particulier. Le système fonctionnait simplement comme prévu.

L’investissement d’ingénierie initial était réel. Écrire des capteurs coûtait plus cher qu’exposer une simple fonction au script. Mais ce coût était payé une fois par type de capteur, et non une fois par script qui l’utilisait. Sur un jeu en service avec des centaines de missions, ce compromis s’accumule nettement en faveur de l’approche architecturale.

Intégrer la réconciliation dès le départ signifie aussi que vous ne découvrez pas toute une classe de bogues bloquant la progression en QA, ou pire, en production.

Le coût de la logique client non suivie

L’exemple le plus clair de ce qui se passe quand l’architecture n’est pas appliquée de façon cohérente est l’exploit du raid Crota. Des joueurs ont découvert qu’ils pouvaient déclencher un état de jeu favorable en débranchant leur câble réseau à un moment précis pendant l’affrontement contre le boss du raid. Si cela fonctionnait, c’est parce qu’une partie critique de la logique du boss avait été construite entièrement avec des systèmes côté client, contournant complètement l’état faisant autorité de l’hôte d’activité.

Comme l’a dit Truman : « Je considère ce cas comme un échec d’ingénierie, pour ne pas avoir accordé assez d’attention aux scripts de raid les plus complexes ni les avoir audités. »

Ce n’est pas seulement un problème de sécurité. C’est aussi un problème d’optimisation. Une logique qui dérive vers le client sans être suivie côté serveur n’apparaît pas dans le profilage de votre serveur. Elle ne contribue pas à l’empreinte d’instance que vous payez. Mais elle ne vous donne pas non plus les garanties de cohérence que vous pensez avoir. Le résultat, c’est un écart entre l’architecture que vous aviez prévue et celle qui existe réellement.

Des audits réguliers de ce qui s’exécute où, en recoupant la logique des scripts avec l’état suivi par le serveur, font partie de la manière de garder une architecture honnête. Plus le jeu est complexe, plus cet écart peut s’ouvrir facilement sans que personne ne s’en rende compte, jusqu’à ce que quelque chose casse dans une partie en ligne.

Cet article s’appuie sur la conférence GDC originale de Justin Truman et la cite, présentée à la GDC 2015 et publiée sur la chaîne YouTube de la GDC. Tous les droits sur le contenu original appartiennent à leurs détenteurs respectifs.

Écrit par

l'équipe Edgegap

Intégrer Edgegap facilement en quelques minutes

Commencez l'intégration maintenant!

Commencez l'intégration maintenant!