He creado un juego para la SNES desde cero en pleno 2020 (¡con cartucho incluido!)

Crear nuevos juegos para las videoconsolas retro es algo que los programadores amateurs podemos hacer fácilmente gracias a las herramientas disponibles en la actualidad. El año pasado publiqué un nuevo juego para mi consola favorita: la Super Nintendo (SNES). El proyecto acabó teniendo su propia edición física con su cartucho y su caja de cartón, al igual que en los 90.

En este artículo explicaré los pasos que tuve que seguir en esta increíble aventura: diseñar el juego, solventar los problemas técnicos relacionados con la SNES a la hora de programar el juego, fabricar nuevos cartuchos para la SNES y crear el manual de instrucciones y la caja.

El juego: 'Yo-Yo Shuriken'

'Yo-Yo Shuriken' es un juego tipo arcade de acción rápida para 1 o 2 jugadores para la Super Nintendo (SNES).

El principal objetivo del juego es lanzar un shuriken (esas pequeñas estrellas afiladas características de los ninjas) que puedes recuperar mágicamente en cualquier momento, lo que te permite atacar a tus enemigos por delante y por la espalda. Incluso puedes concentrar energía en el shuriken para crear un ataque poderoso con el que acabar con varios enemigos a la vez.

El juego está disponible en cartucho con su adorable caja y manual de instrucciones en la página de Catskull Games. Y si prefieres probarlo en un emulador, también puedes hacerte con la ROM del juego.

Ahora que ya sabes un par de cosas sobre el juego, vamos a analizar el proceso de creación.

Diseñando el juego

La creación de 'Yo-Yo Shuriken' fue un proceso bastante orgánico: me dediqué a probar ideas de jugabilidad según se me iban ocurriendo e intenté refinarlas hasta que me salió un juego "divertido". Empecemos con la idea inicial: durante mucho tiempo, quería hacer un juego de disparos de un solo tiro, de manera que el jugador tuviera que esperar antes de volver a disparar. Además de la idea de "una sola bala", también quería hacer un juego que pudiera disfrutar con un amigo en modo multijugador.

Con esas dos ideas en mente, me dediqué a crear el juego paso a paso. Cada vez que introducía una buena novedad, contaba como una nueva "versión" y hacía testeos todo lo que podía. Si la versión que tenía era buena, seguía añadiéndole opciones. De lo contrario, seguía trabajando en lo que ya tenía hasta que el juego fuera divertido y a partir de ahí le seguía añadiendo más cosas. Este es un resumen de los principales prototipos del juego con capturas de pantalla. Si te apetece probar las ROMs de estos prototipos, están disponibles a modo de ventajas exclusivas para mis seguidores en Patreon.

'Cyber Ninja': Versión 1

Lo primero que tienes que hacer cuando creas un videojuego en una plataforma que no conoces es ¡hacer que salga algo en la pantalla! Así que dibujé un ninja robótico en un mapa de bits e hice que la SNES lo mostrara en la pantalla. Cuando funcionó, añadí el código para hacer los movimientos del _sprite_ con el D-pad y posteriormente hice la animación para que caminara cuando la imagen se moviera.

Estos primeros pasos pueden parecer bastante sencillos pero hay que tener en cuenta que era mi primera vez haciendo un juego para la SNES, así que me llevó bastante tiempo ya que iba aprendiendo cómo funcionaba la consola mientras me dedicaba a crear el juego. Como en su momento mi proyecto de juego solo tenía un ninja robótico, le puse de nombre 'Cyber Ninja'.

'Cyber Ninja' : Versión 2

El _sprite_ del jugador, un ninja, apareció por primera vez en esta versión y los _sprites_ de los robots pasaron a ser sus enemigos (todo el mundo sabe que los ninjas y los robots se odian). Como buen ninja, el jugador solo puede lanzar un shuriken que puede acabar en uno de los bordes de la pantalla, haciendo que el jugador tenga que recogerlo si quiere volver a lanzarlo. Los robots enemigos pueden moverse sin problemas por la pantalla, pero todavía no hay ningún detector de colisiones.

'Yo-Yo Shuriken' : Versión 1

Tras varias pruebas, me planteé que el shuriken podría volver al ninja de forma automática si el jugador volvía a presionar el botón. Me divertí mucho probando esta funcionalidad, así que pasó a ser la parte central del juego. También cambié el título del proyecto para incluir dicha funcionalidad: ¡Se acabó lo de "Cyber Ninja"! ¡Larga vida a 'Yo-Yo Shuriken'! De hecho, en el juego el shuriken va y viene, al igual que un yoyó.

También le añadí el detector de colisiones para que los robots desaparezcan cuando reciben el ataque de un shuriken. Pero si un robot ataca al jugador, es éste el que desaparece. Si bien todavía está todo en un nivel muy básico, la jugabilidad principal del juego ya está casi finalizada en este tercer prototipo. Fue entonces cuando decidí hacer experimentos con el motor de juego para saber cuánto podía forzarlo hasta que el juego se bloqueara. Conseguí tener hasta 80 enemigos caminando e interactuando en pantalla. Recordemos que la SNES puede mostrar en pantalla hasta un total de 128 _sprites_, así que tener 80 sprites actualizándose 60 veces por segundo con sus colisiones y animaciones es todo un logro.

'Yo-Yo Shuriken' : Versión 2

En esta cuarta versión, los enemigos ya no solamente se mueven en línea recta y se pueden mover en varias direcciones. También rebotan cuando llegan al borde de la pantalla, haciendo que el juego se vuelva más interesante.

'Yo-Yo Shuriken' : Versión 3

Añadí un color de fondo diferente y un sistema para generar enemigos de forma infinita. En la versión anterior, en cuanto los 80 robots eran destruidos el juego se quedaba vacío. ¡Pues a generar un ejército de robots infinito! Los enemigos pueden seguir al jugador, forzándole a seguir moviéndose. De hecho, en esta quinta versión, el juego se volvía rápidamente aburrido si el jugador se quedaba quieto.

'Yo-Yo Shuriken' : Versión 4

En esta versión me tuve que enfrentar a mi primera gran dificultad técnica: mostrar grandes _sprites_ de explosiones cada vez que un robot muere. Escogí que los _sprites_ del jugador y de los enemigos fueran bastante pequeños: 16x16 píxeles.

De esta forma podía mostrar muchos en pantalla con suficiente espacio libre para que el jugador pueda moverse por la pantalla y evitar a los enemigos (la resolución de la SNES es de 256x224 píxeles). Sin embargo, decidí que las explosiones tuvieran un tamaño más grande: 32x32 píxeles.

La Super Nintendo es capaz de mostrar dos tamaños diferentes de _sprites_ al mismo tiempo. El desarrollador puede elegir entre un tamaño de _sprite_ "pequeño" y uno "grande" desde una pequeña lista de tamaños (8x8, 16x16, 32x32 y 64x64) y la consola utilizará esta información a la hora de acceder a la RAM de vídeo para mostrar los datos del sprite en pantalla. Esta es una de las muchas funcionalidades gráficas que hacen que la vida del desarrollador de videojuegos sea más fácil. Sin embargo, como cualquier tipo de característica técnica, puede ser intimidante si no sabes cómo utilizarla.

En mi caso, en este prototipo en concreto, solo podía mostrar en pantalla una pequeña parte de los _sprites_ de explosión, independientemente de lo que hiciera. El problema resultó ser bastante sencillo: no estaba subiendo los datos de los _sprites_ a dónde debía en la memoria de vídeo de la SNES, así que la consola no podía leerlos. Encontré la solución tras pasarme varias horas repasando las maravillosas guías que la comunidad de desarrolladores de videojuegos amateur ha creado a lo largo de los años. Les estoy muy agradecido por su gran trabajo a la hora de crear y compartir todos estos conocimientos: sin ellos, los desarrolladores amateur como yo no podríamos crear videojuegos para la SNES.

'Yo-Yo Shuriken' : Versión 5

Este prototipo marca la incorporación de otra funcionalidad principal: ¡El modo para dos jugadores!

También se unen a la batalla nuevos enemigos: como los robots naranjas que pueden recibir varios ataques hasta que explotan o los robots azules que pueden seguir al jugador por la pantalla. También añadí monedas que tienes que recoger para conseguir puntos. Esta mecánica mejora mucho la jugabilidad. De hecho, las monedas son la única forma de obtener puntos, puesto que matar robots no tiene ninguna "recompensa" en sí, simplemente es necesario para evitar que tu personaje muera.

Los robots sueltan monedas cuando mueren, pero las monedas desaparecen al cabo de unos segundos. También hay que tener en cuenta que siempre hay varios robots en la pantalla y te matarán al instante si te tocan. Para conseguir puntos, el jugador tiene que tomar muchos riesgos y moverse entre los robots o de lo contrario no conseguirá una buena puntuación. Sin embargo, a veces es mejor dejar que las monedas desaparezcan y no arriesgarse a perder una vida.

Esta mecánica de juego hace que 'Yo-Yo Shuriken' ofrezca una progresión paulatina de la dificultad a los jugadores. Normalmente, un jugador novato tenderá a quedarse quieto y se centrará solamente en destruir robots. No conseguirá puntos, pero será capaz de seguir jugando y poderá enfrentarse al jefe final. En cuanto el jugador gane confianza, será capaz de recoger monedas para obtener una buena puntuación. Por supuesto, los jugadores más experimentados pueden intentar conseguir la "partida perfecta" haciéndose con todas las monedas, aunque supone tomar una extrema cantidad de riesgos.

'Yo-Yo Shuriken' : Versión 6

A medida que continuaba con el testeo, me di cuenta de que el juego se estaba volviendo bastante repetitivo y probé varias ideas para tratar de arreglarlo. La que me pareció más interesante fue mantener pulsado el botón de disparar para "cargar" el shuriken. Cuando sueltas el botón, lanza un "súper disparo" que puede atravesar a varios enemigos. Esta mecánica aporta una pizca de estrategia al juego, puesto que ahora el jugador tiene la opción de lanzar varios ataques y matar a los enemigos uno a uno o realizar un ataque más potente para matar a varios enemigos a la vez.

'Yo-Yo Shuriken' : Versión 7

A partir de esta versión, todas las principales mecánicas del juego ya estaban terminadas y comenzaba la parte más larga y tediosa del proyecto: añadir contenido y pulir el juego. Primero, añadí efectos de sonido que había creado con BFXR. También incluí las maravillosas pistas de música compuestas por XRACECAR y modifiqué la interfaz gráfica del juego y la desplacé a la parte superior de la pantalla.

En cuanto a los gráficos, añadí una textura al fondo del juego. Teniendo en cuenta que mis habilidades artísticas son bastante limitadas, me resultó complicado dibujar un fondo convincente. Hubo varios intentos, incluyendo el actual, hasta decantarme por un "suelo de tablas de madera" para resaltar la idea de que le juego se desarrolla en un dojo japonés (véase la siguiente versión).

Finalmente, aunque no menos importante, empecé a crear varios niveles de juego. Cada nivel se compone de varias tandas de enemigos que van aumentando en número y dificultad. Me tiré muchísimo tiempo probando y equilibrando dichas tandas de enemigos para hacer que el juego fuera entretenido. Cada desarrollador de videojuegos tiene su forma de hacerlo y personalmente, para un juego tipo arcade, a mí me gusta mezclar momentos de intensidad y difíciles con momentos más fáciles para dejarle al jugador que respire de vez en cuando.

Por ejemplo, si el jugador consigue pasar una pantalla con varios robots persiguiéndole rápidamente y la pantalla está llena de enemigos, le apremio con una pantalla más lenta con 4 o 5 enemigos básicos que se muevan lentamente y donde sea fácil matarlos y hacerse con las monedas.

Como curiosidad, puede que te des cuenta de que los gráficos de las explosiones todavía son bastante horrorosos.

'Yo-Yo Shuriken' : Versión 8

En esta versión, apareció un nuevo enemigo en la batalla: el robot "escudo". A este enemigo solamente se le puede atacar por la espalda y la mecánica de juego de 'Yo-Yo Shuriken' tiene más sentido. De hecho, la mejor manera para matar a los robots con escudo es disparar a su lado para posteriormente recuperar el shuriken y le dé al robot escudo en su trayectoria de regreso. También creé nuevos sprites de explosiones y la imagen de fondo está mejorada. También añadí un bonus de invencibilidad (una cabeza de ninja blanca que finalmente pasaría a ser una estrella en la versión final del juego).

'Yo-Yo Shuriken' : Versión 9

La última gran característica del juego llegó en esta versión: los jefes de nivel. Me pasé mucho tiempo diseñando y probado varios jefes y fue una de las partes más divertidas de todo el proceso de desarrollo del juego.

En las capturas de pantalla puedes ver un prototipo del jefe "serpiente" y un jefe que no está presente en la versión final del juego: el tanque. Hacen falta varios pasos para destruir al jefe tanque y cuenta con varios puntos débiles (las bolas naranjas) que hay que atacar una tras otra. Una vez que se ha destruido un punto débil, elimina parte de la estructura del tanque exponiendo nuevos puntos débiles. Se trataba de un jefe bastante complicado. Por ejemplo, uno de los puntos débiles está al final de un túnel, así que requiere una puntería muy precisa.

En teoría, la idea para este jefe era bastante interesante y me llevó varios días programarla. Sin embargo, tras haber jugado varias veces decidí eliminarlo del juego porque resultaba bastante aburrido. De hecho, muchas veces era demasiado difícil acabar con el jefe debido a su gran tamaño y si el jefe conseguía acorralarte en una esquina no tenías escapatoria, puesto que era imposible darle en alguno de sus puntos débiles.

Finalmente, enfrentarse a este jefe era más frustrante que divertido y como puedes ver, incluso en los proyectos amateur, a veces tienes que quitar contenido que no está a la altura por mucho que te hayas tirado muchas horas programándolo.

'Yo-Yo Shuriken' : Versión 10

La palabra clave de esta versión final es "pulido". Añadí la pantalla de inicio, las animaciones de la introducción y de los créditos y una pantalla para explicar cómo funciona el juego. El toque final fue incluir un modo bonus secreto: el modo "doble ninja" donde puedes controlar a dos ninjas con un solo mando. Para desbloquear este modo, simplemente necesitas acabar el juego una vez (¡O usar un código!).

Así que tras más de un año de trabajo y 5491 líneas de código, ¡'Yo-Yo Shuriken' finalmente estaba terminado! La ROM del juego funcionaba sin problemas y la probé en varias versiones de la consola original (Japanese Super Famicom, US Super NES, PAL Super Nintendo); en versiones modernas (PAL modificada con el kit 50/60Hz de FFVIMan, Analogue Super NT); y en varios emuladores (Higan/BSNES, SNES9X, ZSNES, No$SNS, RetroArch, etc.) para varias plataformas (PC, smartphone, PSP, Raspberry Pi, etc.).

Una vez que la versión final del software del videojuego había sido validada (todos los bugs habían sido arreglados tras una fase beta de testeo bastante extensa), podía empezar la parte del hardware del proyecto. En otras palabras, el objetivo era hacer que el juego estuviera disponible en cartucho con su correspondiente caja de cartón. Pero antes de explorar esa parte del proceso, me gustaría dar más detalles sobre el proceso de desarrollo de este videojuego para la SNES.

Programando el juego

Crear juegos para plataformas retro es algo que tiene muchas limitaciones técnicas. Con las herramientas modernas la tarea se simplifica bastante en comparación con todo lo que tenían que hacer los desarrolladores en los 90. Sin embargo, todavía existen muchas limitaciones debido a las restricciones relacionadas con las especificaciones del hardware. Estas son las herramientas que utilicé y los principales problemas a los que me enfrenté. Espero que te sirvan de ayuda para hacerte una idea de cómo funciona la SNES por dentro.

Las herramientas del gremio

En los 90 los programadores de videojuegos tenían que aprender a utilizar el lenguaje ensamblador para cada consola con la que trabajaban y la SNES era una consola con la que era difícil trabajar, puesto que no solamente tenías que aprender un lenguaje, sino dos: el 65816 ensamblador para la CPU y el SPC700 ensamblador para el chip de audio.

A día de hoy es posible seguir usando ensamblador y es la única forma de sacarle el mayor partido a cualquier consola retro. Pero también puedes hacer juegos bastante vistosos con lenguajes de programación más sencillos, como C o Basic. Para la SNES, solamente existe un compilador de C: tcc816. No es perfecto y es necesario utilizar algunos scripts de python para mejorar y arreglar algunos bugs en el código, pero funciona. Alekmaul es un programador con mucho talento que a partir de este compilador creó toda una herramienta para facilitar la creación de videojuegos: la librería PVSNESlib.

La SNES era una consola con la que era difícil trabajar, puesto que no solamente tenías que aprender un lenguaje, sino dos: el 65816 ensamblador para la CPU y el SPC700 ensamblador para el chip de audio

Utilicé esta librería en el proceso de creación de 'Yo-Yo Shuriken' y así poder programarlo en lenguaje C. Para los gráficos, dibujé las imágenes BMP y luego las convertí al formato de gráficos de la SNES. Para el audio el programa aceptaba archivos .wav para los efectos de sonido y archivos .it (Impulse Tacker format) para la música. Fue todo un reto hacer un juego que funcione en la SNES, ¡pero pasó a ser "un reto difícil pero divertido" gracías a PVSNESlib!

¿Cómo funciona la SNES?

En comparación con otras consolas como la Mega Drive/Genesis o la PC Engine/TurboGrafx16, la SNES es una consola bastante compleja con muchos modos gráficos diferentes. Sin embargo, su procesamiento interno es bastante sencillo. Básicamente, la SNES puede mostrar gráficos a través de dos canales: el _"fondo"_ y los _"sprites"_.

El fondo es una imagen a pantalla completa hecha a partir de cuadros de 8x8. El fondo puede tener varias capas (de 1 a 4) que pueden desplazarse de forma independiente. La RAM de vídeo es limitada, así que normalmente tienes que transferir los datos gráficos de la ROM del cartucho a la RAM de vídeo a tiempo real para mostrar algunas zonas de _scroll_ infinitas o grandes.

En cuanto a los _sprites_, la SNES puede mostrar varios tamaños: 8x8, 16x16, 32x32 y 64x64 (solamente dos tamaños pueden mostrarse al mismo tiempo en pantalla). Para hacer que los _sprites_ se muevan tienes que establecer su posición de forma manual en la pantalla y modificar los datos gráficos que mostrarán, 60 veces por segundo. Para ello, al igual que con el fondo, primero deberás copiar los datos gráficos (parte de tu hoja de _sprites_) desde el chip del cartucho ROM a la memoria RAM de la consola.

En comparación con otras consolas como la Mega Drive/Genesis o la PC Engine/TurboGrafx16, la SNES es una consola bastante compleja con muchos modos gráficos diferentes

La SNES también puede reproducir audio gracias a un chip integrado (SPC700). Para la entrada de audio es bastante fácil leer qué botones los jugadores han presionado en los mandos de la SNES. (¡El mejor mando jamás diseñado!)

Al fin y al cabo, incluso utilizando una herramienta como PVSNESLib necesitarás estar familiarizado con el funcionamiento de la SNES si quieres hacer juegos para esta consola. Por suerte, la maravillosa comunidad de creadores de videojuegos amateurs han creado documentación muy extensa al respecto. Como por ejemplo:

  • La Wiki de PVSNESLib (En inglés). Te ayudará a la hora de configurar las herramientas y crear programas sencillos para la SNES
  • La guía NoCash SNES specs (En inglés. Bastante técnica, pero exhaustiva)
  • La sección SNESdev del foro NESdev (En inglés). Una comunidad colaborativa y llena de expertos ¡Me salvaron la vida más de una vez durante el proceso de creación de 'Yo-Yo Shuriken'!

Ahora que ya hemos cubierto algunos de los temas básicos podemos adentrarnos en algunos de los problemas técnicos a los que me enfrenté.

¿Cuántos enemigos se pueden mostrar en pantalla?

¡En un juego como 'Yo-Yo Shuriken', cuantos más _sprites_ haya en pantalla _(enemigos, explosiones, etc.)_ mejor será el juego! Sin embargo, no podemos permitir que se cuelgue. Así que es necesario hallar el número máximo de enemigos que puede procesar la CPU sin problemas en una pantalla de 60 FPS. Muchas veces se tacha a la SNES de "lenta" en comparación con la Genesis/Mega Drive (todo sea por el "Blast Processing"), algo que en cierto modo es verdad.

Aunque la SNES puede mostrar imágenes más coloridas y una mayor calidad de sonido, el tiempo de la CPU disponible suele ser más bajo que el de la Mega Drive. En otras palabras, la Mega Drive normalmente puede mover más sprites en pantalla que la SNES. El mejor ejemplo es la diferencia entre 'Contra III' (SNES) y IV (Mega Drive) y más específicamente la forma en la que cada juego gestiona las explosiones:

Las explosiones en el 'Contra III' para la SNES (primera imagen) están hechas con unos pocos sprites junto a un efecto gráfico especial (transparencia), mientras que el 'Contra IV' para la Mega Drive (segunda imagen) las representa con una cantidad increíble de sprites en pantalla

A la hora de programar en cada consola como debería ser, directamente en ensamblador, puedes notar esta diferencia en la capacidad de procesamiento, pero cuando usas un compilador de C como fue mi caso a la hora de crear 'Yo-Yo Shuriken', la diferencia se vuelve aún más obvia. Así que el número total de enemigos que podía mostrar en pantalla estaba limitado por el tiempo de CPU disponible.

Sin embargo, las tareas de la CPU no se limitan a la gestión de los sprites y también tiene que procesar las animaciones, la carga de datos gráficos a la RAM de vídeo, las colisiones, leer la entrada de los comandos del mando, activar los sonidos y la música en el chip de audio, etc. El desarrollo de 'Yo-Yo Shuriken' fue una lucha constante para mantener tantos enemigos como fuera posible en pantalla mientras que el resto de elementos se hacían con el tiempo total de la CPU disponible. De ahí que tuviera que reducir el número de enemigos varias veces a medida que iba introduciendo nuevas características en el juego.

Al principio, cuando solamente había robots estándar que caminaban en línea recta sin detector de colisiones, podía mostrar 80 enemigos en pantalla (además de un jugador y su shuriken). Cuando añadí la detección de colisiones entre enemigos, jugador y shuriken tuve que reducir el número a 40 enemigos.

Aunque la SNES puede mostrar imágenes más coloridas y una mayor calidad de sonido, el tiempo de la CPU disponible suele ser más bajo que el de la Mega Drive. En otras palabras, la Mega Drive normalmente puede mover más sprites en pantalla que la SNES

Al añadir el segundo jugador, las explosiones, los efectos de sonido y la música, la capacidad de la CPU se vio bastante reducida y finalmente la versión definitiva del juego solamente podía mostrar hasta 24 enemigos en la pantalla si quería mantener una buena cadencia a 60 FPS. Aunque en teoría parezcan pocos enemigos, jugando al juego te darás cuenta de que 24 enemigos son más que suficientes para que el juego sea todo un reto, sobre todo en los últimos niveles del juego.

Sinceramente, ser capaz de gestionar 38 _sprites_ animados en pantalla (24 enemigos + 2 jugadores + 2 shurikens + 10 explosiones) sin que se colgara el juego no deja de ser un logro. Sin embargo, este logro tiene su truco: no todos los sprites se actualizan en cada _frame_. De hecho, mientras que el jugador y el shuriken se actualizan 60 veces por segundo, los enemigos y las explosiones solo se actualizan cada dos _frames_ e incluso cada cuatro _frames_ en algunos casos. Este truco de programación era bastante común en los 90, puesto que permite propagar el procesamiento relacionado con las colisiones a través de varios _frames_ para mostrar más _sprites_ en pantalla sin ralentizar la visualización del juego.

¡LUT hace que los _sprites_ se muevan!

Aunque los enemigos estándar tienen unos patrones de movimiento sencillos, con movimientos en línea recta o diagonal, los jefes se mueven de una forma más compleja. Por ejemplo, muchos jefes cuentan con bolas dando vueltas a su alrededor.

Desde un punto de vista matemático, simplemente necesitas calcular el seno y el coseno de cada ángulo de bola para moverlas de forma circular. En una plataforma moderna este tipo de computaciones son sencillas y se pueden hacer rápidamente, pero en las plataformas retro es todo un reto. Las CPUs de las consolas de 8/16 bits no tienen funciones internas para computar el seno y el coseno en el hardware, así que tienes que computarlos en el software combinando muchos cálculos más complejos.

Es algo que obviamente lleva mucho tiempo. La SNES no permitiría computar el seno y el coseno de 24 enemigos a un ritmo de 60 fps mientras hace todo lo demás. A medida que las bolas se mueven lentamente, en realidad sólo se actualizan una vez cada 4 _frames_, reduciendo el número de cálculos de 24 a 6. Pero en este caso en concreto, sigue siendo demasiado: la CPU no puede computar 6 senos y 6 cosenos cada _frame_ mientras hace todo lo demás.

Por supuesto, existe un truco para solucionar este problema en particular que era muy común en los 90. Para reducir la carga de la CPU, simplemente puedes utilizar una _Look-Up Table_ en vez de tener que calcular el seno y el coseno en cada _frame_.

Dicho de otro modo, calculé previamente los valores del seno y del coseno para un gran número de ángulos utilizando un programa de hojas de cálculo en mi ordenador moderno para posteriormente almacenar dichos valores en una tabla gigante dentro de la ROM del juego. De esta forma, la CPU ahora puede leer los valores del seno y del coseno que necesita para mover las bolas en la ROM en vez de perder tiempo computándolos cada _frame_.

A esta tabla gigante de valores pre-calculados se la denomina "Look-Up Table" o LUT. Las LUT eran muy comunes en los juegos previos a la era 32 bits y no se limitan al seno y al coseno. Cualquier cosa que sea "lenta de computar" en una CPU normalmente se computará de antemano para así almacenar los resultados en una LUT: trigonometría, efectos de color, generador de números aleatorios, efectos de rasterización, etc...

Cuando llegaron las consolas de 32 bits el problema se solucionó gracias a que el hardware de la CPU permitía realizar cálculos de trigonometría en una memoria flash. De hecho, la trigonometría es una parte esencial de cualquier procesamiento basado en 3D y las consolas como la PlayStation o la Saturn requerían hacer dichos cálculos de forma rápida y repetida en cada _frame_. Leyendo esto, puede que te preguntes cómo era posible que la SNES procesara gráficos en 3D en juegos como 'Starfox'.

En este caso, una LUT no sería suficiente: son demasiados cálculos. Así que los creadores de 'Starfox' simplemente añadieron un nuevo procesador que pudiera computar trigonometría de forma rápida dentro del cartucho: ¡El famoso chip "Super FX"! La SNES no sería capaz de computar y mostrar en pantalla todos esos objetos en 3D sin el Super FX.

Pero 'Starfox' no es el único juego que utiliza un chip de este tipo. Super Mario Kart y Pilotwings utilizan otro chip con el mismo fin: el "DSP-1". Al igual que el Super FX, puede calcular operaciones de trigonometría más rápido que la CPU de la SNES. Mientras que el DSP-1 solamente se utiliza para realizar cálculos, el Super FX es mucho más potente y puede representar polígonos en un _framebuffer_ 2D, tal y como lo hacen la PlayStation y la Saturn.

¡Cuidado con el VBLANK!

Una vez que la CPU ha terminado con sus computaciones, le tiene que decir al chip de gráfico que muestre el resultado de sus cálculos en pantalla. Este es el funcionamiento de cualquier consola, independientemente de su fecha de salida al mercado. Sin embargo, los chips de las consolas de la era de los 8/16 bits tienen un comportamiento específico: la CPU solamente puede mandar datos al chip de gráfico durante un periodo de tiempo concreto: el "VBLANK". ¿Pero qué es el VBLANK?

En una televisión de tubo de rayos catódicos (las antiguas, vamos), la imagen se proyecta a través de un haz de electrones que se mueve de arriba a abajo y de izquierda a derecha. Mientras que el haz de electrones se mueve detrás de la pantalla para dibujar la imagen, muestra "píxeles" de un color específico utilizando las instrucciones del chip gráfico de la consola.

Sin este chip gráfico, el haz de electrones no sabría qué color mostrar y por lo tanto no se mostraría ninguna imagen en la pantalla. Una vez que el haz de electrones ha terminado de mostrar una imagen llega al fondo de la pantalla y entonces tiene que volver a la parte de arriba para empezar a mostrar una nueva imagen utilizando las instrucciones del chip gráfico. El intervalo de pausa del haz de electrones mientras vuelve a la parte de arriba de la pantalla se denomina "intervalo vertical" o VBLANK.

En una SNES, cuando el chip gráfico envía las instrucciones al haz de electrones, no puede realizar ninguna otra operación. Además, ni siquiera puedes modificar la memoria de vídeo, puesto que contiene la imagen a mostrar en pantalla. De hecho, el chip gráfico la necesita para controlar el haz de electrones.

Si de alguna forma conseguimos modificar la memoria de vídeo mientras el chip gráfico muestra la imagen en pantalla, mostraría una imagen corrupta o algo peor. De ahí que la SNES esté diseñada para prevenirlo: la CPU simplemente no puede acceder a la memoria de vídeo al mismo tiempo que el chip gráfico muestra una imagen. La CPU necesita esperar al intervalo vertical para poder enviar los datos gráficos a la nueva imagen a mostrar en pantalla en la memoria de vídeo y dicho intervalo es bastante breve.

Entonces, ¿cuáles son las consecuencias reales de todas estas limitaciones relacionadas con el VBLANK? Dicho de forma sencilla, se trata de otra ardua limitación en el tiempo total disponible del desarrollador de videojuegos para mostrar su juego en pantalla. Lo primero de todo, para prevenir que el juego se cuelgue, necesitas realizar todos los cálculos de la jugabilidad (colisiones, movimientos, animaciones, etc.) entre dos intervalos VBLANK. Si el código del juego tarda más tiempo en ser procesado, no podrás mostrar el _frame_ resultante a tiempo y el juego se ralentizará de forma visible en pantalla.

Pero una limitación aún más complicada es que solamente puedes mandar unos pocos datos gráficos a la memoria de vídeo durante cada intervalo vertical. De hecho, la velocidad de transferencia de los datos gráficos está limitada por lo que se denomina como "bus". El "bus" es el cable físico electrónico que conecta todos los chips. Si intentas enviar más datos de los que es posible transferir durante el intervalo VBLANK, los datos adicionales simplemente se cortarán y no se mostrarán en pantalla.

Un bug brutal: la trampa de 50Hz/60Hz

Pude experimentar las limitaciones del VBLANK de primera mano durante la creación de 'Yo-Yo Shuriken'. Fue la causa de una de los bugs más brutales con los que me encontré durante todo el proyecto. Durante el testeo beta utilizando el emulador ZSNES y mi propia consola todo se mostraba sin problemas. Sin embargo, cuando probé el juego en otros emuladores con fama de ser más precisos que ZSNES, a saber SNES9X y Higan/BSNES, algunos de los sprites no se mostraban en pantalla. Específicamente, las explosiones habían sido "cortadas" tal y como puedes ver en las siguientes imágenes:

ZSNES y mi consola (arriba) / BSNES-Higan (abajo)

Me pasé semanas intentando resolver el problema sin éxito alguno. Finalmente fui capaz de arreglarlo gracias a la ayuda de los cracks del foro SNESDev. La comunidad de SNESDev me ayudó más de una vez durante este proyecto y no podría estar más agradecido de toda la ayuda que me ofrecieron. Se dieron cuenta de que el motivo del problema era simplemente que estaba enviando demasiados datos al chip gráfico por _frame_.

El tiempo necesario para transferir todos los datos superaba al tiempo del intervalo vertical y por eso las animaciones de las explosiones no tenían tiempo de llegar al chip gráfico antes de que finalizara el intervalo vertical y simplemente no aparecían. Pero te preguntarás por qué este bug solamente aparecida en un emulador en concreto y no en la propia consola.

Ahí es donde el bug se convierte en un rompecabezas. Como todos los amantes de la SNES que viven en Europa, mi consola de la infancia funciona en formato PAL a 50Hz. En otras palabras, el chip gráfico de la consola muestra una nueva imagen en pantalla 50 veces por segundo. En EE.UU. y en Japón, el formato de televisión es diferente: NTSC a 60Hz.

De ahí que las consolas para NTSC muestren una nueva imagen en pantalla 60 veces por segundo. ¿Significa que los juegos estadounidenses y japoneses van más rápido que los europeos? Desafortunadamente, así es (pero no lo sabíamos en los 90...) Pregúntale a cualquier fan de los juegos de lucha y te explicará por qué las versiones NTSC de los juegos son mejores: más rápidas, más fluidas, sin bordes negros, etc...

No obstante, el formato PAL tiene una ventaja sobre el formato NTSC. Como el sistema PAL reproduce 50 imágenes por segundo en vez de 60, el haz de electrones se mueve más lento y por eso el intervalo vertical dura más tiempo en las consolas PAL que en las NTSC. Por eso puedes transferir más datos de gráficos por _frame_ en una consola PAL en comparación con un modelo NTSC.

Resulta que esta era la causa principal de mi bug. Cuando probé el juego en mi consola de la infancia, a 50Hz, los _sprites_ de explosiones se mostraban sin problema porque el intervalo VBLANK era lo suficientemente largo para que todos los datos se pudieran transferir sin problemas. Pero en BSNES/Higan, un emulador extremadamente preciso a 60Hz, los _sprites_ se quedaban fuera debido a que el intervalo vertical era más breve y no se podían transferir todos los datos a tiempo. Sin embargo, ¿por qué ZSNES, que también va a 60Hz, mostraba los _sprites_ sin problema?

Bueno, simplemente porque ZSNES es un emulador más antiguo y menos preciso a la hora de reproducir todas las limitaciones técnicas de la SNES. Por ejemplo, ZSNES no te impide modificar el contenido de la memoria de vídeo fuera del VBLANK: ¡Una diferencia técnica importante en comparación con la verdadera consola! Al final, este problema me enseñó lo importante que es utilizar emuladores precisos a la hora de elaborar juegos caseros y que nada puede reemplazar al testeo en el hardware de verdad y en todas las versiones de hardware. Por eso me tuve que comprar una SNES extra a "60Hz" para poder testear el juego bien a fondo.

Creando un producto físico: los cartuchos

Para mí, un proyecto casero no está del todo completado hasta que el usuario puede introducir un cartucho real del juego en su propia consola de la infancia. ¿Cómo es posible producir una copia física para una consola cuyo único fabricante de cartuchos, Nintendo, cesó su producción hace unos 20 años?

La respuesta es simple: ¡tienes que hacerlo tú mismo! Para esta parte, trabajé mano a mano con un mago de la electrotécnica llamado Catskul. Yo ya había diseñado cartuchos para mis juegos para la Game Boy, pero para este proyecto, Catskull diseñó un nueva placa de circuito impreso para la SNES desde cero. Solamente utilizó componentes de primera mano, en concreto Flash ROM. Todos los cartuchos están hechos a mano y a modo de ejemplo pongo la explicación en detalle de todo el proceso de montaje con fotos:

1) Placa de circuito impreso virgen

Empecemos desde el principio: la PCB virgen. Catskull pide las placas de circuito impreso fabricadas de forma profesional y las recibe "vírgenes", tal y como se muestra en la siguiente foto:

2) Poniendo la pasta de soldar

Para añadir componentes (como pueden ser los chips electrónicos) a la PCB, primero tienes que poner la pasta de soldar: un "pegamento" que acoplará los chips a la PCB. Se trata de una tarea meticulosa y para ello Catskull utiliza una máscara para poner la pasta solamente donde sea necesario.

Como resultado, la placa de circuito impreso ahora tiene la pasta de soldar en todas las partes que van a sostener los componentes:

3) Posicionando los componentes

Esta es otra tarea meticulosa. Todos los componentes (chips) tienen que ser posicionados en la PCB. Catskull trabaja en 5 PCBs al mismo tiempo (lo entenderás en el siguiente paso). Aquí las PCBs sin componentes:

Y las mismas PCBs con todos los chips posicionados en el lugar que les corresponde:

4) ¡Cartuchos al horno!

La pasta de soldar es como un cemento para los chips electrónicos. Cuando se posiciona todavía está "húmeda", de modo que puedes reubicar los chips en caso necesario. Para terminar las PCBs, necesitas secar la pasta con un horno. Así que técnicamente hablando, el último pasa del proceso de montaje es "hornear" los cartuchos:

5) Poniendo la ROM del juego

Ahora que el circuito electrónico está listo y funcionando, podemos escribir la ROM del juego en el chip de memoria. Para ello, Catskull utiliza el maravilloso INLretro Dumper-Programmer de Infinite NES Lives. Para aquellos que no le conozcan, Infinite NES Life es otro crack de la electrotécnica que ha creado muchos componentes de hardware para NES y SNES. Ha publicado varios juegos caseros para la NES de alta calidad, es un patrocinador del concurso anual NESDev y vende PCBs y cartuchos de NES y SNES para personas que quieren hacer juegos caseros.

Tanto a Catskull como a mí nos gustaría dar las gracias a Infinite NES Lives por su apoyo en este proyecto. Lo primero de todo, ayudó a Catskull a arreglar las clavijas de la PCB. También añadió el soporte para la PCB de Catskull en su flasher y así poder utilizarlo para fabricar nuestro juego. Y por último nos proporcionó el chip CIC necesario para montar cartuchos que pueden utilizarse en las consolas originales. Así que gracias a INL Catskull pudo transformar de forma sencilla su PCB montada a mano en un cartucho para la SNES con 'Yo-Yo Shuriken' y que funciona:

6) Poniendo la PCB en la carcasa

Para completar el montaje del cartucho, Catskull pone la PCB dentro de la carcasa. Como puede que ya sepas, las ediciones comerciales para la SNES de los 90 tenían dos variantes de carcasas de cartucho. Las ediciones japonesas y europeas tenían las esquinas redondeadas, mientras que las estadounidenses eran un poco más grandes y más rectangulares. Por supuesto, no puedes introducir un cartucho japonés/europeo en una consola estadounidense y viceversa.

Para 'Yo-Yo Shuriken' queríamos hacer una única versión internacional, así que tuvimos que usar una carcasa que pudiera ser introducida en ambas variantes de la consola. Afortunadamente, hay gente que ha diseñado "carcasas universales" que pueden introducirse en todos los modelos de la consola. Por ejemplo, es fácil encontrar dichas carcasas en China a un precio bastante bajo. Sin embargo, queríamos materiales de buena calidad y Catskull tuvo la suerte de encontrar un proveedor en Estados Unidos que diseñó sus propias carcasas universales para la SNES hechas con plástico de buena calidad.

Obviamente estas carcasas son más caras, pero cuando las tienes en la mano te ofrecen una sensación de ser "robustas", la misma que los cartuchos originales. Para nosotros es algo que justifica el coste extra y además esas carcasas de buena calidad también le aportan un toque extra al lanzamiento de 'Yo-Yo Shuriken': solamente están disponibles en rojo. Aunque me sorprendí al principio, ahora me parece algo chulo y es un guiño a los ojos rojos brillantes de los robots enemigos del juego. Aquí unas fotos de las carcasas (parte delantera/parte trasera):

Por supuesto, la carcasa del cartucho también requiere una pegatina con el nombre del juego, pero es algo que veremos en la siguiente sección. Para finalizar esta parte del proceso de montaje de la PCB, dejo un problema al que tuvo que enfrentarse Catskull durante el montaje la primera copia:

"Lo único es que las PCBs de la SNES tienen sus componentes en la parte trasera (en la parte opuesta a ti cuando está dentro de la consola). Así que en todas esas fotos, estoy trabajando en la parte trasera de la PCB. En la primera la conecté sin querer al revés a la consola porque no la tenía en la carcasa ¡Y se fundieron los componentes de la PCB!"

Tener la placa base es solamente el primer paso hasta conseguir crear un cartucho completo. Hace falta poner las PCBs en carcasas, con un etiquetado impecable y presentarlo todo en una caja de cartón con su manual. Mientras Catskull estaba ocupado diseñando y montando a mano los cartuchos, yo me dediqué a diseñar la etiqueta del cartucho, el manual y la caja de cartón por mi cuenta.

El diseño

No soy para nada un artista, pero uno de los placeres de los proyectos amateur/caseros es hacer todo lo posible por tu cuenta, así que me animé a hacer todo cuanto estuviera posible en mis manos y me decidí a dibujar el diseño yo mismo. Empecé con unos bocetos en papel:

Posteriormente escaneé este garabato y lo redibujé en el ordenador utilizando un software para dibujar con vectores:

Una vez finalizado el diseño, lo utilicé para diseñar la caja, el manual y la etiqueta del cartucho. La versión final de todos estos elementos fue impresa de forma profesional en Estados Unidos pero durante la fase de diseño tuve que imprimir los prototipos por mi cuenta.

El manual

Para el manual utilicé los juegos de los 90 a modo de referencia para crear algo lo más auténtico posible. Sin embargo, tuvimos que hacer algunas concesiones puesto que queríamos producir una versión única para todos los países (nada de variantes EEUU/Japón/Europa como antaño). El resultado final es una mezcla del estilo de diseño estadounidense y del europeo de los 90. Por ejemplo, la mayoría de los lanzamientos en EE.UU. tenían cajas y manuales negros, mientras que los europeos tenían un fondo de colores. Aquí algunas páginas de ejemplo del manual:

La caja

Para la caja, también utilicé una mezcla del diseño europeo y estadounidense con el mismo color que el manual. Tuve que imprimir los prototipos con mis propios medios para asegurarme que el tamaño fuera el correcto. Para el manual, pude hacerlo sin problemas con mi propia impresora, pero para la caja necesitaba tamaño A3.

También tuve que imprimir la caja en cartón para poder montarla, así que fui a una copistería de mi barrio para imprimir la caja en una lámina de cartón A3 y posteriormente la monté en mi casa. Tuve que hacer varias versiones antes de conseguir el tamaño exacto de un juego original de la SNES de los 90, pero finalmente lo conseguí. Aquí una foto del último prototipo de la caja:

Una vez completado el prototipo de la caja y con el visto bueno de Catskull, encontramos un proveedor en Estados Unidos que podía hacer los componentes con materiales profesionales. Nos alegramos mucho de encontrar un proveedor que pudiera imprimir las cajas en un material de cartón parecido al de los juegos de los 90.

Si abres una caja del 'Yo-Yo Shuriken', verás que el interior es gris/marrón, como los juegos de los 90 y no blanco como la mayoría de cartón básico. Cada caja ha sido impresa y montada a mano en los Estados Unidos por nuestro proveedor (una operación en la que solo se vieron involucradas dos personas), que le envió las cajas ya preparadas a Catskull. Posteriormente Catskull añadió el manual y el cartucho y así conseguir la copia física final de 'Yo-Yo Shuriken' que puedes ver aquí:

Finalmente y teniendo en cuenta todos estos pasos, ¡La creación de 'Yo-Yo Shuriken' me llevó casi dos años de duro trabajo! Espero que hayas disfrutado leyendo este artículo. Para mí fue toda una odisea y me alegra poder compartir el proceso en Internet con la esperanza de que servirá de inspiración y motivará a otros desarrolladores a hacer nuevos juegos para la SNES.

Si te apetece jugar a 'Yo-Yo Shuriken' en tu propia consola o simplemente quieres apoyar mi trabajo, puedes comprar el juego físico con su caja directamente de Catskull Games. Si prefieres jugar al juego en un emulador, puedes comprar la versión ROM.

Este artículo se trata de una republicación íntegra del artículo "Making a SNES game in 2020" escrito por Doctor Ludos.

Doctor Ludos es un diseñador de videojuegos indie/amateur y miembro de Ludoscience, un laboratorio de investigación científica dedicado al estudio de los videojuegos. Tiene un Patreon donde puedes apoyar su desarrollo de juegos y también edita una newsletter con sus lanzamientos. Puedes encontrar todos sus videojuegos retro aquí.

Foto | iStock

Portada de Xataka