Kirin: ejecutando RPG Maker XP en Android
Cómo un motor nacido para Windows puede ejecutarse sobre Ruby moderno, ARM64 y las GPU de los dispositivos Android.
RPG Maker XP nació para una época muy diferente.
Cuando apareció, su entorno natural era Windows. Los juegos creados con él estaban pensados para ejecutarse en un PC, con una arquitectura de escritorio, API propias de Windows y un intérprete de Ruby integrado mediante RGSS. Incluso los requisitos oficiales de RPG Maker XP estaban centrados exclusivamente en Windows.
Más de dos décadas después, intentar ejecutar uno de esos mismos juegos en un teléfono Android plantea un problema interesante.
Android no entiende RPG Maker XP.
No posee RGSS. No utiliza las mismas API de Windows. Su sistema de archivos funciona de otra manera. La entrada táctil no se parece a un teclado. El manejo del audio es diferente. La GPU se encuentra detrás de interfaces gráficas pensadas para dispositivos móviles. Y, además, gran parte del código de juegos como los desarrollados con Pokémon Essentials está escrito en Ruby y fue creado suponiendo que se ejecutaría dentro de un entorno Windows.
Ahí comienza Kirin.
No se trata de emular Windows
Una primera solución podría parecer evidente: emular un PC completo dentro del teléfono.
Pero Kirin toma otro camino.
En lugar de intentar reproducir Windows entero, construye directamente en Android el entorno que necesita el juego.
Esto reduce enormemente la cantidad de elementos que hay que reproducir. El juego continúa utilizando sus mapas, eventos, sprites, scripts y recursos originales, pero las funciones que antes dependían del entorno de RPG Maker XP son implementadas por un motor moderno.
La base histórica de este sistema es mkxp y, posteriormente, mkxp-z. Este último es una versión profundamente modificada de mkxp creada con uno de los problemas más difíciles del ecosistema RGSS en mente: ejecutar proyectos complejos y, en particular, juegos basados en Pokémon Essentials. El proyecto mkxp-z explica que ese fue uno de sus objetivos originales por la fuerte dependencia de Essentials de las API de Windows.
Pero mkxp-z no es Kirin. El proyecto upstream anuncia compatibilidad con Windows, Linux y macOS, no con Android. Kirin parte de ese trabajo y lo evoluciona para un entorno móvil específico.
Esta diferencia es importante. Kirin no distribuye juegos ni sustituye sus archivos: proporciona el entorno que permite ejecutar en Android proyectos compatibles que el usuario ya posee.
El primer gran problema: Ruby
En un juego convencional podría pensarse que la mayor parte del trabajo ocurre en la GPU. En RPG Maker XP no siempre es así.
Detrás de lo que aparece en pantalla existe una enorme cantidad de código Ruby ejecutándose continuamente:
- Mover al personaje
- Actualizar un evento
- Abrir un menú
- Calcular una batalla
- Actualizar un sprite
- Comprobar una colisión
- Ejecutar una animación
- Procesar un NPC
Todo eso puede terminar pasando por Ruby. Pokémon Essentials lleva esta característica mucho más lejos: sobre la base de RPG Maker XP construye mediante scripts sistemas de combate, criaturas, habilidades, objetos, mapas, interfaces y numerosas mecánicas adicionales.
Así, un juego puede mostrar una escena 2D relativamente sencilla mientras el procesador realiza miles de operaciones Ruby detrás de ella. Por eso una GPU más potente no soluciona necesariamente un juego lento.
Ruby tarda demasiado → el siguiente frame no puede comenzar → la GPU espera → aparecen caídas de FPS.
Y es aquí donde Kirin comienza a separarse todavía más del entorno original de RPG Maker XP.
De un Ruby antiguo a un Ruby moderno
El código de muchos juegos de RPG Maker XP fue escrito pensando en versiones de Ruby extremadamente antiguas. Sin embargo, ejecutar eternamente un intérprete de aquella época también significa renunciar a más de veinte años de evolución del lenguaje y de su máquina virtual.
Kirin busca conservar el comportamiento que espera el juego mientras utiliza una base moderna de CRuby/MRI. Esto no es simplemente cambiar un número de versión.
Actualizar Ruby puede romper comportamientos antiguos. Algunos métodos han cambiado, ciertas tolerancias del parser desaparecieron, la codificación de cadenas funciona de otra manera y determinados scripts dependen de comportamientos que originalmente ni siquiera estaban documentados. Pokémon Essentials, además, acumula una enorme cantidad de código escrito a lo largo de años.
Por eso la compatibilidad de Kirin no consiste únicamente en utilizar un Ruby más reciente. Consiste en conseguir que software escrito para un Ruby antiguo siga comportándose correctamente sobre uno moderno. mkxp-z ya sigue la línea de utilizar MRI como implementación de Ruby; Kirin lleva esa filosofía a Android y la combina con distintos perfiles de runtime según las necesidades del proyecto.
De interpretar Ruby a compilarlo mientras el juego funciona
Aquí aparece una de las diferencias más interesantes entre el Ruby de la época de RPG Maker XP y el Ruby moderno. El código ya no tiene por qué permanecer siempre interpretado.
Ruby dispone de compiladores JIT, o Just-In-Time, capaces de detectar código que se ejecuta repetidamente y transformarlo en código máquina nativo.
Para un teléfono moderno esto resulta especialmente interesante. La mayoría de los dispositivos Android actuales utiliza procesadores ARM64. Tanto YJIT como el nuevo ZJIT de CRuby poseen soporte upstream para ARM64/AArch64, aunque la documentación oficial de ZJIT enumera actualmente macOS, Linux y BSD, no Android. Hacerlos funcionar correctamente dentro de Kirin exige integración específica: no basta con activar una opción.
YJIT es la opción establecida dentro del Ruby moderno y ya forma parte de uno de los runtimes de Kirin. ZJIT representa una nueva generación todavía en desarrollo: un compilador basado en métodos y perfiles de ejecución, con una representación intermedia diseñada para permitir optimizaciones progresivamente más agresivas. En Kirin, ZJIT es una línea de integración y experimentación, no una promesa de aceleración automática para todos los juegos.
Esto abre una posibilidad que RPG Maker XP nunca tuvo: que el propio código Ruby de un juego pueda convertirse dinámicamente en código nativo del procesador del teléfono mientras se juega.
El JIT tiene un coste. Necesita observar el programa, detectar código frecuente, compilarlo y reservar memoria ejecutable. Pero los juegos poseen una característica favorable: repiten las mismas rutas una y otra vez. El mismo método de actualización, el mismo sistema de sprites, el mismo código de eventos o de batalla, el mismo update, frame tras frame, durante minutos o incluso horas.
Ese tipo de carga es precisamente donde un JIT puede empezar a resultar interesante.
Pero Ruby es solamente una parte
Aunque consiguiéramos ejecutar todo el código Ruby instantáneamente, todavía quedaría otro problema: hay que dibujar el juego.
RPG Maker XP nació para un PC Windows. Kirin se ejecuta dentro de un teléfono cuya GPU puede ser Mali, Adreno, PowerVR u otra arquitectura móvil. Entre ambos mundos debe existir una traducción.
El juego continúa pensando en conceptos conocidos por RGSS: Bitmap, Sprite, Viewport, Tilemap, Plane y Window. Pero el teléfono finalmente necesita recibir comandos que su GPU pueda ejecutar.
La ruta de producción actual de Kirin realiza ese trabajo mediante un renderer nativo basado en OpenGL ES 3. Vulkan representa una posible evolución futura, no una tecnología que este artículo dé por terminada. Ese matiz importa: cambiar de API gráfica no sustituye el trabajo de compatibilidad ni garantiza por sí solo más rendimiento.
- Pokémon Essentials
- Scripts Ruby
- CRuby / YJIT / experimentos con ZJIT
- Bindings de Kirin
- Motor derivado de mkxp-z
- Renderer adaptado a Android
- OpenGL ES 3
- Driver de la GPU
- Pantalla
Cada flecha de esa cadena representa un lugar donde puede aparecer un problema de rendimiento o compatibilidad. Ese es el verdadero trabajo de Kirin: no simplemente conseguir que RPG Maker XP “abra” en Android, sino hacer que un ecosistema construido alrededor de tecnologías de hace más de veinte años pueda convivir con Ruby moderno, ARM64, compilación JIT y GPU móviles sin que el juego tenga que reescribirse desde cero.
Qué ocurre realmente durante un frame en Kirin
Para entender dónde se consume el tiempo hay que observar una sola vuelta del juego. Un frame no comienza en la GPU: comienza recogiendo el estado del mundo.
1. Android recoge la entrada
La pantalla táctil, un mando físico o el teclado virtual producen eventos Android. Kirin los convierte en el conjunto de acciones que espera RGSS: direcciones, aceptar, cancelar, abrir un menú o ejecutar una función asignada. Esa traducción debe mantener pulsaciones, repeticiones y diagonales de forma consistente.
2. Ruby actualiza el juego
El bucle del proyecto ejecuta la lógica de la escena actual. Se consultan eventos, interruptores y variables; se actualizan personajes y NPC; se calculan colisiones; se procesa la interfaz; y se decide qué ha cambiado. En un proyecto grande esta fase puede invocar una enorme red de métodos Ruby antes de dibujar nada.
3. RGSS actualiza la escena visual
Los scripts modifican objetos gráficos. Un sprite cambia de posición o de bitmap, un viewport altera su tono, un tilemap avanza sus autotiles y una ventana redibuja su contenido. Los bindings de Kirin traducen esas operaciones Ruby a estructuras nativas que el renderer puede utilizar.
4. El renderer organiza el trabajo
El motor ordena elementos por profundidad, aplica recortes y transformaciones, prepara texturas, selecciona shaders y agrupa operaciones que pueden enviarse juntas. Reducir cargas duplicadas, cambios de estado y transferencias de datos es esencial en una GPU móvil, especialmente en mapas con muchos sprites y capas.
5. La GPU compone la imagen
OpenGL ES entrega los comandos al driver. La GPU procesa vértices, texturas, mezclas, tonos y efectos hasta producir la imagen final. Después, Android presenta esa imagen en la pantalla y el ciclo comienza de nuevo.
Todos los pasos comparten el mismo presupuesto. Si la lógica Ruby llega tarde, la GPU puede quedarse esperando. Si el renderer genera demasiado trabajo, optimizar Ruby no bastará. Si el driver se bloquea, el tiempo ahorrado en las capas anteriores desaparece.
Por eso Kirin no persigue únicamente un contador alto de FPS. RPG Maker XP vincula buena parte de su lógica a una cadencia concreta; mantener tiempos estables ayuda a que movimiento, animaciones, audio y respuesta de los controles permanezcan sincronizados. Un frame rápido seguido de otro demasiado lento puede sentirse peor que una secuencia ligeramente inferior pero constante.
YJIT, ZJIT y el cuello de botella real
YJIT y ZJIT atacan la parte Ruby de la cadena, pero lo hacen desde diseños diferentes. YJIT compila bloques de código frecuentes y puede volver al intérprete cuando encuentra una situación que no ha especializado. ZJIT trabaja por métodos y utiliza perfiles para construir una representación intermedia sobre la que aplicar optimizaciones.
La comparación útil para Kirin no es cuál obtiene el número más grande en un benchmark aislado. Importan el tiempo de calentamiento, el consumo de memoria, la cantidad de código del juego que permanece dentro del JIT, la estabilidad en ARM64 y la compatibilidad con scripts reales. Un fangame puede pasar mucho tiempo repitiendo unos pocos métodos; otro puede recorrer rutas muy variadas y ofrecer menos oportunidades de compilación.
La medición debe atravesar todo el frame. Si Ruby domina el tiempo de CPU, un JIT puede abrir margen. Si la carga está en la preparación de tilemaps, la subida de texturas o el driver gráfico, la solución estará en otro nivel. Kirin puede mejorar precisamente porque controla toda la cadena, desde el runtime seleccionado hasta la presentación de la imagen.
Compatibilidad y rendimiento avanzan juntos
Pokémon Essentials demuestra hasta dónde puede llegar un proyecto de RPG Maker XP. Sus distintas generaciones, los plugins de la comunidad y los sistemas creados por cada fangame forman ecosistemas propios. Una corrección válida para una versión puede ser innecesaria —o incluso incorrecta— para otra.
Kirin combina compatibilidad general con ajustes dirigidos cuando un proyecto utiliza un patrón conocido. Puede adaptar una llamada ausente, corregir una suposición de Windows o acelerar una ruta que se ejecuta muchas veces por frame. Estos cambios se evalúan procurando no modificar las reglas, los datos o la identidad del juego.
También hay límites deliberados. Kirin es un runtime, no una tienda: no incluye proyectos, gráficos, música ni datos de terceros. Cada persona debe utilizar archivos que tenga derecho a usar. Separar la aplicación de los juegos mantiene claro qué aporta Kirin y qué pertenece a sus respectivos autores.
Dos generaciones de software, una misma pantalla
Cuando un juego de Pokémon Essentials comienza a ejecutarse en Kirin, dos generaciones de software funcionan al mismo tiempo: el código de un motor nacido para Windows hace más de veinte años y una plataforma Android moderna ejecutándolo sobre hardware que RPG Maker XP nunca pudo imaginar.
Ruby debe entender scripts antiguos y modernos. RGSS necesita una implementación compatible. El motor gráfico debe hablar con una GPU móvil. La entrada, el audio y los archivos tienen que integrarse con Android. Kirin reúne esas piezas, absorbe sus diferencias y las traduce para que el proyecto pueda concentrarse en lo que siempre fue importante: el juego.
Prueba Kirin en Android
Consulta la guía de instalación y añade un proyecto compatible a tu biblioteca.
Ver guía de instalación