Comment lanalyse de code statique aide dans lindustrie GameDev

( 4 décembre 2020)

Lindustrie du jeu évolue constamment et se développe plus vite quune balle rapide. Parallèlement à la croissance de lindustrie, la complexité du développement augmente également: la base de code augmente et le nombre de bogues augmente également. Par conséquent, les projets de jeux modernes doivent accorder une attention particulière à la qualité du code. Aujourdhui, nous allons couvrir lune des façons de rendre votre code plus décent, qui est lanalyse statique, ainsi que la façon dont PVS-Studio aide dans la pratique au développement de projets de jeu de différentes tailles.

« La chose la plus importante que jai faite en tant que programmeur ces dernières années est pour poursuivre agressivement lanalyse de code statique. Le changement de mentalité concernant la façon dont je perçois la fiabilité des logiciels et la qualité du code est encore plus précieux que les centaines de bogues graves que jai évités. »- John Carmack

Nous travaillons avec les principaux développeurs de jeux depuis de nombreuses années et pendant ce temps, nous avons réussi à faire beaucoup de choses intéressantes et utiles pour lindustrie du jeu. Ce n’est pas vraiment une surprise, étant donné la liste de nos clients de l’industrie du jeu vidéo. Nous soutenons activement nos clients: pour intégrer PVS-Studio dans leur propre processus de développement, corriger les erreurs trouvées par lanalyseur et même créer des fonctionnalités personnalisées spéciales.

De plus, nous faisons beaucoup de développement indépendant de lanalyseur dans la direction GameDev, ainsi que la promotion de PVS-Studio, en informant les gens des erreurs intéressantes quil a trouvées dans divers jeux vidéo.

Bien sûr, nous avons des histoires intéressantes à raconter. Cet article couvrira plusieurs de ces cas.

PVS-Studio et Unity

Lune des façons dont nous faisons la promotion de notre produit consiste à rédiger des articles sur la vérification des projets ouverts. Tout le monde profite de ces articles: un lecteur a la chance de découvrir des erreurs inhabituelles dans un projet familier et dapprendre quelque chose de nouveau. Quant à léquipe PVS-Studio, nous avons lopportunité de montrer le travail effectué sur du code réel, afin que les développeurs de projets puissent connaître les erreurs et les corriger à lavance.

Notre première grande connaissance de Unity a eu lieu en 2016, lorsque les développeurs de ce moteur de jeu ont ouvert le code source de plusieurs composants, bibliothèques et démos dans leur référentiel officiel. Pas étonnant, nous navons pas pu passer par un cas aussi séduisant et avons voulu écrire un article sur la vérification du code affiché.

Ensuite, nous avons découvert que le code Unity3D (à lépoque le moteur sappelait comme ça) était de très haute qualité. Mais nous avons tout de même pu y trouver de nombreuses erreurs graves. Il y en avait suffisamment pour écrire un article .

Deux ans plus tard, une autre chose sest produite: les développeurs Unity ont ouvert le code du moteur et léditeur lui-même. Et tout comme la fois précédente, nous navons pas pu en prendre note et avons vérifié le code source du moteur. Et ce nétait pas pour rien – nous avons également trouvé un tas de défauts captivants.

Dans le même temps, nos intentions vont bien au-delà de la simple écriture des articles. Nous continuons à travailler sur PVS-Studio, et GameDev est lun des domaines les plus importants pour notre développement. Par conséquent, nous voulons que les développeurs de jeux Unity puissent obtenir la meilleure analyse possible de leurs projets.

Lune des étapes pour améliorer la qualité de lanalyse des projets Unity consistait à écrire des annotations pour les méthodes définies dans lAPI Unity Scripting .

Lannotation de méthode est un mécanisme spécial utilisé dans PVS-Studio. Il permet à un utilisateur de fournir à lanalyseur toutes les informations nécessaires sur une méthode particulière. Elle est écrite dans un code spécial par les développeurs de lanalyseur eux-mêmes (cest-à-dire par nous).

Ces informations peuvent être de toutes sortes. Par exemple: comment la méthode peut affecter les paramètres qui lui sont passés, si elle peut allouer de la mémoire et si elle renvoie une valeur qui doit être gérée. Ainsi, lannotation permet à lanalyseur de mieux comprendre la logique des méthodes, lui permettant de détecter des erreurs nouvelles et plus complexes.

Nous avons déjà écrit un grand nombre dannotations différentes (par exemple, pour les méthodes du système namespace), et nous avons été heureux dy ajouter des annotations de méthode de lAPI Unity Scripting.

Nous avons commencé à étendre la liste des annotations avec une évaluation. Combien de méthodes y a-t-il au total? Lesquels doivent être annotés en premier? Il y avait beaucoup de méthodes au total, nous avons donc décidé de commencer par annoter les plus fréquemment utilisées.

Cest ainsi que nous recherchions des méthodes populaires: dabord, nous avons rassemblé un pool de projets de GitHub qui utilisent les fonctionnalités dUnity, puis nous avons utilisé un utilitaire auto-écrit (basé sur Roslyn) pour calculer les appels à les méthodes qui nous intéressaient. En conséquence, nous avons obtenu une liste de classes dont les méthodes étaient les plus utilisées:

  • UnityEngine.Vector3
  • UnityEngine.Mathf
  • UnityEngine.Debug
  • UnityEngine.GameObject
  • UnityEngine.Material
  • UnityEditor.EditorGUILayout
  • UnityEngine.Component
  • UnityEngine.Object
  • UnityEngine.GUILayout
  • UnityEngine.Quaternion

Ensuite, il est resté pour annoter les méthodes de ces classes. Nous avons créé un projet de test et fouillé dans la documentation pour obtenir autant dinformations que possible sur ces méthodes. Par exemple, nous avons essayé de passer null comme divers arguments pour voir comment le programme se comporterait.

Au cours de ces vérifications, nous découvrions de temps en temps des informations non documentées intéressantes. Nous avons même trouvé quelques bugs notables dans le moteur. Par exemple, lorsque nous exécutons le code suivant:

MeshRenderer renderer = cube.GetComponent();
Material m = renderer.material;
List<int> outNames = null;
m.GetTexturePropertyNameIDs(outNames);

léditeur Unity lui-même plante (au moins dans la version 2019.3.10f1). Bien sûr, il est peu probable que quiconque écrira un tel code. Pourtant, le fait que léditeur Unity puisse être mis en panne en exécutant un tel script est curieux.

Nous avons donc fait écrire les annotations. Après avoir exécuté lanalyse, nous avons immédiatement trouvé de nouveaux déclenchements. Par exemple, lanalyseur a détecté un appel étrange à la méthode GetComponent :

void OnEnable()
{
GameObject uiManager = GameObject.Find("UIRoot"); if (uiManager)
{
uiManager.GetComponent();
}
}

Avertissement de lanalyseur: V3010 La valeur de retour de la fonction GetComponent doit être utilisée. – ADDITIONAL IN CURRENT UIEditorWindow.cs 22

La méthode GetComponent implique le retour dune valeur spécifique même due à son nom. Il est logique de supposer que cette valeur doit être utilisée dune manière ou dune autre. Désormais, grâce à la nouvelle annotation, lanalyseur sait quun tel appel «sans assistance» à cette méthode peut indiquer une erreur logique et en avertit.

Ce nest pas le seul avertissement apparu dans lensemble de notre tester des projets après avoir ajouté de nouvelles annotations. Je ne citerai pas le reste, pour ne pas rendre cet article trop volumineux. Lessentiel est que maintenant le développement de projets Unity à laide de PVS-Studio vous permet décrire du code beaucoup plus sûr et plus propre sans bogues.

Si vous souhaitez en savoir plus sur notre travail avec les annotations pour les méthodes Unity, voici larticle: Comment lanalyseur PVS-Studio a commencé à trouver encore plus derreurs dans les projets Unity .

Unreal Engine 4

Quand, en 2014, les développeurs dUnreal Le moteur 4 a ouvert le code source du moteur, nous navons tout simplement pas pu passer outre ce projet et avons également écrit un article à ce sujet. Les développeurs de moteurs ont aimé larticle et ont corrigé les erreurs que nous avons trouvées. Mais cela ne nous a pas suffi, et nous avons décidé dessayer de vendre la licence de notre analyseur à Epic Games.

Epic Games souhaitait améliorer son moteur avec PVS-Studio, nous nous sommes donc mis daccord sur ce qui suit : nous corrigeons le code Unreal Engine nous-mêmes afin que lanalyseur némette aucun avertissement, et les gars dEpic Games achètent notre licence et nous récompensent en plus pour le travail effectué.

Pourquoi tous les avertissements devaient être fixé? Le fait est que lon peut tirer le meilleur parti de lanalyse statique en corrigeant les erreurs correctement lorsquelles apparaissent . Lorsque vous vérifiez votre projet pour la première fois, vous recevez généralement plusieurs centaines (et parfois des milliers) davertissements. Parmi tous ces déclenchements danalyseur, il est facile de perdre les avertissements émis pour le code nouvellement écrit.

À première vue, ce problème peut être résolu assez facilement: il vous suffit de vous asseoir et de parcourir lintégralité du rapport , corrigeant progressivement les erreurs. Cependant, bien que cette méthode soit plus intuitive, elle peut prendre du temps. Il est beaucoup plus pratique et plus rapide d’utiliser les fichiers de suppression.

Les fichiers de suppression sont une fonction spéciale de PVS-Studio qui vous permet de masquer avertissements de lanalyseur dans un fichier spécial. Cependant, les avertissements masqués napparaîtront pas dans les journaux suivants: vous pouvez les afficher séparément.

Après avoir eu de nombreux déclenchements après la première vérification, vous pouvez ajouter tous les avertissements détectés au fichier de suppression en quelques clics, et vous obtiendrez un journal propre sans une seule entrée après la prochaine vérification.

Maintenant que les anciens avertissements ne sont plus inclus dans le journal, vous pouvez facilement détecter un nouvel avertissement immédiatement quand il apparaît. Voici lordre des actions: écrivez le code -> vérifiez-le avec lanalyseur -> repérez un nouvel avertissement -> corrigez lerreur. Cest ainsi que vous tirerez le meilleur parti de lutilisation de lanalyseur.

En même temps, noubliez pas les avertissements dans le fichier de suppression: ils peuvent toujours contenir des avertissements sur des erreurs et des vulnérabilités majeures, comme auparavant. Par conséquent, il faut revenir à ces avertissements et réduire leur nombre régulièrement.

Pas de doute, ce scénario est pratique, mais les développeurs dEpic Games voulaient que leur code soit corrigé immédiatement, ils ont donc passé le tâche à nous.

Et nous nous sommes mis au travail. Après avoir vérifié le code du projet, nous avons trouvé 1821 avertissements de Level_1 et Level_2. Lanalyse dun si grand volume davertissements nécessite un travail sérieux, et pour faciliter tout ce processus, nous avons mis en place une analyse continue du code sur notre serveur CI.

Cela ressemblait à ceci: chaque nuit sur notre serveur, le version dUnreal Engine 4 a été créée, et immédiatement après la construction, lanalyse a été automatiquement lancée. Ainsi, lorsque nos gars venaient travailler le matin, ils avaient toujours un nouveau rapport de lanalyseur, ce qui les aidait à suivre les progrès de lélimination des avertissements. De plus, ce système nous a permis de vérifier la stabilité de la compilation à tout moment en lexécutant manuellement sur le serveur.

Lensemble du processus nous a pris 17 jours ouvrables. Le calendrier de correction des erreurs était le suivant:

En fait, ce calendrier ne reflète pas pleinement notre travail. Après avoir corrigé tous les avertissements, nous avons attendu encore deux jours pour quils acceptent nos dernières demandes dextraction. Pendant tout ce temps, la dernière version dUnreal Engine était automatiquement vérifiée, qui, à son tour, continuait dêtre mise à jour avec un nouveau code. Alors, que pensez-vous quil sest passé? Pendant ces deux jours, PVS-Studio a trouvé quatre autres erreurs dans le code! Lun dentre eux était crucial et pouvait potentiellement conduire à un comportement indéfini.

Bien sûr, nous avons également corrigé ces erreurs. À ce stade, les développeurs dUnreal Engine navaient plus quune chose: configurer lanalyse automatique à leur place, comme nous lavons fait. À partir de ce moment, ils ont commencé à voir tous les jours des avertissements émis pour le code quils venaient décrire. Cela leur a permis de corriger les erreurs dans le code dès leur apparition – au tout début du développement .

Pour en savoir plus sur la façon dont nous avons travaillé sur le code Unreal Engine, consultez le blog officiel Unreal Engine ou sur notre site Web .

Analyse de divers jeux

Ai-je mentionné que nous vérifier divers projets ouverts et écrire des articles à leur sujet? Donc, nous avons maintenant beaucoup darticles similaires sur les projets de jeux! Nous avons écrit sur des jeux comme VVVVVV , Space Engineers , Command & Conque r, osu! et même (un article très ancien) Doom 3 . Nous avons également compilé le top 10 des bogues logiciels les plus intéressants de lindustrie du jeu vidéo.

Donc, nous avons probablement vérifié la plupart des moteurs open source bien connus. Outre Unity et Unreal Engine 4, des projets tels que Godot , Bullet , Amazon Lumberyard , Cry Engine V et bien dautres sont passés sous nos yeux.

La meilleure partie de tout cela est que la plupart des bogues que nous avons décrits ont été corrigés plus tard par les développeurs du projet eux-mêmes. Cest agréable de sentir que loutil que vous développez apporte des avantages réels, visibles et tangibles au monde.

Vous pouvez consulter une liste de tous nos articles liés au développement de jeux vidéo dune manière ou dune autre sur un page spéciale de notre blog.

Conclusion

À ce stade, mon article se termine. Je vous souhaite un code propre et fonctionnant correctement, sans bogues ni erreurs!

Le sujet de lanalyse statique vous intéresse? Vous voulez vérifier votre projet pour les erreurs? Essayez PVS-Studio .

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *