eSportConnect

Créer mon compte

Créez votre compte gratuitement pour profiter de toutes les fonctionnalités !

2019-10-26 18:40:00

Star Citizen : l'OCS expliqué

L’OCS en une ligne
L’OCS est la technologie de Star Citizen qui doit permettre aux développeurs de créer un univers entier, de grande qualité graphique, sans chargements.Un objectif : Au moins 30 images par seconde
Pour qu’un jeu vidéo soit perçu comme fluide par le joueur, il est nécessaire d’afficher une nouvelle image au plus tard toutes les 33 millisecondes (ce qui correspond à un minimum de 30 FPS). En dessous de ce niveau de performance, l’humain peut distinguer les images les unes des autres.
L’architecture technique du jeu est entièrement conçue pour atteindre cet objectif.Des données qui doivent être présentes en RAM
Pour calculer ces images à afficher, l’ordinateur a besoin d’avoir accès à certaines données du jeu.
Ces données (formes, textures, caractéristiques…) peuvent être stockées soit sur un disque dur, soit en mémoire vivre (RAM). Les disques durs disposent d’une immense capacité de stockage (de l’ordre de plusieurs centaines à plusieurs milliers de gigaoctets) qui se conserve même quand l’ordinateur est éteint, ce qui est nécessaire et suffisant pour conserver le jeu. La RAM est beaucoup plus limitée en stockage (de l’ordre de quelques dizaines de gigaoctets) et s’efface quand l’ordinateur est éteint. Cependant, la RAM est beaucoup plus rapide d’accès, plus de 40 fois plus rapide que les disques durs.
Pour être en dessous de l'objectif des 33 ms de temps de traitement, ces données doivent impérativement être présentes en RAM.Des échanges nécessaires avec le disque dur
Comme on l’a indiqué plus haut, tout le jeu ne tient pas en RAM (Le jeu fait plus de 50 Go aujourd’hui et les ordinateurs ont généralement 16 Go ou 32 Go) L’idée est donc de ne pas charger tout le jeu, mais seulement les données qui sont utiles pour les calculs actuels.
Sauf que ces transferts entre le disque dur et la RAM prennent du temps (200 millisecondes pour 10 mégas), ce qui peut provoquer des ralentissements visibles par les joueurs. Il faut donc pouvoir les faire à l’avance, sans ralentir les traitements.Les processeurs modernes à la rescousse
Les processeurs modernes disposent de plusieurs unités de calculs (coeurs et autre techniques de multithreading), ce qui permet d’en allouer certains au chargement (et déchargement) dynamique des données en mémoire pendant que d’autres continuent de faire tourner la simulation.Une architecture globale : l’OCS
On ne peut pas charger et décharger les données n’importe comment n’importe quand. Si on touche à une donnée en RAM alors qu’un traitement l’utilise, ou si on lance un traitement alors que sa donnée n’est pas encore présente, cela peut provoquer des erreurs, des bugs, des crashs. Les différents cœurs doivent donc se synchroniser entre eux, ce qui consomme du temps.
L’architecture du jeu doit donc être entièrement pensée pour permettre ces chargements/déchargements dynamiques tout en minimisant le temps perdu dans les synchronisations. C’est l’Object Container Streaming.
Dans un développement traditionnel, l’OCS aurait été développé sur de nombreux mois pendant lesquels les fonctionnalités n’auraient pas pu être testées. Comme Star Citizen est en Alpha avec des patchs réguliers, ils ont dû trouver une stratégie de déploiement de l’OCS par petits bouts, afin de conserver un jeu jouable pendant toute son implémentation.
Les fondations
Même si les résultats n’ont vraiment été visibles qu’à partir du patch 3.1, le travail a commencé il y a 5 ans. Avant, le moteur du jeu était construit sur le concept de niveau. Un niveau est un ensemble d’entités qui doivent être chargés en mémoire vive pour que le niveau puisse se lancer.
Les développeurs ont donc imaginé le concept de conteneur d’objets, c’est-à-dire le découpage de l’univers en plusieurs parties plus petites. Au lieu d’avoir un seul niveau monobloc, l’univers est composé d’une arborescence d’entités (par exemple, l’univers est composé de systèmes, qui sont composés de planètes, de lunes, de stations, qui sont composées de ... etc)
Quand les développeurs sont passés d’une architecture en niveaux à une architecture en conteneurs d’objets, il n’y a eu aucun changement pour les joueurs : en effet, au début, ils chargeaient tout l’univers pendant l’écran de chargement. Mais c’était une étape essentielle pour la suite.
A partir de l’architecture en conteneurs d’objets, on peut implémenter un système de chargement/déchargement dynamique pour que tout l’univers ne se charge pas d’un coup, mais seulement les objets utiles.Le problème du LUA
Avant de mettre en place des chargements dynamiques, certaines améliorations ont dû être apportées au code. Le moteur du jeu utilisait massivement le LUA, un langage de script très répandu mais qui ne permet pas de travailler sans risque dans un environnement multi coeurs/multithreads. Il a fallu convertir toutes les parties du code LUA en C++, ce qui a pris un peu de temps.La conversion des entités en composants
Les entités utilisées avant étaient très grosses pour être utilisées efficacement. Un autre travail préparatoire à l’OCS a été de décomposer les entités en composants, afin de rendre génériques les comportements des entités et de réduire la taille des objets à charger/décharger.La sérialisation des variables
Pour partager des données entre machines ou pour sauvegarder et charger les parties de Squadron 42; les développeurs ont dû réfléchir à la manière de sérialiser les données. Ceci a des conséquences importantes sur le server meshing (voir plus bas)Chargement des ressources en environnement multithread
Une autre étape a été de modifier le moteur du jeu pour lui permettre de charger des composants pendant l’exécution de la simulation. Le moteur le faisait pour quelques éléments graphiques, notamment pour le processeur graphique, mais il a fallu l'étendre à tous les types d'objets.
Chargement parallélisé des composants
Une fois les fondations terminées, ils ont commencé à construire par dessus en permettant aux données de se charger indépendamment de la simulation, ce qui permet de ne pas ressentir de ralentissement quand un nouvel objet apparaît (un vaisseau appelé sur une console ASOP par exemple)
Ensuite, ils ont mis au point une technique pour faire sortir progressivement les centaines de composants différents de la simulation. Ils ont utilisé le principe des fibres, qui permettent de choisir où est quand est exécuté le code. Ainsi, à partir du patch 3.2, de plus en plus de parties du code sont sorties de la simulation pour être exécutées en parallèle, ce qui a amélioré les performances.
Préparation de l’OCS client
Les développeurs ont choisi d’implémenter l’OCS côté client en premier afin de ne pas avoir à gérer tous les fronts d’un coup, et pour permettre aux joueurs d’avoir un gain de performance. Cependant, même cette implémentation limitée a demandé plusieurs étapes préparatoires supplémentaires.Planificateur de mise à jour des composants
Pour pouvoir charger/décharger dynamiquement les conteneurs d’objet sur la machine d’un joueur, il faut pouvoir estimer si ce conteneur est utile ou pourrait être utile bientôt pour ce joueur. Pour cela, ils ont réutilisé un outil qui leur permettait de moduler la fréquence de rafraîchissement des objets en fonction de leur visibilité.Hiérarchie et agrégats de composants
Ensuite, ils ont dû mettre en place un système de hiérarchie des conteneurs qui permet de gérer les situations où des conteneurs s’assemblent ou se combinent. Par exemple, un joueur qui porte une caisse, ou un vaisseau qui entre dans un autre. Ces assemblages de conteneurs imposent un ordre pour les charger/déchargerLots de chargement de composants
Ils ont également dû trouver des solutions pour gérer les chargements de nombreux objets simultanément. En effet, le chargement d’objets prend du temps, et il peut se créer un décalage entre le moment où le serveur indique qu’un objet doit être pris en compte et le moment où cet objet est bien chargé sur le client. Ainsi, les développeurs ont construit un système pour que des conteneurs d’objets soit liés dans leur apparition. Par exemple, pour qu’un vaisseau apparaisse avec son armement entier. Dans cet exemple les apparitions des deux entités sont intrinsèquement liées.
Pour résoudre les problèmes de temps de chargement des objets, ils ont également mis en place un mécanisme pour mettre à jour des objets juste près leur chargement par le client.Serialized variable culling.
Au moment du patch 3.0, les serveurs envoyaient des informations à tous les joueurs sur les entités proches d’au moins un joueur, ce qui créait une consommation de ressource inutile. Ils ont donc implémenté pour le patch 3.1 le « Serialized variable culling », un mécanisme qui permet de n’envoyer que les mises à jour d’objets utiles pour le joueur.
La mise en place de l’OCS client
Toutes les technologies et mécanismes préparés pendant des années ont été mises à profit pour mettre en place le « Network Bind Culling », qui est le nom technique de l’OCS côté client. En résumé, l’OCS client permet à chacune des machines des joueurs de ne connaître et de ne mettre à jour que la partie de l’univers qui la concerne à l’instant présent et dans un futur proche.
Ainsi, la simulation met à jour moins d’entités et s’exécute donc plus rapidement, et la mémoire RAM est moins utilisée. L’OCS client a apporté un gain significatif pour tous les joueurs.
Un autre avantage est que le client n’est plus affecté par la taille de l’univers. Les développeurs peuvent maintenant ajouter autant de systèmes qu’ils le souhaitent : les performances côté client n’en seront pas affectées. Cependant, toutes ces améliorations n’ont que peu d’effet sur le serveur. Celui-ci doit gérer de plus en plus d’entités. Il est donc nécessaire d’implémenter aussi un OCS côté serveur.
L’OCS serveur
L’objectif de l’OCS serveur est de faire en sorte que le serveur ne perde pas de temps à simuler les objets qui ne sont visibles par aucun joueur, c’est-à-dire que le serveur doit pouvoir décharger de sa mémoire et de sa simulation certains objets.
Ceci implique de stocker les objets non utilisés dans une base de données, en utilisant les variables sérialisées, et de les charger quand ils vont être d’intérêt pour un joueur.
On voit donc apparaître une hiérarchie : la base de donnée contient l’univers tout entier de manière statique, chaque serveur simule une partie de la base de données, chaque client voit une partie d’un serveur.
La mise en place de l’OCS serveur nécessite des développements supplémentaires par rapport à l’OCS client.Etats finis
Avec l’OCS serveur, les problèmes d’ordre dans le chargement des objets réapparaissent. En effet, pour régler ces problèmes côté client, les développeurs avaient utilisé une astuce exploitant le fait que les serveurs connaissaient tout en permanence. Ils pouvaient renvoyer les données des objets une fois leur chargement terminé. Le serveur devant lui-même charger ces objets, la solution doit être plus robuste.
Ainsi, les développeurs définissent un ordre strict dans lequel les objets doivent être chargés : par exemple, les personnages doivent apparaître après les bâtiments afin qu'ils ne traversent pas le sol.Starhash
Pour accéder aux données stockées dans la base de données, les serveurs ont besoin de pouvoir faire des recherches spatiales sur un grand nombre d’objets. Les développeurs ont donc adapté l’algorithme Geohash (utilisé par de nombreuses applications cartographiques) en étendant le nombre d’objets manipulés et en le passant en 3 dimensions.Location ID
Les points d’apparition présentent une difficulté particulière : si aucun joueur n’est à proximité, ils n’existent pas dans le serveur. Ainsi, quand un joueur se connecte ou doit apparaître quelque part, ils ont mis en place un mécanisme pour charger tous les objets autour de son point d’apparition.Travaux en cours
Au moment où l’article est écrit, le système de « location ID » est encore en cours de développement et les problèmes liés aux états finis sont en cours de résolution.
Futurs travauxPersistance
Actuellement, un crash serveur implique une perte de données liées à la persistance. Les développeurs doivent donc mettre en place un mécanisme de sauvegarde en continu des objets persistants.Réseau maillé (server-meshing)
L’OCS serveur permet d’améliorer les performances pour les joueurs d’un serveur et d’augmenter la taille de l’univers, mais ne permet pas d’augmenter le nombre de joueurs sur un serveur.
Le server meshing a pour objectif de répartir l’univers sur plusieurs serveurs physiques et donc d’augmenter le nombre de joueurs.Outils internes
L’outil permettant de construire l’univers ne tire pas encore profit de l’OCS serveur. Ainsi, plus la taille de l’univers augmente, plus cet outil est lent, plus il devient difficile pour les développeurs de travailler efficacement. Les développeurs doivent donc adapter leur outil à l’OCS serveur.Support de Squadron 42
Squadron 42 utilisera aussi l’OCS serveur, avec le client et le serveur tournant sur l’ordinateur du joueur. Des adaptation mineures seront nécessaires.
Le mot de la fin par le rédacteur
Cet article est long, mais il montre bien l'esprit long terme dans lequel est construit Star Citizen. Les développeurs savent où ils veulent aller et mettent les moyens pour le faire. Les fondations du jeu sont presque terminées et ont l'air solides. Si le gameplay construit par dessus est à la hauteur des fondations, le jeu sera d'un très haut niveau.


<div class="c-article "
data-id="333399"
data-type="article"
>









Star Citizen : Les 12 défis pour la sortie du jeu



Lors de la CitizenCon 2018, Chris Roberts a présenté une stratégie de lancement dite "Soft Launch", c'est à dire qu'une fois un certain nombre de défis techniques relevés, il n'y aura plus de remises à zéro ("wipes") et le jeu, au début minimal, se construira étape par étape à un rythme trimestriel.

Parcourez les autres

Actualités