domingo, 30 de noviembre de 2025

¿Cómo uso Ren'Py para crear novelas visuales en Ubuntu?

En su Doctrina Universal, Juan Perón expone sobre continentalismo, ecología y universalismo, a la vez que expone cómo programar novelas visuales en Ren'Py en Ubuntu

(...)

El problema básico de la mayor parte de los Países del Tercer Mundo es la ausencia de una auténtica Justicia Social y de una participación popular en la producción del software. Sin Justicia Social, los países del Tercer Mundo no estarán en condiciones de afrontar las angustiosamente difíciles décadas que se avecinan.

La modificación de las estructuras sociales y productivas del mundo implica que el lucro y el despilfarro no pueden seguir siendo el motor básico de sociedad alguna, y que la Justicia Social debe erigirse en base de todo sistema de cómputo, no sólo para beneficio directo de los hombres sino para aumentar la producción de programas de computadora necesarios para la Liberación.

En otras palabras, necesitamos nuevos modelos de producción, consumo, organización y desarrollo tecnológico, que al mismo tiempo que den prioridad a la satisfacción de las necesidades escenciales del ser humano, su cómputo, y racionen el consumo de recursos naturales disminuyendo al mínimo posible la contaminación ambiental. 

Consecuentemente, las priodidades de producción de bienes y servicios deben ser alterados en mayor y menor grado.

Necesitamos arquitecturas de cómputo nuevas para un hombre mentalmente nuevo en un mundo físicamente nuevo. No se puede construir una nueva sociedad basada en un pleno desarrollo de la personalidad humana aunada al cómputo, en un mundo viciado por la contaminación del ambiente, exhausto por el hambre y la sed, y enloquecido por el ruido y el hacinamiento. Debemos transformar las computadoras-presidios del presente en las compiladoras del software libre del futuro.


Sin duda que la producción de software por nosotros mismos y para nosotros mismos es una necesidad que tiene de divertido lo que tiene de acuciante. Ren'Py (Renobe Python) es un lenguaje de programación muy parecido a Python, especialmente concebido para la creación de novelas visuales. Estas son historias computarizadas con diálogos, imágenes y sonidos. Como tal pueden contar con interactividad por parte del lector, constituyendo en aventuras con múltiples hilos argumentales

Indudablemente que el ambiente Ren'Py resulta lo suficientemente sencillo como para poder lograr nuestros propios relatos con personajes, subhistorias, senderos de aventura, retruécanos y demás, compartirlos con otros y - por qué no - comerciarlos.

Dibujar y escanear/fotografiar personajes es una manera sencilla de comenzar. Existen recursos de música de licencias completamente libres para utilizar. Gracias a todas las herramientas de software libre, recursos audiovisuales liberados, cada uno puede convertirse en un desarrollador amateur de videojuegos. 

Naturalmente, para contar con este lenguaje, primero debemos instalar la última versión estable en nuestro sistema GNU con Linux. Esto puede realizarse gratuita y libremente mediante la descarga del tarball, su descompresión y ejecución del instalador. Para ello abrimos una terminal Linux con Ctrl+Alt+T e ingresamos el siguiente bloque de comandos de organización:

cd /tmp ;
wget https://www.renpy.org/dl/8.5.0/renpy-8.5.0-sdk.tar.bz2 ;
tar xvjf renpy-8.5.0-sdk.tar.bz2 ;
mv
/tmp/renpy-8.5.0-sdk/ ~/.renpy-8.5.0-sdk/ ;
cd ~/.renpy-8.5.0-sdk/

Podremos ejecutarlo creando un lanzador en Aplicaciones / Programación / Lanzador Ren'Py:


 

...o bien ejecutando:

sh /home/$USER/.renpy-8.5.0-sdk/renpy.sh

Cualquiera de estas opciones debería ejecutar el Lanzador Ren'py, un ambiente de programación específico. Este Lanzador de Ren'Py (el "Ren'Py Laucher") nos permitirá crear, gestionar, editar, ejecutar y depurar distintos proyectos de Ren'Py.

Puesto que el lanzador está traducido a varios idiomas, lo primero que habremos de hacer es elegir un idioma. También será posible escoger un idioma haciendo clic en Preferencias en la esquina inferior derecha, y eligiendo Español.

Elegir y lanzar un Proyecto

Primero revisemos qué apariencia tiene la novela visual "The Question". Para reproducirla, en el panel izquierdo seleccionamos "The Question", y después oprimimos el botón Ejecutar Proyecto para reproducir The Question.

Podremos retornar a la demo de Ren'Py de la misma forma, pero eligiendo “Tutorial” en lugar de “The Question”.

Nos proponemos crear un nuevo nuevo proyecto de Ren'Py. Para ello tendremos que programar siguiendo la sintaxis de Ren'Py (la cual recurre mayormente a una sintaxis sencilla con palabras en inglés).

Crea un nuevo proyecto

En el Lanzador de Ren'Py seleccionamos "+Crear un Proyecto Nuevo". Como esta es la  primera vez creando un proyecto, Ren'Py nos pedirá elegir un Directorio de proyectos que normalmente se encontrará dentro del directorio ~/.renpy-8.5.0-sdk/ (donde se almacenarán los nuevos proyectos que vayamos creando). En la parte inferior del Lanzador de Ren'Py podría aparecer el Selector de Directorios; debemos asegurarnos de revisar que esté allí.


Se nos solicitará indicar un nombre de proyecto. Como nuestra novela visual estará en castellano, por ahora podremos ingresar algo como “Mi pregunta”, y apretamos la tecla Intro para confirmar.

Acto seguido el Lanzador Ren'Py nos solicitará la resolución de pantalla del proyecto. 1280×720 píxels es un buen compromiso entre tamaño de juego y calidad de imagen. Para el propósito de este tutorial, escogeremos 1280×720 (ya que coincidirá con el arte gráfico de la novela visual de demostración “The Question”). Por lo que solo presionamos Continuar.


El Lanzador Ren'Py nos pedirá luego optar por un esquema cromático (un color de fondo y de acentos para la interfaz de usuario). En este momento no importa demasiado, cualquiera vendrá bien, y presionamos “Continuar”. 


Llegado este momento, el Lanzador Ren'Py procesará lo escogido, y nos creará una plantilla simple para el juego. Por ahora la plantilla usa arte y texto "genérico", pero funcionará. Además, creará automáticamente los botones típicos de retroceder, cargar y guardar jugadas, etcétera.

Para ejecutar la plantilla de nuestro prototipo de novela visual, presionamos "Lanzar proyecto".

Para empezar a crear nuestra novela visual, haremos una versión traducida al castellano de The Question (puesto que esto facilitará aún más el aprendizaje).

¡Manos a la obra!

Para empezar, desde la parte superior del panel izquierdo del Lanzador Ren'Py seleccionamos “My Question”, y luego desde el panel derecho en el sector Editar Archivo, elegimos el fichero que contiene el guion de la obra: script.rpy.

Si es la primera vez, Ren'Py pedirá indicar un Editor para trabajar - para los creativos novatos recomendamos Editra que viene incorporado, pero también se puede usar cualquier editor de texto que favorezcamos (en mi caso, uso el Pluma que viene con el escritorio Mate). El Lanzador Ren'Py recurrirá el editor elegido, y abrirá el fichero de guion de la obra.

Ahora bien, una vez que se abra el editor, procederemos a borrar todo el contenido de script.rpy: como empezaremos desde cero, no necesitaremos nada del guion anterior. Acto seguido, pegamos el siguiente contenido en script.rpy, y lo guardamos.

label start:
 
    "Silvana" "¡Como va! ¿Qué tal estuvo la clase?"
 
    "Yo" "Buena..."
 
    "No puedo admitir que me entró por un oído y me salió por el otro."
 
    "Yo" "¿Te vas a tu casa ahora? ¿Querés que volvamos juntos?"
 
    "Silvana" "¡Dale!"

Este primer guion de juego sigue la sintaxis de Ren'Py, y como se puede observar, es sumamente simple: carece de imágenes o música, y tan sólo presenta un texto de conversación entre dos personajes (una de las líneas es una narración en off). Aún así, ya podremos ejecutar este guion: retornamos al Lanzador Ren'Py y presionamos “Ejecutar Proyecto”. Ren'Py lo ejecutará, y podremos observar como Ren'py dispone directamente la pantalla inicial con los menús que nos dejan cargar y grabar una partida, así como aquellos para modificar las preferencias del juego. Para ver este parco guión, elegimos el menú Start.

Como vemos, este guion mínimo ya incluye varias declaraciones muy comunes del lenguaje Ren'Py. Las estudiaremos brevemente. La primer línea de código consiste una declaración label, utilizada para etiquetar un lugar en el programa. En este caso, creamos una etiqueta llamada start; esta etiqueta start es especial, pues  determina el lugar desde donde comenzará a ejecutarse los guiones de RenPy cuando alguien oprime Empezar Juego en el menú principal; Ren'Py irá interpretando desde start hacia abajo, en secuencia.

Las demás líneas que agregamos constituyen declaraciones say. Existen dos formas de declaración say:

  • Una forma narración en off o pensamientos del personaje principal: consiste en una cadena (comienza con comillas ", contiene caracteres, y termina con comillas ", toda en una sola línea.
  • Una forma para diálogos: consiste en dos cadenas; la primer cadena indica el nombre de personaje y la segunda cadena es lo que dice tal personaje.
Hemos de tener en cuenta que todas las declaraciones say van sangradas a 4 espacios. Esto se debe a que existe un bloque debajo de la declaración label. En Ren'Py, los bloques necesariamente deben estar sangrados en relación a la declaración previa, y todas las declaraciones de un mismo bloque deben estar sangradas por la misma cantidad de espacios.

En el caso que las cadenas contengan en sí caracteres de comillas ("), estas deben ser escapadas con un caracter de barra invertida (\). Por ejemplo:

    "Silvana" "¿Alguna vez oíste la famosa frase de Perón, \"El problema con las citas sacadas de Internet, es que muchas de ellas son truchas.\"?"

Aunque parezca que nuestra novela visual provista de este guion simple  se presentan sobre un marco negro y no tiene mucho efectismo, resulta un ejemplo que demuestra lo simple que es escribir algo válido usando Ren'Py

Más adelante agregaremos imágenes, pero primero veamos cómo definir los personajes de nuestra historia.

Personajes

Un problema que tiene este primer ejemplo es que se vuelve necesario ingresar repetidamente el nombre de un personaje toda vez que el mismo habla (tal como si fuese un guion de una obra teatral). Naturalmente, hacer esto se voolverá sumamente tedioso, sobre todo si quisiéramos escribir mucho diálogo en nuestra novela. Por suerte es posible también declarar los nombres de personaje al iniciar el guion. Para esto tenemos que definir los personajes por adelantado según la sintaxis de Ren'Py. De esta manera podremos asociar un texto a un nombre abreviado al personaje, y cambiar el color del nombre del personaje, todo al mismo tiempo.

Lo haremos editando nuevamente el guion script.rpy para que ahora quede de esta manera:

define s = Character('Silvana', color="#c8ffc8")
define y = Character('Yo', color="#c8c8ff")
 
label start:
 
    s "¡Como va! ¿Qué tal estuvo la clase?"
 
    y "Buena..."
 
    "No puedo admitir que me entró por un oído y me salió por el otro."
 
    s "¿Te vas a tu casa ahora? ¿Querés que volvamos juntos?"
 
    y "¡Dale!"

De ahora en más, escribir el diálogo entre los dos personajes se volverá más sencillo. La primera y segunda declaración definen al primero y el segundo personaje. Como verán, la primer línea define un personaje con el nombre abreviado de “s”, y su nombre largoSilvana“, con un color de nombre verdoso (los colores se representan con tripletes hexadecimales rojo-verde-azul, al igual que en las páginas web). La segunda línea crea un personaje con el nombre corto ”y“ y el nombre largo ”Yo“. con el color de nombre rojizo. Podrán inventar otros personajes copiando una de las líneas de definición de personaje, y cambiándole su nombre corto, nombre largo y el color.

También modificamos las declaraciones say para hacer uso de los objetos Character en lugar de recurrir a la tediosa cadena de nombre para un personaje.

Ver manual: Defining Character Objects

No sería una novela visual sin que se nos muestren imágenes en la pantalla. Aquí hay otra escena de “The Question”. Esta también incluye declaraciones que muestran imágenes al jugador. Si lo desean probar, pueden reemplazar completamente la sección anterior del guion:

define s = Character('Silvana', color="#c8ffc8")
define y = Character('Yo', color="#c8c8ff")
 
label start:
 
    scene bg meadow
 
    "A poco caminar, alcanzamos el campito justo al lado del barrio donde vivimos."
 
    "Acá es muy lindo todo. El otoño se parece a esos animés coreajaponchinos."
 
    "Cuando éramos chic@s, jugábamos mucho en estos lares, guardo hermosos recuerdos."
 
    y "Ey... Umm..."
 
    show sylvie green smile
 
    "Gira hacia mí y su sonrisa es tan luminosa que siento que mis nervios desaparecen."
 
    "¡Creo que le voy a preguntar...!"
 
    y "Ummm... ¿T-te gustaría..."
 
    y "¿Te gustaría hacer el arte para mi novela visual?"
 
    show sylvie green surprised
 
    "Silencio."

Este segmento de guion introduce dos declaraciones nuevas. La declaración scene de la línea 6 borra todas las imágenes y presenta solamente una imagen de fondo. Las declaraciones show de las líneas 16 y 26 hacen aparecer en pantalla un sprite (una gráfica activable) encima de la imagen de fondo, y modifican este sprite, respectivamente.

En Ren'Py, cada imagen consta de un nombre. El nombre consiste de una etiqueta, y opcionalmente de uno o más atributos. Tanto la etiqueta como los atributos deben empezar con una letra, y sólo pueden contener letras, números y guiones bajos. Por ejemplo:

  • En la declaración scene de la línea 6, la etiqueta es bg y su atributo es meadow. Por convención, las imágenes de fondo usan la etiqueta bg (por "background", o sea "fondo" en inglés).
  • En la primer declaración show en la línea 16, la etiqueta es sylvie, y los atributos son green y smile.
  • En la segunda declaración show de la línea 26, la etiqueta es sylvie y los atributos son green y surprised.

En cada momento dado, sólo puede aparecer una imagen con una etiqueta dada. Si se presenta una segunda imagen del mismo nombre, esta reemplazará a la primera (tal como sucede en la línea 26 del guion).

Ren'Py buscará el fichero de imagen en el subdirectorio de imágenes, que puede localizarse seleccionando “Imagenes” en la sección ”Abrir Directorio“ del Lanzador de Ren'Py. Ren'Py es capaz de usar arte de personajes que se encuentren en formato PNG, WEBP, o AVIF, mientras que el arte del fondo puede estar en formato JPG, JPEG, PNG, WEBP, o AVIF. También existe soporte para archivos SVG, aunque estos se utilizan fundamentalmente para personalizar la interfaz de usuario. Es muy importante el nombre de archivo: puesto que la extensión no se usa, el nombre de archivos se convierte forzadamente a minúsculas, y se emplea el resultado como nombre de la imagen.

Por ejemplo, los siguientes archivos - localizados en el directorio de imágenes - definen las siguientes imágenes:

  "bg meadow.jpg" -> bg meadow
  "sylvie green smile.png" -> sylvie green smile
  "sylvie green surprised.png" -> sylvie green surprised

Puesto que los nombres de archivo están en minúscula, también lo siguiente se mantiene:

  "Sylvie Green Surprised.png" -> sylvie green surprised

Las imágenes también pueden ser colocadas en subdirectorios (subcarpetas) contenidas en el directorio de imágenes. El nombre de directorio resultará ignorado y sólo se usará el nombre de archivo para definir el nombre de imágenes.

Ver manual: Displaying Images

Declaración Hide

Ren'Py también soporta una declaración hide, que oculta una imagen dada. Por ejemplo, agreguemos esto al final del guión script.rpy en el que estamos trabajando, y lo probamos con Ejecutar Proyecto:

label irse:
 
    s "¡Me voy a encargar ahora mismo!"
 
    hide sylvie
 
    "..."
 
    y "¡No era eso a lo que me refería!"

En realidad es bastante raro usar hide. Os será posible usar show cuando un personaje cambia de emociones, mientras que scene se utiliza en los momentos en los cuales todos los personajes se retiran de la escena. Sólo es necesario usar hide cuando un personaje abandona la escena, pero el resto de la escena y los demás personajes tienen que permanecer en ella de la misma manera.

Declaración Image

A veces, es posible que no queramos dejar que Ren'Py defina las imágenes automáticamente por sí mismo. Para esto se usa la declaración image. Debería estar en el nivel superior del fichero (sin sangrado y antes del label start), y puede usarse para mapear un nombre de imagen a un fichero de imagen específico. Por ejemplo

image logo = "renpy logo.png"
image eileen happy = "eileen_happy_blue_dress.png"

La declaración image se ejecuta al tiempo de inicio, antes que label start y del resto del guion del juego con que interactúa el jugador (la declaración image también puede ser utilizada para llevar a cabo tareas mas complejas, pero esto se tratará aparte).

Transiciones

Según se ha venido obrando, las imágenes aparecen y desaparecen de forma instantánea. Puesto que a efectos del relato es importante cambiar la locación y hacer que un personaje entre o salga de escena, Ren'Py soporta lo que se conoce como transiciones, que permiten aplicarse cuando los personajes presentan modificaciones.

Las transiciones modifican lo que se muestra, desde el momento de lo que sucedía al final de la última interacción (diálogo, menú o transición - entre otras declaraciones) hasta la apariencia luego de que se han ejecutado las declaraciones scene, show y hide.

label start:
 
    scene bg meadow
    with fade
 
    "A poco caminar, alcanzamos el campito justo al lado del barrio donde vivimos."
 
    "Acá es muy lindo todo. El otoño se parece a esos animés coreajaponchinos."
 
    "Cuando éramos chic@s, jugábamos mucho en estos lares, guardo hermosos recuerdos."
 
    y "Ey... Umm..."
 
    show sylvie green smile
    with dissolve
 
    "Gira hacia mí y su sonrisa es tan luminosa que siento que mis nervios desaparecen."
 
    "¡Creo que le voy a preguntar...!"
 
    y "Ummm... ¿T-te gustaría..."
 
    y "¿Te gustaría hacer el arte para mi novela visual?"

La declaración with acepta el nombre de la transición a emplear. La más común es dissolve (que precisamente disuelve de una pantalla a la siguiente). Otra transición útil es fade (que desvanece la pantalla a negro, y luego la desvanece a la siguiente pantalla). Si establecemos una transición tras un bloque de múltiples declaraciones scene, show o hide, se aplicará a todas ellas a la vez. Por ejemplo, si programamos un bloque así:

    scene bg meadow
    show sylvie green smile
    with dissolve

...tanto las imágenes ”bg meadow“ y ”sylvie green smile“ se disolverán al mismo tiempo. Para disolver una por vez, se volverá necesario programarlo usando un bloque de dos declaraciones with:

    scene bg meadow
    with dissolve
    show sylvie green smile
    with dissolve

...esto disolverá primero el fondo del prado, para luego discolver la gráfica de Silvana. 

Si quisiéramos mostrar instantáneanente el prado, pero luego presentar la gráfica de Silvana con la transisión disolve más suave, deberíamos programarlo en bloque así:

    scene bg meadow
    with None
    show sylvie smile
    with dissolve

El None se ha utilizado aquí para indicar una transición especial que actualiza la idea de Ren'Py de que era la pantalla anterior (sin mostrarle nada al jugador).

Ver manual: Transitions

Posiciones

Por defecto, las imágenes se presentarán centradas horizontalmente, y con su borde inferior tocando el borde inferior de la pantalla. Esto suele venir bien para fondos y personajes únicos, pero al presentar más de un personaje (para hacer grupos, por ejemplo) probablemente guarde más sentido colocarlos en distintas posiciones en la pantalla. También puede tener sentido reposicionar un personaje según convenga en el relato.

     show sylvie green smile at right

Para hacer este reposicionamiento, agrega una clausula at a la declaración show. La cláusula at recibe una posición, y presenta la imagen en dicha posición. Ren'Py incluye varias posiciones predefinidas: left para el lado izquierdo de la pantalla, right para el lado derecho, center para centrarlo horizontalmente (el valor por defecto) y truecenter para que la centre horizontalmente y verticalmente.

Los creadores puede incluso definir sus propias posiciones, y hacer eventos con movimientos complejos, pero esto cae por fuera de este tutorial rápido

Ver manual: Transforms

La mayoría de los juegos de Ren'Py cuentan con música de fondo. La música se reproduce con la declaración play music seguida por un nombre de archivo que es interpretado como un fichero de audio que debe ejecutarse. Los ficheros de audio se interpretan en relación al directorio de juego. Los ficheros de audio deben encontrarse en formato opus, ogg vorbis, o mp3.

Por ejemplo:

    play music "audio/illurock.ogg"

Al cambiar la música, se puede indicar una cláusula fadeout o fadein, que se usan para desvanecer el volúmen de la antigua música y aumentar el volúmen de la música nueva (que cumple la función de lograr una transición suave de  temas musicales).

    play music "audio/illurock.ogg" fadeout 1.0 fadein 1.0

La declaración queue music se utiliza para reproducir un fichero de audio no bien termine el fichero de audio que está reproduciéndose (de este modo se puede hacer una especie de playlist).

    queue music "audio/next_track.opus"

Si en la escena necesitamos detener la reproducción musical, podremos hacerlo mediante la declaración stop music (capaz también de recibir una cláusula fadeout opcional).

    stop music

Los efectos de sonido (y en el mejor de los casos, los doblajes de voz) pueden reproducirse con la declaración play sound. A diferencia de la música, los efectos de sonido no se reproducen en bucle sinfín.

    play sound "audio/effect.ogg"

Cuando disponemos los archivos de audio en el directorio game/audio, se pueden lusar los nombres sin aclarar la extensión de archivo (al estilo de una variable de Python, que comienza con una letra, y contiene sólo letras, números y guiones bajos). En tal caso, nos será posible reproducir tal fichero sin poner las comillas.

Por ejemplo, si contamos con un archivo de audio game/audio/illurock.ogg, podremos programar:

    play music illurock

Ver manual: Audio

La declaración pause hace que el guión de Ren'Py haga una pausa hasta hacer clic con el mouse.

    pause

Si le indicamos un número, la pausa finalizará automáticamente una vez que transcurra dicho número de segundos.

    pause 3.0

Podremos decretar la finalización del guion de la novela visual mediante la declaración return, sin tener que llamar a nada. Antes de hacer esto, es mejor poner algo en el juego que indique que el juego terminó (tal vez aclarando un número de finalización o un nombre de finalización al usuario).

    ".:. Final Feliz."
 
    return
Esto es todo lo que tenemos que hacer para guionar un relato cinético, que resulten en un juego lineal, sin ningún tipo de opción que seguir en él.

Ahora veremos lo que se necesita para hacer que un juego que presente menúes con opciones para que el usuario opte interactivamente. Estas permitirán trazar diferentes senderos o caminos, si es que queremos permitir seguir distintos desarrollos argumentales arbolados.

La declaración menu te permite presentar una opción al jugador:

    s "Yo te ayudaría, pero ¿qué es una \"novela visual?\""
 
menu:
 
    "Es un videojuego.":
        jump juego
 
    "Es un libro interactivo.":
        jump libro
 
label juego:
 
    y "Es una especie de videojuego, que jugás en Linux"
 
    jump matrimonio
 
label libro:
 
    y "Es como un libro interactivo que leés en una computadora o un celular."
 
    jump matrimonio
 
label matrimonio:
 
    "Y de esta manera, nos volvimos un dúo creador de novelas visuales."

Este ejemplo presenta un menú que puede usarse con Ren'Py. La declaración menu introduce una opción que podemos seleccionar dentro del juego. Requiere un bloque de líneas sangradas, cada una consiste en una cadena seguida por dos puntos (:). Estas serán las opciones que se le presentarán al jugador aparenciendo en un menú.  Como se ve, cada opción del menú necesita a continuación su propio bloque de líneas sangradas (ya que se ejecutan cuando se eligen dicha opción del menú). En este ejemplo, cada una de las dos opciones del menú ejecuta una única declaración jump, encargada de transfir el control a la etiqueta que se ha definido  a través de la declaración label correspondiente. Esto significa que tras el salto jump del guion, se ejecutarán las declaraciones  que siguen a la etiqueta label determinada.


En el ejemplo anterior, una vez que que Silvana exprese su pregunta, al jugador se le presentará un menú que contiene dos opciones. Si el jugador elige “Es un videojuego”, se ejecuta la primer declaración jump, y Ren'Py saltará a la etiqueta juego. Esto provocará que el Punto de Vista del personaje diga “Es una especie de videojuego, que jugás en Linux”, tras lo cual Ren'Py saltará a la etiqueta matrimonio.

De no existir declaración jump al final del bloque asociado a la etiqueta label, Ren'Py continuará a la siguiente declaración. La última declaración jump es técnicamente innecesaria, pero al incluírsela suele clarificar el flujo del juego.

Será posible definir etiquetas label en cualquier archivo de juego que esté en el subdirectorio game/ y termine con extensión .rpy. El nombre de archivo no importa en Ren'Py, solamente importan las etiquetas contenidas en el. De esta manera, podríamos concebir a los archivos .rpy del subdirectorio game/ como si fueran un  archivo .rpy enorme con el código fuente del juego, en el cual se usan los saltos jump para transferir el control de uno a otros. De esta manera, podremos obtener flexibilidad en la forma en la que organizamos un guion de un juego muy largo.

Ver manual: In-Game Menus y Labels & Control Flow

Si bien resulta posible lograr buenos juegos simples usando las declaraciones que os he explicado, lo cierto es que juegos más abrevados requieren una programación más compleja que almacene datos, a fin de poder recabarlos luego. Por ejemplo, puede tener sentido que el juego recuerde una opción escogida por el jugador, volver a una sección común del guion, y actuar más adelante según la opción escogida anteriormente. Esta es una de las razones por la cual Ren'Py cuenta con soporte de Python integrado.

Flags de apoyo usando las declaraciones Default, Python e If

Aprendamos cómo almacenar un valor en un flag (que contendrá información sobre una elección escogida por el jugador a lo largo de la trama). Para inicializar el flag, debemos utilizar la declaración default antes de la etiqueta label start, por ejemplo:

# True si el jugador ha decidido comparar las novelas visuales con un libro.
default libro = False
 
label start:
 
    s "¡Como están! ¿Qué tal estuvo la clase?"

De esta forma, el flag libro comienza inicializado de forma apagada (con al valor especial False, puesto que al igual que el resto de Ren'Py, es importante definirla según estilo Python, recurriendo a la primer letra en mayúscula). Esto significa que está desactivada. Si el jugador escoge la senda libro, podemos poner el flag en True recurriendo una declaración de asignación estilo Python, de la siguiente forma:

label libro:
 
    $ libro = True
 
    y "Es como un libro interactivo que leés en una computadora o un celular."
 
    jump matrimonio

Debemos observar que todas las líneas que inician con el caracter son interpretadas como declaraciones de Python en lugar de declaraciones de Ren'Py. La declaración de asignación de Python que utilizamos aquí asigna un valor a una variable.

Ren'Py soporta otras formas para incluir Python, tales como las declaraciones multilíneas (tuplas) de Python. Ren'Py soporta Python 2.7, aunque es recomendable programar Python capaz de correr en Python 2 y Phyton 3.

Para recabar el valor almacenado en el flag, recurrimos la declaración if:

if libro:
 
    "Nuestro primer juego se basó en las ideas de Silvana, pero luego se me ocurrieron mis propias historias también."

Si la condición es True (verdadera), se ejecuta el bloque del guión. Si no lo es, se la salteará. La declaración if puede recibir una cláusula else opcional, la cual introduce un bloque de guion alternativo que corre si la condición es False (falsa).

if libro:
 
    "Nuestro primer juego se basó en las ideas de Silvana, pero luego se me ocurrieron mis propias historias también."
 
else:
 
    "Silvana ayudó con el guion de nuestro primer videojuego."

Las variables de Python no están necesariamente limitadas a sus valores simples True/False. También podremos utilizar variables para almacenar el nombre del jugador, los puntajes, o cualquier otro propósito que se nos ocurra. Ya que Ren'Py cuenta con la capacidad de emplear todo el lenguaje de programación Python, es posible hacer muchas cosas más.

Un recurso típico es el subgénero “simdate” o “juego de conquistas”, donde las elecciones del jugador suman o restan puntaje de una o varias variables; de acuerdo al puntaje que vas sumando o restando, resulta posible avanzar en determinadas sendas de la historia.

Ver Manual: Python Statements y Conditional Statements

La Pregunta es una versión traducida pero tiene los puntos básicos de este tutorial de Ren'Py.

Si lo anhelan podrán observar el guion completo de La Pregunta aqui, pegarlo en el editor, y lanzarlo.

En la carpeta game del los proyectos creados, se incluirá las siguientes carpetas y ficheros:

script.rpy Este es el archivo pensado para incluir otros guiones que incluyen un escenario. También se pueden agregar o borrar cualquier .rpy.
*.rpyc Estos ficheros son resultados de la compilación de cada fichero .rpy para reducir el tiempo de carga. No es necesario editar estos archivos sin borrar el fichero .rpy correspondiente.
gui.rpy Las variables de la GUI van definidas aquí.
options.rpy Variables Config y Build, una parte de preferencias y una parte de la GUI de definen aquí.
screens.rpy Las pantallas van definidas en este fichero. Esto se debería editar si deseamos personalizar la GUI en un sentido mas avanzado.
audio/ En este subdirectorio van los ficheros de audio.
cache/ En este directorio van los ficheros de caché. No se necesita editarlos.
gui/ Este subdirectorio incluye imágenes usadas en la GUI.
images/ Este subdirectorio incluye los ficheros de imágenes.
tl/ Este subdirectorio incluye archivos de traducción.

Una vez que programamos nuestra novela visual, existen varias cosas que podemos hacer hacer antes de publicarlo:

Revisar el guion

Desde la primer página del Lanzador, elegi “Revisar guion (Lint)”. Esto depurará el juego en busca de potenciales errores. Como algunos de estos errores sólo afectan a usuarios de otras plataformas, es importante entender y usualmente corregir todos estos errores, incluso si no dan problemas en nuestro sistema específico.

Revisar versiones nuevas de Ren'Py

Periódicamente se lanzan nuevas versiones de Ren'Py en base a correcciones de errores y nuevas funcionalidades. Antes de lanzarlas, querrías hacer clic en Actualizar en el lanzador de Ren'py para bajarte la última versión. También es posible descargar nuevas versiones y ver un listado de cambios en https://www.renpy.org/latest.html.

Raramente los cambios a Ren'Py requieren realizar modificaciones al guion ya terminado, pero de existir incompatibilidades, se listarán allí con los cambios sugeridos.

Compilar distribuciones

Desde la primer página del lanzador, podemos elegir "Compilar Distribuciones". Basado en la información indicada en option.rpy, el Lanzador Ren'Py compilará uno o más ficheros de archivaje comprimidos que contendrán el juego que has programado.

Probar el juego compilado

El depurador Lint incorporado no es substituto para las pruebas completas del juego. Es tu responsabilidad comprobar tu novela visual antes de publicarla. Sin duda que los compañeros podrán darte una mano y te ayudarán a testear la beta de tu juego compilado (a menudo otros encuentran problemas que no hemos visto):

Ya no puede producirse un aumento en gran escala de la producción computacional del Tercer Mundo sin un desarrollo paralelo de los centros de datos correspondientes. Este Tutorial apenas cubre lo básico de lo que es capaz de hacer Ren'Py. Para hacerlo fácil y breve, he omitido muchas funcionalidades que soporta Ren'Py y he simplificado la explicación de otras, enfocándolo en un subconjunto de funcionalidades básicas necesarias para emprender una novela visual.

Si te interesa aprender mas, no dudes en hojear el Manual de Ren'Py, ya que por eso cada byte de metadatos que hoy se dejen arrebatar los Países del Tercer Mundo, equivale a un terabyte de software compilado que dejarán de producir mañana.