Cómo ayuda el análisis de código estático en la industria de GameDev

( 4 de diciembre de 2020)

La industria del juego está en constante evolución y se desarrolla más rápido que una bala acelerada. Junto con el crecimiento de la industria, la complejidad del desarrollo también aumenta: la base del código es cada vez más grande y la cantidad de errores también aumenta. Por lo tanto, los proyectos de juegos modernos deben prestar especial atención a la calidad del código. Hoy cubriremos una de las formas de hacer que su código sea más decente, que es el análisis estático, así como también cómo PVS-Studio en la práctica ayuda en el desarrollo de proyectos de juegos de varios tamaños.

“Lo más importante que he hecho como programador en los últimos años es para perseguir agresivamente el análisis de código estático. Incluso más valioso que los cientos de errores graves que he evitado es el cambio de mentalidad sobre la forma en que veo la confiabilidad del software y la calidad del código. ”- John Carmack

Hemos estado trabajando con los principales desarrolladores de juegos durante muchos años y durante este tiempo logramos hacer muchas cosas interesantes y útiles para la industria del juego. No es una gran sorpresa, dada la lista de nuestros clientes de la industria del juego. Apoyamos activamente a nuestros clientes: para integrar PVS-Studio en su propio proceso de desarrollo, corregir los errores encontrados por el analizador e incluso crear funciones especiales personalizadas.

Además, hacemos mucho desarrollo independiente de el analizador en la dirección de GameDev, además de promover PVS-Studio, informándole a la gente acerca de errores interesantes que ha encontrado en varios videojuegos.

Claro, tenemos algunas historias interesantes que contar. Este artículo cubrirá varios de estos casos.

PVS-Studio y Unity

Una de las formas en que promocionamos nuestro producto es escribiendo artículos sobre la verificación de proyectos abiertos. Todos se benefician de estos artículos: un lector tiene la oportunidad de ver algunos errores inusuales en un proyecto familiar y aprender algo nuevo. En cuanto al equipo de PVS-Studio, tenemos la oportunidad de mostrar el trabajo realizado en código real, para que los desarrolladores de proyectos puedan conocer los errores y corregirlos con anticipación.

Nuestro primer conocimiento importante de Unity tuvo lugar en 2016, cuando los desarrolladores de este motor de juego abrieron el código fuente de varios componentes, bibliotecas y demos en su repositorio oficial. No es de extrañar, no pudimos pasar por alto un caso tan atractivo y queríamos escribir un artículo sobre cómo verificar el código publicado.

Luego descubrimos que el código de Unity3D (en ese momento el motor se llamaba así) era de muy alta calidad. Pero aun así pudimos encontrar bastantes errores graves en él. Había suficientes para escribir un artículo .

Dos años después, sucedió otra cosa: los desarrolladores de Unity abrieron el código del motor y el propio editor. Y al igual que la vez anterior, no pudimos darnos cuenta de eso y verificamos el código fuente del motor. Y no fue por nada, también encontramos un grupo de defectos cautivadores.

Al mismo tiempo, nuestras intenciones van mucho más allá de escribir artículos. Seguimos trabajando en PVS-Studio y GameDev es una de las áreas más importantes para nuestro desarrollo. Por lo tanto, queremos que los desarrolladores de juegos de Unity puedan obtener el mejor análisis posible de sus proyectos.

Uno de los pasos para mejorar la calidad del análisis de proyectos de Unity fue escribir anotaciones para los métodos definidos en la API de scripting de Unity. .

La anotación de métodos es un mecanismo especial utilizado en PVS-Studio. Permite al usuario proporcionar al analizador toda la información necesaria sobre un método en particular. Está escrito en un código especial por los propios desarrolladores del analizador (es decir, por nosotros).

Esta información puede ser de varios tipos. Por ejemplo: cómo el método puede afectar los parámetros que se le pasan, si puede asignar memoria y si devuelve un valor que debe manejarse. Por lo tanto, la anotación permite al analizador comprender mejor la lógica de los métodos, lo que le permite detectar errores nuevos y más complejos.

Ya hemos escrito una gran cantidad de anotaciones diferentes (por ejemplo, para métodos del sistema espacio de nombres), y nos complació agregarles anotaciones de métodos de la API de scripts de Unity.

Comenzamos a extender la lista de anotaciones con una evaluación. ¿Cuántos métodos hay en total? ¿Cuáles deben anotarse primero? Había muchos métodos en total, así que decidimos comenzar anotando los que se utilizan con más frecuencia.

Así es como estábamos buscando métodos populares: primero, reunimos un grupo de proyectos de GitHub que usan características de Unity, y luego usamos una utilidad auto-escrita (basada en Roslyn) para calcular llamadas a los métodos en los que estábamos interesados. Como resultado, obtuvimos una lista de clases cuyos métodos se usaron con mayor frecuencia:

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

A continuación, permaneció para anotar los métodos de estas clases. Creamos un proyecto de prueba y profundizamos en la documentación para obtener la mayor cantidad de información posible sobre esos métodos. Por ejemplo, intentamos pasar null como varios argumentos para ver cómo se comportaría el programa.

Durante tales comprobaciones, estábamos descubriendo información no documentada interesante de vez en cuando. Incluso encontramos un par de errores notables en el motor. Por ejemplo, cuando estamos ejecutando el siguiente código:

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

el propio editor de Unity falla (al menos en la versión 2019.3.10f1). Por supuesto, es poco probable que alguien escriba ese código. Aún así, el hecho de que el editor de Unity pueda fallar ejecutando un script de este tipo es curioso.

Entonces, teníamos las anotaciones escritas. Después de ejecutar el análisis, inmediatamente encontramos nuevos desencadenantes. Por ejemplo, el analizador detectó una llamada extraña al método GetComponent :

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

Advertencia del analizador: V3010 Se requiere que se utilice el valor de retorno de la función GetComponent. – ADICIONAL EN UIEditorWindow.cs 22

El método GetComponent implica la devolución de un valor específico incluso debido a su nombre. Es lógico suponer que este valor debería usarse de alguna manera. Ahora, gracias a la nueva anotación, el analizador sabe que una llamada «desatendida» a este método puede indicar un error lógico y advierte al respecto.

Esta no es la única advertencia que apareció en el conjunto de nuestro probar proyectos después de agregar nuevas anotaciones. No citaré el resto, para no hacer este artículo demasiado extenso. Lo principal es que ahora el desarrollo de proyectos de Unity usando PVS-Studio le permite escribir código mucho más seguro y limpio sin errores.

Si desea leer más sobre nuestro trabajo con anotaciones para métodos de Unity, aquí está el artículo: Cómo el analizador PVS-Studio comenzó a encontrar aún más errores en proyectos de Unity .

Unreal Engine 4

Cuando, en 2014, los desarrolladores de Unreal El motor 4 abrió el código fuente del motor, simplemente no pudimos pasar de ese proyecto y también escribimos un artículo al respecto. A los desarrolladores del motor les gustó el artículo y solucionaron los errores que encontramos. Pero esto no fue suficiente para nosotros, y decidimos intentar vender la licencia de nuestro analizador a Epic Games.

Epic Games estaba interesado en mejorar su motor con PVS-Studio, así que acordamos lo siguiente : arreglamos el código de Unreal Engine por nuestra cuenta para que el analizador no emita ninguna advertencia, y los chicos de Epic Games compran nuestra licencia y además nos recompensan por el trabajo realizado.

Por qué todas las advertencias tenían que ser ¿fijo? El hecho es que uno puede obtener el máximo beneficio del análisis estático corrigiendo los errores justo cuando aparecen . Cuando revisa su proyecto por primera vez, generalmente recibe varios cientos (y a veces miles) de advertencias. Entre todas estas activaciones del analizador, es fácil perder las advertencias emitidas para el código recién escrito.

A primera vista, este problema se puede resolver con bastante facilidad: solo necesita sentarse y revisar todo el informe , corrigiendo gradualmente los errores. Sin embargo, aunque este método es más intuitivo, puede llevar tiempo. Es mucho más conveniente y rápido usar la supresión de archivos.

La supresión de archivos es una característica especial de PVS-Studio que le permite ocultar advertencias del analizador en un archivo especial. Sin embargo, las advertencias ocultas no aparecerán en los registros posteriores: puede verlas por separado.

Después de tener muchas activaciones después de la primera verificación, puede agregar todas las advertencias detectadas al archivo de supresión con un par de clics y obtendrá un registro limpio sin una sola entrada después de la siguiente verificación.

Ahora que las advertencias antiguas ya no están incluidas en el registro, puede detectar fácilmente una nueva advertencia inmediatamente cuando aparece. Este es el orden de las acciones: escribe el código -> compruébalo con el analizador -> detecta una nueva advertencia -> corrige el error. Así es como sacará el máximo partido al analizador.

Al mismo tiempo, no se olvide de las advertencias en el archivo de supresión: aún pueden contener advertencias sobre errores y vulnerabilidades importantes, como antes. Por lo tanto, uno debe volver a estas advertencias y reducir su número de manera regular.

Sin duda, este escenario es conveniente, pero los desarrolladores de Epic Games querían que su código se corrigiera de inmediato, por lo que aprobaron el tarea para nosotros.

Y nos pusimos manos a la obra. Después de verificar el código del proyecto, encontramos 1821 advertencias de Level_1 y Level_2. Analizar un volumen tan grande de advertencias requiere un trabajo serio, y para facilitar todo este proceso, hemos configurado un análisis de código continuo en nuestro servidor CI.

Se veía así: todas las noches en nuestro servidor, el actual Se creó la versión de Unreal Engine 4 e inmediatamente después de la compilación, el análisis se inició automáticamente. Por lo tanto, cuando nuestros muchachos venían a trabajar por la mañana, siempre tenían un informe nuevo del analizador, lo que les ayudaba a seguir el progreso de la eliminación de advertencias. Además, este sistema nos permitió verificar la estabilidad de la compilación en cualquier momento ejecutándolo en el servidor manualmente.

Todo el proceso nos llevó 17 días hábiles. El programa para corregir errores fue el siguiente:

De hecho, este programa no refleja completamente nuestro trabajo. Después de corregir todas las advertencias, esperamos otros dos días para que aceptaran nuestras últimas solicitudes de extracción. Durante todo este tiempo, se comprobó automáticamente la última versión de Unreal Engine, que, a su vez, se siguió actualizando con nuevo código. Entonces, ¿qué crees que pasó? ¡Durante esos dos días, PVS-Studio encontró cuatro errores más en el código! Uno de ellos fue crucial y podría conducir a un comportamiento indefinido.

Por supuesto, también corregimos esos errores. En ese momento, a los desarrolladores de Unreal Engine solo les quedaba una cosa: configurar el análisis automático en su propio lugar, tal como lo hemos hecho nosotros. A partir de ese momento, comenzaron a ver todos los días advertencias que se emitían para el código que acababan de escribir. Esto les permitió corregir errores en el código justo cuando aparecieron, en las primeras etapas de desarrollo .

Puede leer más sobre cómo trabajamos en el código de Unreal Engine en el blog oficial de Unreal Engine o en nuestro sitio web .

Análisis de varios juegos

¿He mencionado que comprobar varios proyectos abiertos y escribir artículos sobre ellos? Entonces, ¡ahora tenemos muchos artículos similares sobre proyectos de juegos! Escribimos sobre juegos como VVVVVV , Space Engineers , Command & Conque r, osu! e incluso (un artículo muy temprano) Doom 3 . También compilamos el top 10 de los errores de software más interesantes de la industria de los videojuegos.

Por lo tanto, verificamos probablemente la mayoría de los motores de código abierto conocidos. Además de Unity y Unreal Engine 4, proyectos como Godot , Bullet , Amazon Lumberyard , Cry Engine V y muchos otros han estado bajo nuestra mirada.

La mejor parte de todo esto es que muchos de los errores que describimos fueron posteriormente corregidos por los propios desarrolladores del proyecto. Es agradable sentir que la herramienta que está desarrollando brinda beneficios reales, visibles y tangibles al mundo.

Puede ver una lista de todos nuestros artículos relacionados con el desarrollo de videojuegos de una forma u otra en un página especial de nuestro blog.

Conclusión

En este punto mi artículo llega a su fin. ¡Le deseo un código limpio y que funcione correctamente sin errores ni errores!

¿Está interesado en el tema del análisis estático? ¿Quiere comprobar si su proyecto tiene errores? Pruebe PVS-Studio .

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *