Crusader Kings 3 : Performance et IA

Voici la traduction du 36ème carnet de développement de CK3, le prochain jeu de Paradox Development Studio, consacré à la performance et à l'IA.


Bon après-midi à tous,

Je suis Magne "Meneth" Skjæran, l'un des programmeurs de Crusader Kings 3. Vous me connaissez peut-être grâce à mon travail sur CK2 et les wikis Paradox. Mon travail sur la performance et l'IA dans CK2 est particulièrement pertinent aujourd'hui. Aujourd'hui, je vais vous parler de la façon dont nous avons travaillé sur ces deux domaines dans CK3 pour garantir une meilleure expérience de jeu que dans CK2.

Performance

Commençons par parler de la performance.
Tout au long du cycle de vie de CK2, nous avons apporté de nombreuses améliorations aux performances, et lorsque Holy Fury est sorti, c'était le meilleur qu'il ait jamais été. La version d'aujourd'hui ressemble à de la mélasse par rapport aux performances du jeu après sa longue et vénérable vie.
CK2 s'est distingué des autres jeux de Paradox Development Studio en termes de performances, ce qui signifie que nous avons beaucoup à faire. C'est pourquoi la performance a été une priorité tout au long du développement de CK3, et surtout à l'approche de sa sortie. Notre approche d'un certain nombre de systèmes techniques diffère de celle du CK2 pour des raisons de performances, ce qui nous a permis d'obtenir d'excellents résultats.

Les deux systèmes qui diffèrent le plus de CK2 pour des raisons de performances sont le threading et le rendu. Les deux sont fortement imbriqués, à tel point qu'on ne peut pas vraiment parler de l'un sans parler de l'autre.
Dans CK2, notre approche était assez simple. Le jeu dans son ensemble était structuré autour du thread principal. La tâche principale du thread principal était de mettre à jour l'état du jeu afin qu'il progresse. Afin de rendre les images pour que les utilisateurs puissent voir ce qui se passe, il arrêtait périodiquement la mise à jour de l'état du jeu pour faire une image à la place. Le rendu prendrait alors entièrement le relais jusqu'à la fin de l'image.
Lors des mises à jour de l'état de jeu, il effectue un grand nombre d'opérations différentes. La façon dont nous avons structuré cela dans CK2 était largement basée sur les personnages eux-mêmes. La mise à jour quotidienne des personnages était divisée en une poignée de segments avec différentes règles de parallélisation. Par exemple, pendant une partie, il serait illégal pour un personnage de vérifier toute information appartenant à un autre personnage. Pendant une autre, il serait illégal pour lui de modifier toute information qu'il possède et qui est visible par les autres personnages. Ces restrictions signifient que ces mises à jour pourraient être effectuées en parallèle ; chaque thread faisant la même section pour un personnage différent. En pratique, cela a fonctionné raisonnablement bien ; CK2 est un jeu fortement parallèle et a connu des gains de vitesse importants grâce à une parallélisation accrue. Des configurations similaires ont également été appliquées à d'autres objets, comme les titres, les intrigues, etc.
Cependant, il y avait aussi des inconvénients importants. Le plus important étant les différentes règles sur ce que le programmeur peut et ne peut pas faire à chaque mise à jour. La violation de l'une de ces règles entraîne généralement un OOS, rompant ainsi l'expérience multijoueur. Parfois, cela pouvait même faire planter le jeu. Le fait de devoir traiter chaque personnage du jeu et la plupart des vérifications se traduisaient par "nous n'avons pas besoin de faire cette partie de la mise à jour", ce qui entraînait également une surcharge importante.

Ainsi, dans CK3, nous avons entièrement remplacé ce système. Nous sommes passés d'un parallélisme au niveau de l'objet à un parallélisme au niveau du système. Maintenant, au lieu de traiter plusieurs personnages en même temps, nous traitons plusieurs systèmes différents. Par exemple, nous pourrions mettre à jour le système de complot en même temps que le système d'opinion. Cela nous a permis de simplifier massivement les règles de ce que vous pouvez et ne pouvez pas faire : maintenant, pendant le parallélisme, la seule limitation est que nous ne pouvons pas modifier les informations visibles ; nous devons plutôt stocker les modifications que nous voulons faire et les appliquer un peu plus tard dans la série. La simplification des règles signifie que moins de bogues sont introduits, en particulier les OOS. Et il est généralement plus facile d'identifier ce qui peut être mis en parallèle qu'avec CK2, ce qui permet de travailler davantage en parallèle qu'auparavant.



[Un tableau du temps passé sur la plupart des mises à jour parallèles]

De plus, cela fonctionne très bien avec la nouvelle approche de CK3 en matière de rendu. Dans CK3, le rendu est un thread séparé plutôt que d'être effectué sur le thread principal. Il doit encore se synchroniser avec le thread principal, car nous ne pouvons pas vérifier un objet qui est en train d'être modifié. Nous avons donc un système de verrouillage ; lorsque le thread de rendu doit accéder à l'état de jeu, l'état de jeu n'est pas autorisé à se modifier, et lorsque l'état de jeu se modifie, le thread de rendu doit attendre jusqu'à ce qu'il puisse accéder à l'état de jeu. Comme pour CK2, l'état de jeu vérifie périodiquement, lors de sa mise à jour, si le thread de rendu a besoin d'un accès, auquel cas il perd le contrôle pendant un court instant. Mais la grande différence est qu'une partie importante du travail effectué sur le thread de rendu ne nécessite pas d'accès à l'état de jeu, et peut donc être effectuée parallèlement à la mise à jour de l'état de jeu.
Et vous souvenez-vous de la règle que j'ai mentionnée plus tôt ? Les mises à jour parallèles de l'état de jeu ne sont pas autorisées à changer d'état visible, donc pendant ces mises à jour, il est sûr de mettre à jour le thread de rendu. Donc, dans l'ensemble, la section où le processus de rendu doit attendre est assez petite, et elle finit par faire la plupart de son travail en même temps que la plate-forme de jeu.
Maintenant, il nous reste encore un certain parallélisme au niveau de l'objet, notamment l'IA. Mais l'IA dans CK3 est configurée pour ne jamais changer directement l'état de jeu, donc le rendu peut continuer pendant que l'IA trouve ce qu'il faut faire.

Dans l'ensemble, ces changements ont permis à CK3 d'avoir une meilleure utilisation des threads que CK2, un framerate plus stable, et qu'il est plus difficile pour les programmeurs de faire des erreurs de threads qui conduisent à des bugs, des OOS et des plantages.

Pour un point de comparaison, j'ai fait un test rapide sur ma machine en comparant CK2 et CK3. J'ai simplement laissé le jeu tourner à plein régime pendant une minute, et j'ai comparé la fréquence d'images et la progression du jeu. Les deux jeux sont allés aussi loin l'un que l'autre ; de septembre 1066 à avril 1069. Cependant, la fréquence d'images de CK3 était beaucoup plus élevée et plus stable que celle de CK2. Si l'on considère les graphiques bien meilleurs de CK3, ces résultats sont exactement ce que j'espérais.

Regardons la différence que fait le threading. J'ai mis en place un test simple ; j'ai fait tourner le jeu pendant une minute sur ma machine à la vitesse maximale, d'abord avec le threading complètement activé, puis avec le threading désactivé. Vous pouvez le voir par vous-même ci-dessous. La gauche est avec le threading, la droite est sans :





La ligne rouge que vous voyez dans la vidéo correspond au temps entre chaque image. Pour 60 FPS, elle doit être égale ou inférieure à la ligne horizontale verte.
Comme vous le voyez, la différence est stupéfiante. Sans threading, la cadence est épouvantable et le jeu progresse beaucoup plus lentement. Avec le threading , le jeu progresse de 958 jours, alors que sans threading, il ne progresse que de 546 jours. C'est-à-dire qu'avec le threading, le jeu est 75% plus rapide, et avec un taux de rafraîchissement bien meilleur.
La machine sur laquelle je l'utilise est mon PC personnel, qui, au moment de l'enregistrement, avait un i7 4770K, un GTX 1080 et 16 Go de RAM à 2400 MHz, fonctionnant avec les paramètres graphiques les plus élevés. Le CPU et la RAM sont tous deux assez anciens et, à ce jour, bien moins performants que les modèles plus récents, bien que le GPU soit encore solide. La vitesse maximale est suffisamment élevée pour que je ne l'utilise presque jamais en jeu normal, mais plutôt en utilisant les vitesses 3 et 4.

Donc, au-delà de ce qui a été mentionné, comment travaillons-nous avec les performances de CK3 ? Nous consacrons périodiquement du temps à veiller à ce que tout nouveau problème de performance soit traité et à étudier les possibilités d'amélioration. Cela implique souvent d'augmenter le threading, ou de retravailler les systèmes pour être plus performant. Cependant, l'une de mes méthodes préférées pour rendre le jeu plus rapide est de modifier légèrement la conception afin d'éviter des calculs coûteux qui n'affecteront pas le joueur. Pour prendre un exemple, nous actualisons chaque jour l'avancement des tâches du conseil des joueurs. Mais pour l'IA, nous ne le faisons qu'une fois par mois. Il est peu probable que le joueur remarque un jour la différence, mais de cette façon nous réduisons le coût de ces mises à jour à 1/30 de ce qu'elles seraient autrement. Des optimisations comme celle-ci sont partout dans CK3 (et dans une certaine mesure dans CK2) ; il y a beaucoup de petits raccourcis qui peuvent être faits et qui ont un impact énorme sur les performances mais peu ou pas d'impact sur l'expérience du joueur.

IA

Il est maintenant temps de parler un peu de l'IA également.
La personne qui a été responsable de l'IA pour la plus grande partie du développement de CK3 est Niklas "Captain Gars" Strid, mais il est actuellement en congé parental. Depuis environ un an, je l'aide à développer l'IA, et maintenant, en son absence, c'est moi qui en ai l'entière responsabilité.
Comme je n'ai pas conçu l'IA, ce sera plus court que si Niklas était là pour l'écrire, mais je vais vous présenter quelques idées de base sur la façon dont nous avons géré l'IA dans CK3.

Notre principal objectif avec l'IA a été de rendre le jeu plus amusant pour le joueur. Cela comporte plusieurs aspects :
  • Elle devrait offrir un certain niveau de défi, car le déferlement de la vitesse dès le départ n'est pas amusant
  • Elle devrait éviter de faire des choses qui sont frustrantes, même si cela la rendrait plus "intelligente".
  • Elle doit se sentir comme un acteur plausible dans un monde médiéval

Ces objectifs se chevauchent tous et, dans certains cas, s'opposent les uns aux autres. Par exemple, éviter la frustration permet d'obtenir une IA un peu moins difficile, mais c'est souvent un sacrifice du sens.

L'un des plus grands changements structurels de l'IA de CK3 est la façon dont elle traite ses militaires. Dans CK2, s'il y avait plusieurs IA du même côté dans une guerre, elles agiraient essentiellement indépendamment les unes des autres avec quelques systèmes de coordination. Cela fonctionnait généralement bien, mais parfois cela conduisait à un manque de coordination entre les alliés et l'IA prenant des décisions bizarres.
Dans CK3, nous avons conçu le système de A à Z pour gérer plusieurs IA du même côté. Au lieu que chaque IA commande ses propres troupes, elle les assigne à un coordinateur de guerre qui prend toutes les décisions ; la prise de décision individuelle est juste ce que les troupes doivent assigner (ce qui entre en jeu s'il y a plus d'une guerre à laquelle elles pourraient participer).
Les IA ont donc tendance à agir de manière beaucoup plus coordonnée.
Cependant, cela ne concerne pas la coordination avec le joueur. L'approche de CK2 a finalement consisté à introduire un système d'ordre d'IA dans lequel vous dites simplement à l'IA ce qu'elle doit faire. Nous n'avons pas ce système pour le moment dans CK3, mais l'IA se concentre toujours sur l'assistance au joueur. En général, l'IA essaie de garder ses armées très près du joueur et de l'aider dans les batailles, même si celles-ci sont perdues avec son aide. Un système d'ordre de l'IA comme dans CK2 pourrait encore améliorer cela, mais l'écart est beaucoup plus petit que dans CK2, donc nous avons décidé que ce ne serait pas une priorité pour la sortie. De plus, l'existence du système de commande dans le CK2 a considérablement compliqué le code de l'IA, rendant son développement plus difficile, donc il y a un compromis à prendre en compte en ce qui concerne le nombre de bugs qu'il introduira, et le ralentissement du développement de l'IA qu'il causera probablement.

Cela couvre donc "fournir un certain niveau de défi", mais qu'en est-il d'éviter la frustration ? Il y a beaucoup de petites choses ici et là conçues pour cela, mais parlons de quelques exemples concrets. Dans CK3, l'IA a un système que j'ai tendance à appeler "se tenir debout et se battre". Si le joueur (ou tout autre ennemi) se trouve à proximité de son armée, la battra, et qu'il n'y a pas de réel espoir de gagner la guerre car toutes ses troupes sont déjà rassemblées, alors au lieu de s'enfuir, l'IA trouvera un endroit défensif à proximité et y attendra jusqu'à un mois que l'ennemi l'anéantisse. De cette façon, au lieu de faire traîner sa disparition, elle prend une dernière position dans un bon endroit. Le résultat est que le joueur n'a pas besoin de poursuivre des armées autant que dans CK2, mais que cela tend à n'intervenir que pour les guerres que le joueur va clairement gagner de toute façon.
De même, le game design lui-même est souvent créé en tenant compte, au moins partiellement, de l'IA. Nous avons déjà parlé de la mécanique des forts, mais pour résumer, marcher en profondeur en territoire ennemi sans avoir à assiéger d'abord va tuer la plupart de vos troupes. L'IA ne le fera donc pratiquement jamais, donc quand vous êtes derrière vos propres lignes, vous avez le temps de vous regrouper et de trouver quoi faire. De même, il n'y a pas de tentation à essayer de poursuivre l'IA profondément dans son territoire. Cela permet de se concentrer davantage sur la guerre de siège, ce qui est très approprié pour l'époque.
Cela contribue à tous les objectifs que j'ai mentionnés : L'IA finit par être meilleure parce qu'il y a moins d'options disponibles, donc nous pourrions la rendre plus intelligente en choisissant entre ces options. Le joueur est moins frustré. Et cela met en valeur un aspect historique de l'époque, tout en évitant les poursuites idiotes à l'autre bout du monde.

On a beaucoup parlé de l'IA militaire. Qu'en est-il du reste ? L'approche générale est assez similaire à celle de CK2, bien que reconstruite à partir de zéro. L'IA vérifiera périodiquement diverses actions possibles et les prendra si elles ont un sens. Il y a un certain aléatoire, et la personnalité de l'IA affecte une variété d'actions, pour s'assurer que le jeu semble vivant plutôt que déterministe.
Une plus grande partie de l'IA peut être modifiée que dans le CK2, car le système d'interaction a un codage beaucoup moins dur. Il y a encore des parties qui sont codées en dur, comme les actions qui ne sont pas des interactions, mais globalement, il devrait être possible d'influencer un peu plus l'IA que dans CK2.
La réduction du codage en dur a également signifié que l'équilibrage de l'IA est plus facile pour nous que dans CK2, car un programmeur n'a pas toujours besoin d'être impliqué. Surtout lorsque nous recevons des commentaires d'un grand nombre de joueurs après la sortie, cela et les diverses améliorations architecturales du code par rapport à CK2 devraient rendre l'itération sur l'IA plus facile qu'auparavant.
Une grande partie de ce que font les autres personnages est également gérée par des événements et ainsi de suite, dans une plus grande mesure que dans CK2.

D'une manière générale, l'objectif de l'IA non militaire est de faire en sorte que le monde se sente vivant. Cela a parfois nécessité des restrictions pour éviter que le joueur ne soit submergé. Par exemple, nous avons dû à de nombreuses reprises restreindre la séduction à l'encontre du joueur afin qu'il ne soit pas absolument spammé s'il se trouve à jouer l'une des rares femmes dirigeantes au début du jeu.

Dans l'ensemble, l'IA devrait à bien des égards ressembler à CK2, mais en mettant davantage l'accent sur la meilleure expérience possible pour le joueur. Après la sortie du jeu, il devrait être plus facile pour nous d'améliorer l'IA qu'elle ne l'était dans CK2.

Amélioration de PC



[Mon PC récemment mis à niveau]
Curieusement, entre le moment où j'ai écrit ce carnet de développement et celui où il devait être publié, j'ai décidé qu'il était enfin temps de mettre mon PC à niveau. J'ai remplacé mon vieux i7 4770K par un beau Ryzen 9 3900X moderne, et mes 16 Go de RAM à 2400 MHz par 32 Go de RAM à 3600 MHz.
J'ai donc réenregistré mon test d'une minute avec un threading complet, que vous pouvez voir ici :



Comme vous pouvez le voir, cela fait tourner le jeu à un niveau que je ne peux que qualifier d'injouable. En une minute, il a progressé de 1498 jours, soit 56 % de plus que mon ancien processeur. Le taux de rafraîchissement est également plus stable qu'auparavant, je suis donc assez satisfait des résultats.



[Ma nouvelle machine qui fait tourner le jeu à 1000 FPS. Mais seulement lorsque le jeu est en pause dans un coin particulier de la carte]

C'est tout pour aujourd'hui !
La semaine prochaine, nous reviendrons pour parler plus en détail du modding.

Vous pouvez discuter de ce nouveau jeu sur le forum

Carnet traduit avec l'aide de DeepL