SWTOR – Optimisation des performances
Hugo B., le créateur de LogAnalyzer, s'est interrogé sur les performances des jeux suite aux nombreuses questions posées par rapport à la 1.2.7b et plus spécifiquement, il cherche à répondre à la question : à quoi sont liés les problèmes de performance du jeu ?
L’optimisation des performances d’un programme est un sujet qui peut être assez complexe. Afin d’essayer d’être le plus clair possible, je vais développer ce sujet dans deux parties : tout d’abord une partie où il s’agira de décrire grossièrement l’architecture du jeu (à partir de ce que l’on peut deviner) ; dans un second temps je tenterai d’expliquer pourquoi certains problèmes se présentent, et les solutions qui peuvent être apportées avec leurs avantages et inconvénients.
Architecture de SW:TOR
Comme vous le savez tous probablement, SW:TOR est une application dite Client-Serveur. C’est à dire qu’il y a deux applications : une installée chez le client et une qui va interagir avec l’application côté serveur.
Une question qui se pose alors est : qu’est-ce qui est réalisé coté client, et qu’est traité côté serveur ? Mais tout d’abord quelques bases d’architecture logicielle.
Une application est un groupe de données et de traitements. On distingue dans ces cas-là souvent différents types de traitements, et pour diverses raisons que je n’expliquerai pas ici (parce que ça n’intéresse principalement que des développeurs 😉 ), on applique souvent un modèle aux traitements d’une application appelé “MVC”.
MVC signifie Modèle, Vue et Contrôleur. Le principe du Modèle est de manipuler les données, c’est à dire de gérer les opérations de lecture, écriture et surtout modification. Les vues sont les différents affichages de l’application : en tant qu’utilisateur vous ne voyez que le résultat d’une ou de plusieurs vues. Enfin, le contrôleur a pour rôle d’organiser les échanges entre vues et modèles.
Revenons au cas de SW:TOR : l’application est donc client-serveur, et les différents éléments Modèle Vue et Contrôleur sont répartis entre le client et le serveur.
Le client va ici héberger l’ensemble des vues, et une partie du contrôleur, avec un tout petit peu de Modèle (pour ce qui s’agit de gérer les préférences de l’application par exemple). Le serveur lui va s’occuper d’un tout petit peu de vues (pour les échanges avec le client), de contrôleur mais principalement du modèle. C’est en effet côté serveur que sont stockées l’ensemble des données du jeu (personnages, guildes, objets, …).
J’espère que je ne vous ai pas perdus ! Si c’est le cas, le point à retenir est que le serveur traite et stocke les données et le client gère l’affichage.
Quelles sont alors les échanges qui ont lieu entre le client et le serveur ? Il faut distinguer deux types d’échanges :
- L’échange dit évènementiel : un événement s’est produit, ce qui mène à un échange de données
- L’échange dit régulier : c’est un échange qui a lieu toutes les x secondes/minutes par exemple.
Un exemple d’échange régulier est la vérification de la présence de l’utilisateur en ligne. Imaginons que le chat de l’utilisateur ait violemment arraché le câble Ethernet de celui-ci alors qu’il était connecté au jeu. L’utilisateur ne peut plus être connecté, mais le client n’a pas pu prévenir le serveur de la déconnexion (fatalement, puisqu’il a plus de câble l’info peut pas passer). Le fait qu’un message régulier doive être envoyé entre le client et le serveur pour vérifier la connexion du client ou du serveur fait que lorsque le serveur ne recevra plus ce message de la part du client, il pourra alors savoir que le client est déconnecté.
Concernant l’échange événementiel, il s’agit par exemple du déplacement d’un personnage. Lorsque je fais avancer mon personnage sur mon client, l’information de déplacement est envoyée au serveur.
Pourquoi est-ce que je vous explique tout ça ? D’une part parce que c’est assez intéressant à connaître à mon sens (enfin ça peut vous barber, mais moi je trouve ça sympa 😛 ) ; d’autre part parce que ces bases vont me servir à expliquer comment on va chercher à optimiser les performances de nos applications, particulièrement dans le cas de SW:TOR.
Les performances sur SW:TOR
Par problèmes de performance on pense la plupart du temps à ceux qui touchent les utilisateurs de plein fouet : les FPS, les saccades, etc. En somme, on pense aux problèmes de la flotte et aux problèmes d’Ilum.
Alors pourquoi ces problèmes apparaissent quand un grand nombre de joueurs sont présents dans la même zone ? Eh bien penchons-nous sur le fonctionnement d’une rencontre d’un autre joueur.
Lorsque l’utilisateur arrive dans une zone où il n’est pas seul, il faut que le client puisse afficher le personnage. Pour cela, il a besoin des informations de rendu (l’ensemble des éléments configurés à la création de votre personnage, ça prend pas énormément de place sur le réseau puisque le client connait les rendus associés aux valeurs de configuration) qui lui seront envoyées par le serveur. De plus, à chaque événement émis par l’autre personnage (notamment un mouvement, mais aussi le lancement d’une capacité, …), il faudra rendre l’action correspondante.
Le client y arrive très bien pour un personnage, mais commence visiblement a rencontrer des difficultés (selon les ordinateurs) pour en afficher un plus grand nombre, d’autant plus si ceux-ci sont hautement actifs (par exemple sur Ilum).
Le processus d’optimisation consiste en identifier les goulots d’étranglement (bottleneck) et à les supprimer de façon à fluidifier l’application petit à petit. Dans notre cas, nous avons deux points d’action : les performances sur le rendu d’un personnage, ou encore le nombre de personnages affichés. Le patch 1.2.7b de SW:TOR indiquait comme modification notamment que “le nombre maximum des joueurs pouvant se trouver simultanément sur les flottes de l’Empire et de la République a été réduit.” Cette modification a probablement été mise en place car c’est le point d’action le plus rapide (il s’agit simplement de modifier la configuration).
En effet, modifier le rendu d’un personnage prendra plus de temps, car il sera nécessaire de rentrer plus dans les détails afin de localiser les bottlenecks et de les corriger un à un (en effet, la plupart du temps, les bottlenecks se cachent les uns les autres).
Maintenant, concernant la partie “développement” proprement dite, nous avons plusieurs niveaux d’actions pour l’optimisation :
- Conception : il s’agit de l’organisation de l’application en elle-même et des configurations ; c’est sur ce niveau que l’on a agit notamment pour le patch 1.2.7b
- Code source : il s’agit là de traquer les bugs qui impactent la performance ou encore d’améliorer les algorithmes.
- Compilation / Assembleur : Ce sont les étapes qui transforment le code source en programme. Le processus de traduction peut ne pas être parfait, c’est pourquoi il peut parfois être intéressant de regarder de ce côté-là. Aujourd’hui cette étape est considérée comme de l’optimisation “fine”, dans le sens où les programmes permettant de faire cette traduction sont particulièrement travaillés dans l’objectif d’améliorer les performances.
Les éléments de conception et de code source sont longs à optimiser. En effet, ce processus requiert parfois de repenser une grande partie du programme, et impacte beaucoup d’autres éléments. L’application de l’optimisation nécessite donc dans ces cas-là un grand nombre de tests afin de vérifier que le comportement attendu est toujours présent. Et je le rappelle, une fois un premier point réglé, il faudra passer au suivant, puis au suivant, puis ainsi de suite, et ce sans fin (il est toujours possible d’optimiser un programme, c’est aux concepteurs de décider quand s’arrêter).
La solution adoptée par BioWare de limiter le nombre de joueurs dans une zone peut donc sembler facile, cependant c’est la solution la plus rapide à mettre en place. Le processus d’optimisation est long, très long, et surtout se fait pas à pas. Cela viendra au fur et à mesure de l’avancement du jeu, mais ne portera pas de résultats flagrants d’un seul coup (à moins qu’un bottleneck particulièrement important soit levé). Une fois les résultats satisfaisants obtenus, il sera possible de lever la limitation tout aussi rapidement.
Hugo B.