Wie statische Code-Analyse im GameDev-Bereich hilft

image1.png


Die Spielebranche steht nicht still und entwickelt sich jeden Tag schneller und schneller. Mit dem Wachstum der Branche wächst auch die Komplexität der Entwicklung: Es gibt mehr Code und mehr Fehler. Moderne Spielprojekte erfordern daher ein besonderes Augenmerk auf die Qualität des Codes. Heute werden wir über eine Möglichkeit sprechen, Ihren Code zu verbessern - die statische Analyse sowie darüber, wie PVS-Studio in der Praxis bei der Entwicklung großer (und nicht nur) Spielprojekte hilft.



" Das Wichtigste, was ich als Programmierer in den letzten Jahren getan habe, ist, die statische Code-Analyse aggressiv zu verfolgen. Noch wertvoller als die Hunderte schwerwiegender Fehler, die ich damit verhindert habe, ist die Änderung der Einstellung bezüglich der Art und Weise, wie ich die Zuverlässigkeit und den Code von Software betrachte Qualität. "- John Carmack



Wir arbeiten seit vielen Jahren mit großen Spieleentwicklern zusammen und haben es in dieser Zeit geschafft, viele interessante und nützliche Dinge für die Spielebranche zu tun. Dies ist angesichts der Liste unserer Kunden aus der Spielebranche nicht überraschend . Wir bieten unseren Kunden aktive Unterstützung: Wir helfen ihnen, PVS-Studio in ihren eigenen Entwicklungsprozess zu integrieren, vom Analysator festgestellte Fehler zu beheben und sogar spezielle Funktionen auf Bestellung zu erstellen.



Darüber hinaus entwickeln wir den Analysator in unabhängiger Richtung in GameDev-Richtung und machen PVS-Studio bekannt, indem wir die Leute über interessante Fehler in verschiedenen Videospielen informieren.



Natürlich nicht ohne interessante Geschichten. Einige dieser Geschichten werden in diesem Artikel diskutiert.



PVS-Studio und Unity



image2.png


Wir bewerben unser Produkt unter anderem, indem wir Artikel über die Überprüfung von Open Source-Projekten schreiben. Jeder profitiert von diesen Artikeln: Der Leser kann interessante Fehler in einem vertrauten Projekt betrachten und etwas Neues für sich selbst lernen, wir haben die Möglichkeit, die Arbeit von PVS-Studio in echtem Code zu zeigen, und Projektentwickler können sich über Fehler informieren und diese im Voraus beheben.



Unsere erste ernsthafte Bekanntschaft mit Unity begann 2016, als die Entwickler dieser Spiele-Engine den Quellcode mehrerer Komponenten, Bibliotheken und Demos in ihr offizielles Repository veröffentlichten. Natürlich konnten wir an einem so "leckeren" Fall nicht vorbeikommen und wollten einen Artikel über die Überprüfung des Layouts schreiben.



Dann stellten wir fest, dass der Unity3D-Code (zu dieser Zeit wurde die Engine so genannt) von sehr hoher Qualität ist. Es gelang uns jedoch, ziemlich viele schwerwiegende Fehler beim Schreiben eines Artikels zu finden .



Zwei Jahre später ereignete sich ein weiteres Ereignis - diesmal veröffentlichten die Unity-Entwickler den Code der Engine selbst und des Editors, um den Zugriff zu öffnen. Und genau wie beim vorherigen Mal konnten wir den Quellcode der Engine nicht passieren und überprüfen. Und das aus gutem Grund: Wir haben auch eine Handvoll interessanter Fehler gefunden .



Das Schreiben von Artikeln ist jedoch weit von allem entfernt. Wir arbeiten weiterhin an PVS-Studio und GameDev ist für uns einer der wichtigsten Entwicklungsbereiche. Daher möchten wir, dass Unity-Spieleentwickler die bestmögliche Analyse ihrer Projekte erhalten.



Einer der Schritte zur Verbesserung der Qualität der Analyse von Unity-Projekten bestand für uns darin, Anmerkungen zu den in der Unity Scripting-API definierten Methoden zu schreiben.



Methodenanmerkungen sind ein spezieller Mechanismus, der in PVS-Studio verwendet wird. Sie können dem Analysegerät alle erforderlichen Informationen zu einer bestimmten Methode bereitstellen. Es wird von den Entwicklern des Analysators selbst (dh von uns) in speziellem Code geschrieben.



Diese Informationen können ganz anderer Art sein. Beispiel: Wie eine Methode die an sie übergebenen Parameter beeinflussen kann, ob sie Speicher zuweisen kann und ob sie einen Wert zurückgibt, der verarbeitet werden muss. Durch Annotation kann der Analysator die Logik der Methoden besser verstehen und so neue und komplexere Fehler erkennen.



Wir haben bereits eine Vielzahl verschiedener Annotationen geschrieben (z. B. für Methoden aus dem System-Namespace) und sie gerne mit Methoden-Annotationen aus der Unity Scripting-API ergänzt.



Wir haben begonnen, die Liste der Anmerkungen mit einer Bewertung zu ergänzen. Wie viele Methoden gibt es? Welche sollten zuerst kommentiert werden? Insgesamt gab es viele Methoden, und wir haben uns entschlossen, zunächst die am häufigsten verwendeten Methoden zu kommentieren.



Die Suche nach gängigen Methoden wurde wie folgt durchgeführt: Zuerst haben wir einen Pool von Projekten von GitHub gesammelt, die die Funktionen von Unity nutzen, und dann haben wir mit einem selbstgeschriebenen Dienstprogramm (basierend auf Roslyn) die Aufrufe der Methoden gezählt, an denen wir interessiert sind. Als Ergebnis haben wir eine Liste von Klassen erhalten, deren Methoden am häufigsten verwendet werden:



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


Als nächstes müssen die Methoden dieser Klassen noch mit Anmerkungen versehen werden. Wir haben ein Testprojekt erstellt und in die Dokumentation gegraben, um so viele Informationen wie möglich über diese Methoden zu erhalten. Wir haben beispielsweise versucht, null als verschiedene Argumente zu übergeben, um zu sehen, wie sich das Programm verhält.



Bei solchen Überprüfungen wurden regelmäßig interessante undokumentierte Informationen entdeckt - und wir fanden sogar einige interessante Fehler im Motor. Wenn Sie also Code wie folgt ausführen:



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


Der Unity-Editor selbst stürzt direkt ab (zumindest in Version 2019.3.10f1). Es ist natürlich unwahrscheinlich, dass jemand solchen Code schreibt, aber die Tatsache, dass der Unity-Editor durch Ausführen eines solchen Skripts "heruntergefahren" werden kann, ist interessant.



Die Anmerkungen werden also geschrieben. Nach dem Start der Analyse haben wir sofort neue Auslöser entdeckt. Der Analysator hat beispielsweise einen seltsamen Aufruf der GetComponent- Methode festgestellt :



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

  if (uiManager)
  {
    uiManager.GetComponent<UIManager>();
  }
}


Analyzer-Warnung: V3010 Der Rückgabewert der Funktion 'GetComponent' muss verwendet werden. - ADDITIONAL IN CURRENT UIEditorWindow.cs 22



Die GetComponent- Methode impliziert auch bei ihrem Namen die Rückgabe eines bestimmten Werts. Es ist logisch anzunehmen, dass genau dieser Wert irgendwie verwendet werden sollte. Jetzt (dank der neuen Anmerkung) weiß der Analysator, dass ein solcher "verwaister" Aufruf dieser Methode einen logischen Fehler anzeigen kann, und warnt Sie davor.



Dies ist bei weitem nicht der einzige Auslöser, der nach dem Hinzufügen neuer Anmerkungen in unseren Testprojekten aufgetreten ist. Den Rest werde ich nicht geben, um diesen Artikel nicht zu groß zu machen. Die Hauptsache ist, dass Sie jetzt mit der Entwicklung von Unity-Projekten mit PVS-Studio viel sichereren und saubereren Code ohne Fehler schreiben können.



Wenn Sie mehr über unsere Arbeit mit Anmerkungen für Unity-Methoden erfahren möchten, können Sie dies in unserem Artikel tun: Wie der PVS-Studio-Analysator begann, noch mehr Fehler in Unity-Projekten zu finden .



Unwirkliche Engine 4



image3.png


Als die Entwickler von Unreal Engine 4 2014 den Quellcode der Engine für die Öffentlichkeit veröffentlichten, konnten wir dieses Projekt einfach nicht umgehen und schrieben auch einen Artikel darüber . Die Engine-Entwickler mochten den Artikel und haben die gefundenen Fehler behoben. Dies war jedoch nicht genug für uns und wir beschlossen, die Lizenz für unseren Analysator an Epic Games zu verkaufen.



Epic Games war daran interessiert, seine Engine mithilfe von PVS-Studio zu verbessern, daher haben wir uns auf eine Vereinbarung geeinigt: Wir korrigieren den Unreal Engine-Code selbst, damit der Analysator keine Warnungen dafür ausgibt, und die Jungs von Epic Games kaufen unsere Lizenz und zusätzlich Belohnen Sie uns für unsere Arbeit.



Warum mussten Sie alle Warnungen korrigieren? Der Punkt ist, dass der maximale Nutzen aus der statischen Analyse erzielt werden kann, indem Fehler korrigiert werden , sobald sie auftreten . Und wenn Sie Ihr Projekt zum ersten Mal überprüfen, erhalten Sie in der Regel mehrere Hundert (und manchmal Tausende) Warnungen. Unter all diesen Warnungen des Analysators können Warnungen für frisch geschriebenen Code leicht verloren gehen.



Auf den ersten Blick kann dieses Problem ganz einfach gelöst werden: Sie müssen sich nur hinsetzen und den gesamten Bericht vollständig umgehen, um Fehler schrittweise zu korrigieren. Diese Methode ist zwar intuitiver, kann jedoch einige Zeit in Anspruch nehmen. Die Methode zur Verwendung von Unterdrückungsdateien ist viel bequemer und schneller.



Unterdrückungsdateien sind eine spezielle Funktion von PVS-StudioHiermit können Sie die Trigger des Analysators in einer speziellen Datei "ausblenden". In diesem Fall werden versteckte Warnungen in nachfolgenden Protokollen nicht angezeigt: Sie können separat angezeigt werden.



Nachdem Sie nach der ersten Überprüfung eine große Anzahl von Triggern erhalten haben, können Sie alle erkannten Trigger mit wenigen Klicks zur Unterdrückungsdatei hinzufügen. Bei der nächsten Überprüfung durch den Analysator erhalten Sie ein sauberes Protokoll ohne einen einzigen Trigger.



Jetzt, da alte Warnungen nicht mehr protokolliert werden, können Sie eine neue Warnung leicht erkennen, sobald sie angezeigt wird. Wir haben den Code geschrieben -> ihn mit dem Analysegerät überprüft -> eine neue Warnung gesehen -> den Fehler behoben. So holen Sie das Beste aus Ihrem Analysegerät heraus.



Vergessen Sie gleichzeitig nicht die positiven Elemente in der Unterdrückungsdatei: Sie sind dieselben wie zuvor und enthalten möglicherweise Warnungen vor schwerwiegenden Fehlern und Schwachstellen. Daher lohnt es sich, diese Warnungen regelmäßig zu überprüfen und ihre Anzahl zu verringern.



Dieses Szenario ist natürlich praktisch, aber die Entwickler von Epic Games wollten, dass ihr Code sofort repariert wird, und haben ihn uns übergeben.



Und wir müssen arbeiten. Nachdem wir den Projektcode überprüft hatten, fanden wir 1821 eine einstufige Warnung von Level_1 und Level_2. Das Parsen einer solchen Menge von Warnungen erfordert ernsthafte Arbeit. Um diesen gesamten Prozess zu vereinfachen, haben wir eine kontinuierliche Code-Analyse auf unserem CI-Server eingerichtet.



Es sah so aus: Jede Nacht wurde die aktuelle Version von Unreal Engine 4 auf unserem Server kompiliert und die Analyse wurde sofort nach dem Build automatisch gestartet. Wenn unsere Mitarbeiter am Morgen zur Arbeit kamen, hatten sie immer einen neuen Analysatorbericht zur Hand, mit dem sie den Fortschritt bei der Korrektur von Warnungen verfolgen konnten. Ein solches System ermöglichte es außerdem, die Stabilität des Builds jederzeit zu überprüfen, indem es manuell auf dem Server ausgeführt wurde.



Der gesamte Prozess dauerte 17 Arbeitstage. Der Zeitplan für die Korrektur von Warnungen lautet wie folgt:



image4.png


Tatsächlich spiegelt diese Grafik unsere Arbeit nicht vollständig wider. Nachdem wir alle Warnungen behoben hatten, warteten wir weitere zwei Tage, bis sie unsere neuesten Pull-Anfragen angenommen hatten. Während dieser ganzen Zeit überprüften wir weiterhin automatisch die neueste Version von Unreal Engine, die wiederum mit neuem Code aufgefüllt wurde. Und was denkst du? Während dieser zwei Tage hat PVS-Studio vier weitere Fehler im Code gefunden! Einer von ihnen war besonders ernst und könnte möglicherweise zu undefiniertem Verhalten führen.



Natürlich haben wir diese Fehler auch behoben. Jetzt haben die Unreal Engine-Entwickler nur noch eines zu tun: Konfigurieren Sie ihre automatische Analyse auf die gleiche Weise wie wir. Von diesem Moment an sahen sie jeden Tag Warnungen, die für den neu geschriebenen Code ausgegeben wurden. Dies ermöglichte es ihnen, Fehler im Code bereits in dem Moment zu beheben, in dem sie auftraten - in den frühesten Entwicklungsstadien .



Weitere Informationen zur Arbeit am Unreal Engine-Code finden Sie im offiziellen Unreal Engine- Blog oder auf unserer Website .



Analyse verschiedener Spiele



image5.png


Habe ich erwähnt, dass wir verschiedene Open Source-Projekte überprüfen und Artikel darüber schreiben? Wir haben also nur eine ganze Reihe ähnlicher Artikel über Spielprojekte! Wir haben über Spiele wie VVVVVV , Space Engineers , Command & Conquer , osu geschrieben! und sogar (sehr alter Artikel) Doom 3 . Wir haben auch die 10 interessantesten Bugs aus der Videospielbranche zusammengestellt.



Wir haben vielleicht auch die meisten bekannten Open-Source-Engines überprüft. Neben Unity und Unreal Engine 4 kamen auch Projekte wie Godot , Bullet , Amazon Lumberyard und Cry Engine V in Sichtund viele andere.



Das Beste daran ist, dass viele der von uns beschriebenen Fehler später von den Projektentwicklern selbst behoben wurden. Es ist schön zu spüren, dass das Tool, das Sie entwickeln, der Welt echte, sichtbare und greifbare Vorteile bringt.



Eine Liste aller unserer Artikel, die sich auf die eine oder andere Weise auf die Entwicklung von Videospielen beziehen, finden Sie auf einer speziellen Seite unseres Blogs.



Fazit



Damit ist mein kurzer Artikel abgeschlossen. Ich wünsche Ihnen einen sauberen und korrekt funktionierenden Code ohne Fehler!



Interessiert am Thema statische Analyse? Möchten Sie Ihr Projekt auf Fehler überprüfen? Probieren Sie PVS-Studio aus .







Wenn Sie diesen Artikel einem englischsprachigen Publikum zugänglich machen möchten, verwenden Sie bitte den Übersetzungslink: George Gribkov. Wie statische Code-Analyse in der GameDev-Branche hilft .



All Articles