Master Gollum

Twine: Tutorial (I)

Publicado hace 2 años, 247 días

Paradojas de la vida, lo cierto es que estos días de cuarentena estoy currando como un puto cabrón y eso que no formo parte de ningún sector de los considerados esenciales. Cuando te pasas doce o trece horas picando código como un poseso a contrarreloj, no te queda mucho tiempo para mucho más. Aún así, este fin de semana he encontrado un hueco para empezar a trastear con Twine. ¿De qué estoy hablando? De una plataforma para escribir librojuegos. (Lógicamente nos serviría para otro tipo de textos dinámicos, pero como este blog versa sobre rol nos centraremos en este uso) ¿Qué puedo decir? Me ha encantado su flexibilidad, simpleza y lo fácil que es de usar. Así que aquí va mi experiencia y mis primeros pinitos.

Lo básico

Twine puede ser utilizado como una aplicación que uno se descarga o directamente como una herramienta online. Esta última opción no requiere registrarse. Se accede a twinery.org y de allí vamos a Use it online en el menú de la derecha. Le damos a "+Story". Nos aparecerá una caja de diálogo para introducir un título. A continuación saltaremos al editor donde se creará el primer pasaje. Para editarlo pulsamos sobre él con un doble click o al lápiz del pequeño menú. La verdad es que es muy intuitivo. A partir de ahí ya podemos introducir nuestro primer texto.

Pantalla principal

Lógicamente querremos ofrecer varias opciones a los lectores para que escojan y vayan avanzando en la historia. Para ello nos limitaremos a poner entre dobles corchetes el texto que deseemos convertir en un enlace. El mismo texto será el título del siguiente pasaje de nuestro libro, y así podremos irlos encadenando. Por comodidad podemos hacer que el texto del enlace sea diferente al título del pasaje con una fecha ->. Así enlazar el texto "¿Abres la puerta?" con el pasaje "Habitación Misteriosa", quedaría tal que así [[¿Abres la puerta?->Habitación Misteriosa]]. Los títulos no se muestran al lector y nos sirven a nosotros para orientarnos mejor por el juego que estamos creando.

Pantalla de navegación

También podemos dar algún formato básico, como //cursiva// o ''negrita''. O hacer listas con las líneas de texto precedidas por un * si no son numeradas o un # si son numeradas.

Código:

''Kargul'' //el Titiritero// extendió sus manos hacia sus marionetas y te dio a elegir una de ellas... ¡Escoge la que quieras!
* [[Araña]]
* [[Princesa->Marioneta Princesa]]
* [[Guerrero]]

Resultado:

Kargul el Titiritero extendió sus manos hacia sus marionetas y te dio a elegir una de ellas... ¡Escoge la que quieras!

Sencillo ¿No? Tan solo con esto ya podríamos crear un libro juego. Sin embargo, Twine nos ofrece, mucho, ¡mucho más! Tiene un lenguaje de script bastante chulo y relativamente fácil de usar. ¡En seguida nos adentraremos en él para simular las reglas de juego de los libros de Lucha Ficción!

Macros: variables y condiciones

Si habéis sido lectores habituales de los libro juegos de Lucha Ficción os recordaréis cuando encontrabais opciones del estilo "si tienes la llave del ogro, pasa al 178, si no la tienes pasa al 93". Con Twine ya no necesitamos preguntar al lector este tipo de cosas. Este editor usa el lenguaje de scripting Harlowe. Con él, podemos usar variables para saber si ha realizado una determinada elección en el pasado y llevarlo hacia un lado u otro del texto sin que si quiera sea consciente de ello. Para este fin usaremos macros, que son comandos especiales que nos van a permitir hacer un gran número de cosas. Hay muchas y de lo más variado. Su documentación se encuentra en https://twine2.neocities.org/ y está bastante bien explicado. Pueden ser conceptos un poco nuevos si no se está familiarizado con algún lenguaje de programación, pero veremos que es bastante sencillo.

Las macros son comandos que se escriben entre paréntesis con el siguiente formato (comando:argumentos). Aunque el comando esté vacío sigue necesitando los dos puntos. El primer comando que aprenderemos es (set:variable to valor). Es de gran utilidad, ya que nos permitirá guardar información a lo largo del texto. Por ejemplo, si el lector roba la llave al ogro, nos podemos guardar ese hecho en una variable con la instrucción (set:$llaveOgro to 1). De esta forma cuando alcance la puerta podemos mostrarle la opción de usar la llave y si no la tiene, ya ni siquiera le ofrecemos la oportunidad de ver que existe una llave que abre esa puerta. Una variable es una palabra clave a la que asignamos un valor, en este caso un 1. Las variables que deseamos estén disponibles a lo largo de todo la lectura del libro deben ir precedidas por un $. (Existen variables temporales, pero de momento nos olvidamos de ellas).

Ahora que nos hemos guardado el valor de $llaveOgro, para crear una condición en base a su valor usaremos la macro (if:condición)[texto]. Una condición es una evaluación lógica de una expresión booleana, es decir, de una expresión cuyo resultado es cierto (true) o falso (false). La macro if lo que hace es evaluar la condición y si esta se cumple, se muestra lo que hay entre los corchetes. En jerga de Twine, el bloque entre los corchetes se llama un hook.

Ante tí hay una puerta de madera firmemente cerrada. (if:$llaveOgro is 1)[Ahora que lo piensas, recuerdas que robaste la llave al ogro. La sacas de tu bolsillo y crees que con ella podrías intentar [[abrirla->Abrir Puerta de la Cámara de Tortura]].]

Como ya habrás adivinado, el texto del hook solo aparecerá si el valor de la variable $llaveOgro vale 1. En él se muestra el texto que invita a usarla y se convierte la palabra "abrirla" en un enlace hacia el pasaje titulado "Abrir Puerta de la Cámara de Tortura". Una variable puede contener directamente un valor booleano, que es en sí mismo una condición. Así si hubiéramos hecho (set:$llaveOgro to true), podríamos evaluar el if directamente con (if:$llaveOgro)[...].

Más formas de relacionar pasajes

Hemos visto que podemos ir de un pasaje a otro por medio de enlaces. No es una única forma de navegar entre ellos. Podemos mostrar directamente el contenido de un pasaje dentro de otro sin necesidad de obligar al lector a pulsar para visitarlo. Para ello usaremos la macro (display:"Título Pasaje"). Tal cual, allí donde pongamos esta macro se mostrará el pasaje con el título indicado entre dobles comillas. Las dobles comillas es la forma en la que declaramos las cadenas de texto. Esta funcionalidad es muy útil, nos permite, entre otras cosas, evitar esos pasajes con una o dos frases que enseguida redirigen a otro pasaje del juego.

El ocasiones nos interesa saltar directamente a otro pasaje, sin siquiera detenernos en el que nos encontramos. Por ejemplo, por ser este un pasaje que usamos únicamente para crear y guardar varias variables que usaremos más adelante. Imaginemos que en el pasaje principal invitamos al jugador a escoger la profesión de su personaje. Cada profesión es un enlace a un pasaje que prepara las variables con los datos de inicio de cada profesión y luego todos ellos redirigen directamente a una misma presentación común. Para ello podemos utilizar el comando (goto:"Título Pasaje").

La única pega del uso de macros para gestionar el flujo del texto es que no veremos reflejada la relación existente entre estos pasajes en el editor.

Números aleatorios y ficha de personaje

¿Qué sería un juego de rol sin tiradas de dados? Existe una macro que nos permitirá simularla. (random:desde,hasta) devuelve un valor aleatorio entre los dos extremos indicados. Así, lazar 1D6 es tan sencillo como escribir (random:1,6). Por supuesto, podemos asignar un valor aleatorio a una variable, tan solo tenemos que recurrir a la macro (set:). Lo haremos de esta forma: (set:$RES to (random:1,6)+(random:1,6)+12). Acabamos de crear una variable $RES con valor igual a 2D6+6. Combinando esta idea y la macro (display:) ya podemos crearnos una ficha que poder representar de forma rápida en los pasajes que queramos.

(set:$DES to (random:1,6)+6)
(set:$RES to (random:1,6)+(random:1,6)+12)
(set:$SUE to (random:1,6)+6)
(set:$PG to $RES)
(set:$PS to $SUE)

Con el ejemplo anterior hemos generado las estadísticas de personaje con las reglas de Lucha Ficción. Así tendríamos los valores de Destreza, Resistencia y Suerte, así como contadores para llevar el valor actual según la suerte se va consumiendo o la resistencia menguando. Podríamos ahora preparar una ficha simple para mostrarla cuando nos interese con un (display:"Ficha"). Para ello bastará con que creemos un pasaje con el título Ficha y el siguiente contenido.

Ficha de $Nombre:
DESTREZA $DES RESISTENCIA $PG/$RES
SUERTE $PS/$SUE

Lógicamente podríamos complicar la ficha tanto como quisiéramos llevando el conteo de las provisiones o las monedas del personaje, así como el equipo inicial o el que vaya adquiriendo a lo largo del juego.

Enlaces dinámicos: ¡Prueba tu Suerte!

Ya hemos visto que podemos usar una variable para visualizar su valor y que pueden ser usadas también como argumento de una macro. Esta potencia nos va permitir crear pasajes con verdaderos bloques de código a los que invocar y luego proseguir el juego a un determinado punto. Veamos un ejemplo simple de ello con las tiradas de Suerte. Las reglas dicen que cada vez que se quiera Probar la Suerte hay que lanzar 2D6, si el resultado es igual o menor a la Suerte, se es afortunado, si es estrictamente mayor, se es desafortunado. En cualquier caso, al Suerte disminuirá en un punto. Podemos codificar esta simple rutina de forma muy simple en un pasaje al que enviar al jugador y redirigir la lectura hacia un pasaje u otro en función de su suerte.

Prueba tu Suerte
(if:$PS is 0)[(goto:$desafortunado)]
(set:_suerteActual to $PS)
(set:$PS to $PS-1)
(set:_tirada to (random:1,6)+(random:1,6))
(if:_tirada<=_suerteActual)[(goto:$afortunado)]
(if:_tirada>_suerteActual)[(goto:$desafortunado)]

Si el jugador se ha quedado sin Suerte (ya no tiene Puntos de Suerte), no hay nada que hacer, lo enviamos al pasaje cuyo título está en la variable $desafortunado. A continuación guardamos el valor actual de la Suerte en la variable temporal _suerteActual. Una variable temporal es aquella que se usa únicamente dentro de un pasaje y su valor se pierde fuera de él. Restamos un punto a los PS. Lanzamos 2D6 y comparamos el resultado de la tirada.

Para usar la rutina anterior tan solo tenemos que enviar al jugador a esa página especial que llamaremos Prueba tu Suerte preparando antes los valores de las dos variables.

(set:$afortunado:"Cruza el río")
(set:$desafortunado:"Cae al agua")
Intentas atravesar el río sobre el precario tronco de madera. Su superficie está llena de musgo y es resbaladiza ¡[[Prueba tu Suerte]]!

Nota: el código de Prueba tu Suerte se puede simplificar usando la instrucción (else:)[...], con lo que no haría falta guardar el resultado de la tirada y el código sería más compacto. La macro (else:) permite ejecutar el contenido de un hook si no se cumple la condición del (if:) que lo precede. Ejemplo: (if:(random:1,6)+(random:1,6)<=$PS+1))[(goto:$afortunado)](else:)[(goto:$desafortunado)].

¡Y llega el combate!

Con todo lo visto hasta ahora ya deberíamos ser capaces de programar el combate del sistema Lucha Ficción. Este es muy sencillo, se suman 2D6 a las Destrezas de los combatientes, si el jugador tiene una tirada igual o mayor que el enemigo, le resta 2 puntos a su Resistencia, en caso contrario es él quien sufre la pérdida de 2 puntos. Haríamos el mismo truco, prepararíamos unas variables con las estadísticas del enemigo y podríamos crear una rutina de combate.

Ogro malvado
(set:$Enemigo to "Ogro") (set:$RESEnemigo to 10)
(set:$DESEnemigo to 8)
(set:$Victoria to "Ogro Muere")
(set:$Derrota to "Ogro Vence")
¡Prepárate para [[luchar contra el ogro->Combate]]!

Combate
(set:_pj to $DES+(random:1,6)+(random:1,6))
(set:_pnj to $DESEnemigo+(random:1,6)+(random:1,6))
(if:_pj>=pnj)[(set:$RESEnemigo to $RESEnemigo-2)](else:)[(set:$PG to $PG-2)]
(if:$PG<=0)[(goto:$Derrota)]
(if:$RESEnemigo<=0)[(goto:$Victoria)]
(display:"Ficha")

$Enemigo: DESTREZA $DESEnemigo RESISTENCIA $RESEnemigo
[[¡Atácale de nuevo!->Combate]]

A estas alturas el código debería ser autoexplicativo. Intenta comprenderlo y si tienes alguna duda, puedes dejarla en los comentarios. Lógicamente el sistema podría ser mucho más complicado, permitir lanzar conjuros, dar ofrecer diferentes tipos de ataque o la posibilidad de intentar huir.

Código completo en un ejemplo práctico. Espero que así sea más comprensible: TutorialTwine.html. Puedes descargarlo con el botón derecho e importarlo en Twine para ver toda la estructura y el código de los pasajes.

Despedida

¡Y hasta aquí llega el primer tutorial acelerado de Twine! Espero que os haya parecido interesante. Las posibilidades son muy amplias y permite realizar muchas más cosas además de las que aquí he explicado. A penas he empezado a explorar sus funcionalidades, así que es posible que haya nuevas entregas. Es posible que me anime e incluso termine publicando alguna aventurilla simple a modo de prueba.