Stellaris, carnet des développeurs n°170 : Des performances et autres problèmes techniques.

Bonjour mes amis ! Ici Moah, le responsable du développement/programmation de Stellaris. Je peux enfin vous parler de ce que vous attendez tous : combien d’ornithorynques seront dans l’extension Fédération? Après plusieurs semaines …..

Ah, apparemment, le sujet devait être plus technique. Avant de se plonger dans les méandres du code de Stellaris, je voulais vous parler de l’équilibre entre l’ajout de nouvelles mécaniques, l’amélioration des performances et la stabilité du jeu (spécifiquement en multijoueur et de ses redoutables désynchronisations de mon point de vue).

Un Équilibre délicat :

Stellaris, comme la plupart des programmes codés de cette taille, est comme un jeu de mikado ou une tour de Jenga. Chaque partie est connectée d’une certaine façon aux autres. Lorsque vous ajoutez une nouvelle mécanique, vous ajoutez des connexions. Si vous êtes rigoureux vous en ajoutez que quelques unes, si vous n’avez pas le temps, il se peut que vous en ajoutiez trop. Ceci mène généralement à ce que l’on peut appeler des fonctionnalités non désirées (les bugs). De plus, une fois les nouvelles mécaniques dans le jeu, nous avons tendance à les pousser toujours plus loin et de façon inédite, menant alors à plus de fonctionnalités non désirées.
Une fois que l’on réalise ce qui se passe, on demande plus d'attention de la part du jeu. Peut être même trop. Le jeu réalise alors des vérifications constantes et régulières afin d’éviter que les interactions non voulues n’arrivent pas, ni maintenant, ni plus tard, jamais.
Et donc une fois que vous avez résolu tous ces bugs et que le jeu vérifie tout, ce dernier est tellement rigoureux qu'il en devient un peu lent.
Alors vous supprimez quelques unes des vérifications. Vous réalisez qu’il n’y a pas besoin faire une boucle à travers la galaxie, que vous pourriez juste la réaliser pour cette petite planète. Vous allez encore plus loin et pensez “Bon je pourrais faire ce calcul toutes les trois semaines, et celui ci pourrait être conservé pour être réutilisé plus tard”.
Ainsi le jeu n’est plus aussi attentif et les bugs reviennent. Par ailleurs le stockage des données ainsi que le moment de leur réutilisation se fait différemment selon les machines. II est donc possible d’avoir des résultats complètement différents suite à un changement (un peu comme lorsque vous posez une question à un développeur, le résultat est légèrement différent si la question est posée avant ou après son café matinal).
Ce sont ces résultats “légèrement” différents qui entraînent les désynchronisations. Une corvette pourrait être construite chez le client mais pas au sein serveur à cause d’une différence de 0.0001 de ressources créée au fur et à mesure du temps qui passe.
Pour éviter ça, vous remplacez de nouveau votre algorithme “intelligent” par le bon algorithme. Vous perdez la moitié des gains de performances et de nouveaux bugs peuvent apparaître.

Et ainsi de suite.
Mais assez de ma routine matinale parlons maintenant des …

Performances :

Les fans de Stellaris sont comme des développeurs de C++ : ils ont toujours les performances à l’esprit. Pour être plus juste, ces dernières ont aussi été notre sujet de préoccupation dernièrement. Nous savons que le jeu peut mieux faire en fin de partie et spécialement avec de grandes galaxies. Avec ceci en tête, nous avons pris du temps afin d’accroître les performances de façon plus approfondie que ce nous faisons d’habitude. Nous avons pu regarder dans ce qui consomme le plus de ressources et de temps, qui est comme tout le monde le sait, la gestion des ...


Populations :

Nombreuses sont les raisons qui font que les populations consomment beaucoup de temps de traitement dans Stellaris mais la principale est leur nombre IMMENSE principalement en fin de partie. Il y en a tellement. Et elles font tellement ! Chaque population doit calculer la qualité du travail qu'elle fournit pour chaque emploi (une fois tous les sept jours). Ensuite elle doit se confronter à toutes les autres populations de la planète pour avoir l’emploi ou elle sera la plus productive. Elle doit aussi réaliser des contrôles pour savoir si elle doit changer d’éthique, éventuellement pour rejoindre une faction spécifique, pour savoir si elle est heureuse sur cette planète, etc.
Tous ces calculs sont aussi affectés par des modificateurs. Si vous vous rappelez mon carnet précédent, vous savez que les modificateurs sont la seule quantité plus nombreuse que les populations. Et chacune de ces quantités dépend de l’autre. Les calculer, c’est comme tirer sur le fil et détricoter le pull entier.

Même si nous y avons pensé, la réduction du nombre de population en jeu compensée par un doublement de la production n’est pas une vrai solution. En effet tous les ralentissement ne viennent pas que de leur nombre. En plus il aurait fallu adapter le jeu à ces nouveaux nombres ce qui requerrait des décisions que nous l’équipe en charge du code ne pouvons prendre seul et je trouve qu'il est dommage de devoir faire plier le gameplay à cause de problèmes techniques. D’un autre côté il y a toujours l’idée d’adapter les “Règles du jeu” que l’on peut retrouver dans CK2 et de faire de l’écran de partie une fête des sliders.

Fort bien mais que peut-on y faire? :

Alors tout d’abord, j’admets que j’ai été un peu étourdi à propos du “nous avons besoin de faire la distribution des tâches tous les jours parce qu’on ne sait jamais quand est ce qu’un emploi sera libre” (NdT : ce que certain mod pouvait réduire au prix d’une incompréhension lorsque l’on voulait attribuer des populations sur une tâche et que le jour de la distribution n’étant pas encore arrivé les populations restaient au chômage). C’est ainsi que certaines populations changeaient de travail tous les jours. Nous avons réexaminé cette hypothèse et maintenant la distribution des tâche ne se fera qu’à la demande. Nous avons aussi pu réécrire certaines partie du code à des fins d’optimisation (comme le marché aux esclaves ou la carte de l’opinion, des idées afin d'alléger l’interface utilisateur du marché aux esclaves en les regroupant par espèce ainsi que l’interface des notifications sont aussi à l’étude).
Certains déclencheurs devaient aussi contrôler toutes les populations d’un empire pour savoir si elles étaient esclaves, décadentes ou toutes ces particularités tel que les traits des espèces. Ces derniers ont été changés pour faire un contrôle au niveau de l’espèce entière plutôt que de chaque population individuellement. Dans le même esprit, nous avions des événements qui passaient en revu chaque vaisseau d’une flotte et ainsi les déclencheurs associés sont maintenant placés au niveau de la flotte.

Deuxièmement, l’approche du contrôle des éthiques des populations a aussi été changé (afin que la mécanique fonctionne de nouveau), cette approche concerne aussi la possibilité de rejoindre des factions ou non.

Finalement nous avons recherché (et trouvé) de nouvelles opportunités d’utiliser plus de multithreading. Ce n’est pas si évident que cela mais nous avons pu mettre en parallèle quelques tâches supplémentaires et l’allocation des threads a été retravaillée afin d’être plus réactive. Nous sommes toujours à la recherche de bonnes idées mais nous nous sommes surtout concentrés sur les populations étant donné que c’est la que nous allions le plus gagner. Le problème étant aussi que le jeu soit fondé sur les modificateurs. Presque toutes les statistiques dépendent de modificateurs et on ne sait jamais à l’avance leur état et ainsi il est difficile de mettre les calculs en parallèle. Mais il y a aussi des chaînes de dépendance, comme des populations modifiées par leur environnement planétaire lui même modifié par des statistiques liées à l’empire. Cela ne peut se faire en parallèle. De la même façon, les flottes dépendent-elles d’un système, d’un empire ou parfois de planètes? etc…

Ce n’est pas non plus impossible mais nous ne pouvons dire “ok, on arrête tout six mois le temps de réécrire le code et de changer COMPLÈTEMENT la façon dont fonctionne le jeu”. De toute façon, je ne pense pas qu’il soit nécessaire de procéder ainsi. Un usage judicieux de l’allocation des threads aide déjà beaucoup et je pense déjà à quelques autres optimisations qui obtiendraient de bon résultats avec peu de travail.

Mais assez parler, une image valant mille mots :


Cette vidéo compare les performances de la version 2.5.1 “Shelley” avec la version 2.6 “Verne'' sur une sauvegarde de la communauté qui peut être retrouvé (NdT : en source). Il y a sur la carte plus de 20 k d’unité de population. La vidéo a été enregistrée sur mon poste de travail qui contient un processeur Intel Core i7-7900X @ 3.30Ghz, avec 10 cœurs physique et 20 thread avec une carte graphique AMD R9 Fury. Vous n’aurez pas nécessairement les mêmes résultats sur votre machine. En moyenne nous avons trouvé qu’il y a une accélération de 15 à 30 pourcent en fin de partie (NdT : 600% sur la vidéo mais c’est aussi un cas extrême avec 20 k pop).
Cette sauvegarde est un cas de test idéal pour montrer les impacts de l’amélioration des calculs du côté des populations.


Qu’est ce que cette moyenne de 15%? Comment pouvez vous la calculer? :

Toutes les nuits, nous avons des androïdes synthétiques qui jouent au jeu. Le matin nous regardons jusqu’où sont-ils allés. Nous pouvons aussi voir combien d’erreurs ils ont rencontré en cours de route, à quoi ressemblait la fin de partie, si ils ont eu des désynchronisations et ainsi mettre toutes ces données en forme pour faire de jolis graphiques avec plein de couleurs. Ensuite nous détruisons les synthétiques avant qu’ils nous posent des questions sur l’âme et ce genre de chose.


Bonus :

Un de nos bêta testeur m’a demandé de poster cette image. Ci joint son commentaire :

"Basé sur un processeur i5-3570K : Le ratio de performance montre un ralentissement de 10% les cents premières années puis tout va plus vite jusqu’à 50% en 2500. Cela s’explique par un plus grand nombre de populations les cents premières années alors que les nouvelles améliorations ne sont pas encore très actives et ensuite les gains sont présents et le jeu va de plus en plus vite. C’est plus qu’impressionnant. La courbe devrait être plus linéaire et suivre le nombre croissant de populations mais les guerres et la crise de fin de jeu lui donne une tête amusante. Ainsi vers la fin c’est comme si le jeu allait deux fois plus vite qu’avant.


Pour conclure :

Même si les performances sont toujours un sujet auquel nous allouons en permanence un peu de temps, nous sommes très content d’avoir eu la chance d’y plonger vraiment. Nous espérons que ces changements allumeront autant de joie en vous que ça a été le cas pour nous et nous sommes impatient de voir vos retours. Ces derniers nous sont précieux afin d’améliorer le jeu. Mon but personnel est d’atteindre le point où les joueurs nous demanderont d’ajouter des vitesses réduites en plus comme sur CK2.

La semaine prochaine nous parlerons d’un autre changement que vous attendez tous : PLUS D'ORNITHORYNQUES ! (NdT : L’ia très certainement).

PS: La sauvegarde nous provient d’un membre inconnu de la communauté et nous serions très heureux de pouvoir la créditée si ce dernier se manifeste.


L'un des malheurs du jeu et problème important pour communauté est en passe d'être résolu, qu'en pensez vous? Par ailleurs le résumé stream de jeudi 27/02 amène quelques précisions et est disponible sur le forum.