15 aspectos críticos en la programación de videojuegos

Este artículo presenta diversos aspectos que deben atenderse al momento de desarrollar un videojuego. Corresponde a una presentación sucinta de aquellos aspectos críticos que hemos identificado durante el desarrollo de nuestro más reciente videojuego: The Rainbow Machine. Por consiguiente, para comprender este artículo se requiere conocer la terminología pertinente. A continuación, los aspectos críticos:

 

1) Línea de producción automatizada: Una de las primeras cosas que debes procurar al desarrollar un videojuego es la automatización del flujo de trabajo. Debes crear los scripts necesarios para producir, con un simple comando, cualquier versión de tu juego. Por ejemplo, para obtener la versión de trabajo de tu juego debes ejecutar algo como “make debug”, para la versión final de escritorio, un “make release”, para la versión final android algo como “make android”, y así. Deberás tener varios targets si pretendes abordar múltiples plataformas e idiomas. Y por supuesto, no está demás tener un “make all”. El flujo de trabajo en entornos de desarrollo como Visual C++ y Eclipse es muy conveniente para agregar código y observar los efectos de dicha modificación. Sin embargo, a la larga, los scripts de producción te ahorrarán mucho tiempo y molestias al momento de producir versiones de tu juego para testers, publishers, clientes directos, etcétera.

2) Respalda tu trabajo: Y crea un script para ello. Cerciórate de que respaldas a una ubicación segura (o a más de una ubicación si es posible). Tus respaldos deben estar cifrados, y además correctamente identificados (fecha, hora y cualquier otro atributo pertinente).

3) Organiza bien tus directorios de trabajo: Procura separar el código de los recursos (imágenes, videos, música, efectos de sonido). Estructura tus directorios de tal forma que los artistas tengan acceso al directorio de imágenes pero no a los directorios con el código fuente del juego. Además, con frecuencia los recursos producidos por los artistas requieren algún tipo de preprocesamiento antes de poder ser usados por tu base de código. Por ejemplo, las imágenes podrían tener que empaquetarse en texturas, o preparar versiones de las imágenes para dispositivos con y sin Retina-display. Entonces, aplica lo dicho en el punto 1. Crea un script que lea el directorio con las imágenes de los artistas y las agrupe en texturas aptas para tu base de código. Así, el código utiliza las texturas y no directamente las imágenes de los artistas. Los artistas no necesariamente tienen que involucrarse en el proceso de generación de texturas, ni con el código. Lo mejor: cuando quieras actualizar las texturas de tu juego para que incluyan las nuevas producciones de los artistas, una simple invocación del script bastará para poner todo al corriente.

Challenging the first Boss on a Kindle Fire Tablet

4) No subestimes las diferencias entre la versión de escritorio y la versión móvil: Las versiones móviles tienen requisitos de bajo consumo de memoria y batería. Por lo general, en el escritorio (Windows, Mac, Linux) tu juego no sufrirá estas restricciones: puedes cargar todos tus recursos (o un buen lote de ellos) durante el inicio, y dejarlos en memoria para el resto del juego. En la versión móvil, a menos que tu juego sea muy pequeño, no tendrás memoria suficiente para cargar todo de una vez. O mejor dicho, no puedes asumir que todos los dispositivos móviles donde correrán tu juego tendrán la cantidad de memoria suficiente para cargar todos tus recursos y escenas de una vez. Por consiguiente, al comenzar el juego deberás cargar sólo lo esencial, y luego, a medida que el jugador progresa, deberás ir cargando y descargando los recursos.

5) Respalda tu trabajo, incluyendo los recursos: Ver el punto 2.

6) Respalda, es en serio.

7) Cuidado con las fugas de memoria (dreadful memory leaks): Muy especialmente si trabajas con C/C++. Pero no te confíes tampoco de ningún automatic garbage collector ni del autoreference counting. El enemigo puede aguardarte en la esquina más inesperada. Asegúrate de revisar bien tu código, y revisa con atención la documentación de las librerías o SDKs que uses con tu juego: puede haber objetos y estructuras de datos que nadie se compromete a liberar por ti. Mucho cuidado.

8) Prepárate para soporte multilenguaje: Nada de
label.text = “Bienvenido”
Prefiere código como éste:
label.text = getSring(MSG_WELCOME)

Y créeme, querrás soporte multilenguaje. Después de todo, así podrás llegar a más jugadores. Mientras más, mejor. Porque lo que quieres es una gran cantidad de dinero jugadores.

9) Los primeros segundos son muy importantes: Procura que cuando un usuario ejecute tu juego se muestre alguna imagen lo más rápidamente posible. No se trata de que la carga de recursos sea inmediata (aunque ciertamente, si puedes hacer eso, adelante). Se trata de que cuando tu juego se ejecute se cree la ventana lo más rápidamente posible, y muestres, pronto alguna imagen. Esta imagen puede ser el logo de tu empresa o del juego, o la típica barra de carga de recursos del juego. Los usuarios suelen ser más tolerantes con una barra de carga que va avanzando lentamente, que con un inicio lento. Por tanto, posterga lo más posible las operaciones lentas como la inicialización de sonidos y la creación de archivos.

Por cierto, en relación con lo primero que muestra un juego, típicamente es un splash screen con los logos pertinentes. Sin embargo, cuando trabajas con publishers, éstos suelen requerirte que antes de mostrar tu logo, exhibas el de ellos y el de quién sabe cuántos otros partners. Lo mejor es que tu juego lea todas estas imágenes de splash desde un directorio específico. Así todos estos publishers, partners y tú mismo podrán colocar en dicho directorio las imágenes que deseen.

10) Publishers: Hablando de publishers… seguramente van a pedirte algunos anexos muy específicos, como links a alguna página, o ningún link en absoluto. Adicionalmente, te pedirán muchos activos gráficos del juego en distintos tamaños.

11) No confíes en emuladores: Asegúrate de evaluar el framerate y el consumo de memoria en un dispositivo real. Lo mejor es ir probando en los dispositivos a medida que vas trabajando. Idealmente, al terminar el día de trabajo deberías realizar una prueba en un dispositivo, para evitar desagradables sorpresas al final, cuya solución exija modificaciones amplias de tu código. Para estas pruebas al final del día, tu script que produce una versión release te va a ahorrar mucho tiempo.

12) Respalda.

13) Premature optimization is the root of all evil - Donald Knuth: Primero escribe un código que funcione. Que haga lo que tiene que hacer y que sea legible. Y continúa adelante. Al final, si todo está bien, y tu juego muestra un nivel aceptable de consumo de recursos, entonces todo está listo, y olvídate de optimizaciones. Optimiza tu código sólo si en verdad debes hacerlo, para reducir el tiempo de alguna operación, o el consumo de memoria y batería.

14) No reinventes la rueda: Si necesitas leer archivos XML, busca una librería que haga eso por ti. Olvídate de escribir tu súper-único-protomacho-parser de XML. Es más, si has desarrollado otros juegos, seguramente tienes una gran base de código que ha pasado por varias pruebas y usos. Si puedes, aprovecha ese código. Úsalo. Pero no reescribas código a menos que sea estrictamente necesario. El código antiguo y funcional suele tener muchos errores corregidos. Si te pones a modificar código “para optimizarlo” o “para que se vea mejor” probablemente acabarás introduciendo nuevos errores y perdiendo tiempo.

15) Avanza y termina: No te pases 3 meses revisando librerías o SDKs antes de empezar tu juego. Y cuando estés trabajando, ataca los problemas, soluciónalos y avanza. Deja de darle muchas vueltas al asunto. Toma decisiones y continúa. Al final de tu trabajo tendrás experiencia que te permitirá tomar mejores decisiones en un futuro. Pero no mires atrás ni te arrepientas de nada. Piensa que con cada decisión eres un mejor programador, un mejor diseñador. Y por favor, termina el juego. Un juego puede ser malo, puede no gustarle a nadie. Pero recuerda: no hay peor juego que el juego que no se termina.

Ve. Y buena suerte.

P.D. ¿Respaldaste?