Creando juegos de aventura con Adventure Game Studio (VII)

AGS Blue Cup Logo Adventure Game Studio es un programa creado por Chris Jones para que amateurs de la creación de videojuegos puedan hacer sus juegos de aventura al estilo de los juegos que hacía Sierra y/o LucasArts a mediados de los 90. En particular, AGS permite concentrar a la persona o al equipo en la creación de contenido del juego y facilitar la programación de los guiones que conformarán la historia. AGS se ha convertido a lo largo de estos años en un programa muy poderoso, con una gran gama de características, un lenguaje de scripting muy flexible, y una excelente comunidad dispuesta a ayudar y con gente bien simpática. En la parte anterior habíamos comenzado a crear habitaciones en AGS, la unidad fundamental de un juego de aventura.

En la parte anterior habíamos comenzado a hacer scripts para definir las interacciones del juegos con los objetos y hotspots de una habitación. En esta parte definiremos los diálogos que ocurrirán entre los personajes dentro del juego. AGS ofrece una forma simplificada de escribir estos diálogos y realizar acciones producto de estos diálogos.

Parte VII: Programación de conversaciones en AGS

Para esta parte comenzaremos con la fuente de la parte VI [ZIP, 3MB]. Cuando terminemos esta parte, deberíamos tener algo similar a esta versión de fuente de la parte VII [ZIP, 3MB].

La incorporación de otros personajes con los que el protagonista pueda interactuar permite al escritor hacer una historia más envolvente para el jugador. Los jugadores se identifican mejor con personajes que tengan diálogos que refuercen su personalidad, o su percepción del entorno donde están. En AGS los diálogos se manejan a través de «Tópicos». Estos tópicos son listas de opciones que un jugador puede escoger a la hora de hablar con alguien.

Cada tópico se desarrolla a través de guiones simplificados. En vez de ser como los que vimos la vez anterior, estos guiones son específicamente para las conversaciones, por lo que en general sólo se requiere escribir el nombre del personaje y lo que dice. Veremos que también incluyen unas instrucciones para controlar el flujo entre diálogos, interactuar con los datos del juego, y correr scripts del juego.

La conversación

Para esta parte supondremos que la máquina grande que está en la habitación verde de la casa de Joe es capaz de mantener una conversación con un ser humano. Por otra parte, la máquina está a cargo de mantener la puerta principal cerrada, y otras tareas que no nos conciernen ahora.

Cuando se escriben los diálogos para un juego de aventura, hay que tener en cuenta que las conversaciones no son lineales: el jugador debería escoger sobre qué conversar, el juego responder adecuadamente y así ir construyendo la historia. Esto significa que los diálogos van a tomar forma de árboles de conversación: el jugador comienza la conversación, ya sea con un simple «hola», y ésta prosigue hasta que llega a determinados puntos donde hay varias alternativas para el jugador.

AGS provee la estructura necesaria para hacer estos árboles de conversación. Para ello accederemos a la pantalla de diálogos, Dialogs, donde tendremos algo similar a esto:

Dialog Screen

Estructura de las conversaciones

AGS provee Tópicos de Conversaciones, que contienen a su vez Opciones, que son las líneas que inician una conversación. Al seleccionar una opción, se corre la conversación escrita para ella. La idea es poder conectar un tópico con otro, y así obtener conversaciones significativas para el jugador.

A la izquierda tenemos la lista de tópicos, y a la derecha abajo tenemos la lista de opciones. Para agregar un tópico debajo de la lista tenemos el botón New topic, y para agregar opciones para un tópico tenemos el botón New option debajo de la lista correspondiente. Lo primero que haremos será ir hasta el tópico 0 y poner como nombre en Script name: MachineSalute. Como en el caso de los objetos y los personajes, este nombre permitirá identificar el tópico cuando lo llamemos desde el código. También lo identifica el número correpondiente en la lista.

Luego crearemos tres opciones, donde pondremos las líneas «¿Qué cuentas de nuevo?«, «Necesito un favor tuyo» y «Adiós«. Te habrás fijado en las dos marcas a la derecha de cada opción, llamadas Show y Say. La opción Show determina si la opción se mostrará desde el inicio. De no ser así entonces habría que hacerla visible en algún momento escribiendo el código necesario. La opción Say indica que nuestro protagonista dirá la frase contenida en la opción. Podemos desactivar esta marca si la opción es un pensamiento de él, o si va a hablar primero aquél con quien esté conversando.

Tenemos una marca en la parte superior que no utilizaremos. Sirve para poner un cuadro de texto entre las opciones para que el jugador introduzca sus propias opciones. Este estilo de conversación es muy similar al que tiene Veil of Darkness.

En la parte superior tenemos 4 botones. Export dialogs… y Replace form file… exportan e importan los diálogos de un juego, respectivamente, a un formato binario propietario de AGS. No dialog bullet point permite escoger un gráfico para las marcas que van al lado de cada opción. Edit script es el botón que nos interesa para este tutorial. Es el que permite escribir el guión de las conversaciones.

El Guión de las Conversaciones

Para cada opción de un tópico es necesario incluir el resto del diálogo. Al presionar el botón Edit script obtenemos una ventana similar a la de los scripts que escribimos en la parte anterior. En este caso, utilizamos código distinto al usual para poder escribir las conversaciones. Este código es más específico a lo que queremos hacer. También es limitado con respecto a las cosas que podemos hacer, pero veremos que es sencillo saltarse esta limitación en caso de que sea necesario.

Dialog Script Window

Cuando abrimos la ventana aparecen algunos comentarios (antecedidos siempre por la doble barra // ) y las siguientes líneas:

@S // dialog startup entry point
joe: ¿Hola?, ¿máquina?
machine: Hola, Joe
return
@1 // option 1
machine: Nada nuevo. Tu habitación está segura conmigo.
joe: Es bueno saber eso.
return
@2 // option 2
machine: ¿Qué necesitas, Joe?
goto-dialog 1
@3 // option 3
joe: Adiós,Joe.
stop

Lo que viene a continuación de @S representa el guión previo a la presentación de las opciones. Veremos que en nuestro ejemplo lo utilizamos para hacer un saludo a la máquina. Los guiones se escriben muy similar a un guión de teatro: se pone el nombre del personaje (el mismo que sale en el Script-O-Name), dos puntos y su línea.

Existen dos nombres especiales que AGS distingue: «narrator» es uno y sirve para que el «narrador omnipresente» hable. Básicamente alguien sin cuerpo presente en la habitación. «player» es el otro, y sirve como un alias general para el personaje que esté controlando el jugador. Útil para cuando éste maneje más de un personaje.

También es posible poner «…» como línea de un personaje. En este caso, el personaje simplemente no dirá nada ni moverá la boca.

Instrucciones especiales

AGS es capaz de leer instrucciones específicas, en vez de las líneas de los personajes. Esto permite controlar el flujo entre tópicos de conversación, controlar las opciones del tópico donde estamos parados, y controlar el flujo del juego (alterar variables y cosas por el estilo). Las instrucciones más usuales son:

  • return — Termina el diálogo y retorna a la lista de opciones del tópico actual.
  • goto-previous — Retorna al tópico anterior, que llamó al actual. Si el diálogo comenzó en el tópico actual, se retorna al juego.
  • option-on X — Hace visible la opción X del tópico actual, siendo X el número que le pases a la instrucción.
  • option-off X — Hace invisible la opción X del tópico actual, siendo X el número que le pases a la instrucción.
  • option-off-forever X — Hace permanentemente invisible la opción X del tópico actual, siendo X el número que le pases a la instrucción. A diferencia de la opción anterior, option-on no volverá a hacer visible la opción.
  • add-inv X — Agrega el objeto X al inventario del jugador.
  • lose-inv X — Quita el objeto X del inventario del jugador.
  • run-script X — Esta opción corre la función global «dialog_request», donde X es un parámetro que se le pasa. Como esta función se ejecuta de la misma manera que las funciones que has hecho en partes anteriores, dispones de mayor flexibilidad para hacer cosas avanzadas. En el archivo de script global de tu juego debería haber una función como esta:

    function dialog_request(int valor) {
        if (valor == 12) { //12 o cualquier número que sea X)
            //código aquí
        } else if (valor == 11) {
            //otro código aquí
        }
    }

Volviendo al juego

Así que ya hemos creado nuestro primer tópico, donde Joe hace una charla insignificante con la máquina. Crearemos un segundo tópico, donde estarán las opciones de favores que pediremos a la máquina. Cerraremos el editor de script si lo teníamos abierto y volvemos a la pantalla de Dialogs. Allí hacemos click sobre el botón New topic, e introducimos el texto de sus opciones:

  1. ¿Puedes prepararme un café?
  2. ¿Puedes abrir la puerta por mí?
  3. ¿Puedes limpiar la habitación?
  4. Olvídalo

En los 4 casos nos aseguramos que las opciones Show y Say correspondientes a cada una estén marcadas. El script que asignaremos a este tópico será el siguiente:

// dialog script file
@S // dialog startup entry point
return
@1 // option 1
machine: Pero no tengo manera de hacer café, Joe.
joe: Lo siento, lo olvido siempre.
option-off 1
return
@2 // option 2
machine: Ahora mismo, Joe. Ya puedes pasar.
set-globalint 1 1
option-off 2
return
@3 // option 3
machine: La limpiaré cuando regreses a la casa.
joe: Gracias.
option-off 3
return
@4 // option 4
goto-previous

En este caso no tenemos un diálogo introductorio, por que lo que el caso @S no tiene nada. Las opciones 1 y 3 son solamente de relleno, por lo que una vez dichas, escondemos las opciones correspondientes y retornamos al tópico. La opción 4 sirve para retornar al diálogo inicial. La opción 2 es la que nos permitirá abrir la puerta: para el juego utilizaremos la variable global 1 para saber si la puerta está abierta o no. Más adelante desarrollaremos el script para que Joe pueda abrir la puerta.

Es importante poner la palabra clave return a todo lo que no sea goto-previous o stop. De otra manera el guión saltará a la siguiente opción. Si en el juego los diálogos parecieran saltar de uno a otro, vale la pena chequear si hemos puesto return en donde debe ser.

Un tip con respecto a los diálogos de relleno: hay ciertas acciones que hace el jugador que impulsan la historia. Para este caso particular y sencillo, la opción 2 que abre la puerta es la que lleva la historia hacia adelante. Otras acciones revelan el interior del personaje: cómo piensa, cómo siente, y qué piensa de sus alrededores y vecinos. La opción 1 muestra a Joe como una persona olvidadiza, y la opción 3 habla de las capacidades de la máquina para hacer trabajo (o para decir cosas sarcásticas 🙂 ). Hay que tener en cuenta esto siempre, ya que los diálogos que se ponen por ponerse acaban fastidiando y aburren al jugador.

Escribiendo mensajes de habitación

Hasta ahora hemos visto dos tipos de mensajes. Por una parte están los que salen en un recuadro y que detienen la acción, como dichos por un narrador que puede parar el tiempo (AGS los llama «Normal Text» o «Texto Normal«). Por otra parte están los que dicen directamente los personajes cuando conversan, como los diálogos que acabamos de ver.

La cosa es que hay ciertas líneas que queremos que el personaje diga, sin necesidad de entrar en un diálogo. En general estos mensajes corresponden a los que tiene que decir el personaje cuando va a ejecutar una acción o emite una observación. La idea es evitar tener que hacer tópicos de diálogos sólo para hacer que un personaje diga algo.

Para esto tenemos los mensajes de habitación, numerados de 0 a 499. Estos mensajes guardan el tipo de línea que acabamos de describir, y el texto normal. A través de Room -> Edit Room Messages… o presionando CTRL – M podemos acceder al editor de mensajes.

En este caso crearemos tres mensajes. El mensaje 0 contendrá la línea «Está trancada. Es una medida de seguridad de la máquina. Debo indicarle que la abra.«, el mensaje 1 contendrá «Ya está abierta. Saldré de aquí.«. En ambos casos pondremos que Joe dirá la línea. El mensaje 2 contendrá «Felicidades, terminaste el juego.» y será texto normal. Se habrán dado cuenta de dos opciones específicas para cada mensaje: Display message after this one permite encadenar diálogos uno detrás del otro de una forma intuitiva, ahorrando llamadas en el código. Automatically remove this message after a time sólo es válido para texto normal, y permite establecer un tiempo para leer la línea antes de continuar con la acción automáticamente.

Mensajes globales

Aparte de los mensajes de habitación, tenemos mensajes a los que es necesario acceder independientemente de dónde se esté. Nos referimos a los casos de las líneas dichas por un personaje con respecto a su inventario, o mensajes genéricos cuando se intenta hacer una interacción inválida. También corresponden con algunos elementos de la interfaz, como el texto correspondiente a las ventanas para restaurar un juego o reiniciarlo.

Los números de los mensajes globales van del 500 al 999, estando los de 984 a 999 reservados para los elementos de la interfaz descritos anteriormente.

Para el caso de este mini-juego no utilizaremos mensajes globales, pero cabe destacar una técnica que explicaremos a continuación. Cuando se muestra a través de código los mensajes globales, suelen salir como texto normal. Muchas veces queremos que este texto salga de la boca de nuestro personaje. Lo que debemos hacer es ubicar el número de mensaje, y en el script correspondiente a la interacción escribes lo siguiente: (asumiendo que pones la interacción en Run Script, cJoe es el personaje que quieres que hable, y 520 el número de mensaje global)

cJoe.Say("%s", Game.GlobalMessages[520]);

La Ventaja de los Mensajes es la Traducción

Se preguntarán por qué hay que pasar por el lío de ventanas con líneas, mensajes y cosas así, en vez de escribir todo directamente en el código. La grandísima ventaja de tener organizados los mensajes de esta manera es que AGS provee facilidades de traducción del texto del juego. Mientras que el texto dentro del código no es tomado en cuenta para la traducción, los mensajes sí lo son, por lo que la labor se simplifica muchísimo en el caso de que quieras hacer esto.

El resto del script de la habitación

Una vez hecho los diálogos hay que hacer dos cosas: conectar la acción de hablar con la máquina con el inicio del diálogo, y rellenar las acciones de Joe con la puerta, lo que se traduce en una comprobación del estado de la variable global 1.

Para comenzar el díalogo con la máquina, Joe debe hablar con la máquina. Para esto iremos a la pantalla de Areas -> Hotspots, y seleccionamos el área de la máquina que definimos en la anterior entrega de este tutorial. Le damos al botón de Interaction…, y hacemos doble click sobre Talk to hotspot. Esta vez no utilizaremos un script, sino que escogeremos la opción Game – Run dialog, y dándole al botón Change nos aseguramos que su valor sea 0. La siguiente figura ilustra dónde se siguen estos pasos.

Tutorial AGS, Parte VII: Pasos para obtener la ventana de interacción
Pasos para obtener la ventana de interacción

Interacción de Joe con la Puerta

En la misma pantalla de hotspots seleccionamos el área de la puerta. Le damos a botón de Interaction…, y hacemos doble click sobre Interact hotspot. Escogemos Run Script como opción, y editamos el script con el botón Edit Script…. En el editor escribimos este código:

// script for Hotspot 2 (Puerta): Interact hotspot
if (GetGlobalInt(1) == 1) {
    DisplayMessage(1);
    DisplayMessage(2);
    QuitGame(0);
} else {
    DisplayMessage(0);
}

La lectura de este código es una traducción bastante fiel de la descripción de las acciones del personaje que hemos establecido anteriormente.

Probando el Juego

Es hora de probar lo que hemos hecho hasta ahora. En la habitación movemos la almohada, recogemos la llave. Usamos la llave con la puerta para pasar a la siguiente habitación. En la segunda habitación hablamos con la máquina, le preguntamos si nos puede hacer un favor, y seleccionamos la opción de la puerta. Nos despedimos de la máquina y usamos la mano sobre la segunda puerta. Fin del juego.

Es probable que Joe no camine hasta la puerta, sino que se queda parado. Haría falta establecer el Walk-to point en la pantalla de Areas->Hotspots. Una vez hecho eso, se guarda y se vuelve a probar el juego para comprobar que todo esté bien.

Conclusiones

Así que en esta parte hemos aprendido a hacer diálogos y mensajes dichos por los personajes. Los diálogos en un juego de aventura son importantes porque son una excelente manera de revelar algo de la historia de los personajes.

AGS ofrece una manera de construir diálogos a través de tópicos. Estos tópicos ofrecen opciones de qué puede hablar el jugador, y a través de los scripts, los tópicos se conectan entre sí, para hacer árboles de diálogos. Los scripts de los diálogos son más específicos que los normales, por lo que se tiene acceso a un menor número de funciones, pero es posible obtener la flexibilidad de los scripts normales con la función run-script.

AGS permite el almacenamiento de diálogos específicos en mensajes. Estos mensajes pueden ser propios de la habitación, o pueden ser mensajes generales. Estos mensajes se muestran con la función DisplayMessage(). La razón por la que se usa este tipo de almacenamiento, es que AGS luego puede generar un archivo de traducción, y así simplificar esta labor.

Para poder correr un diálogo, en una interacción con un personaje se utiliza la función RunDialog().

Para la siguiente parte

Tenemos un juego jugable de principio a fin, por muy corto y tonto que sea. Sin embargo, un juego es mucho más que el ejecutable que lo contiene. En la siguiente parte nos encargaremos de pulir detalles importantes para empacar el juego y presentarlo al usuario de una manera atractiva y agradable. Veremos como crear pantallas y un listado de cosas que hay que hacer antes de publicar el juego.

15 comentarios en «Creando juegos de aventura con Adventure Game Studio (VII)»

  1. Hola

    Creo que agregé este Blog a mi FeedReader hace semanas, pero recién ahora es que lo checkeo con «algo» de calma.
    No me lei completo el post, pues no ando en la nota de juegos de aventura, pero te agradezco el compartir este tipo de información.

    Ze

  2. HOLa…. primero nose hace cuanto no ven el blog… espero que lo sigan manteniendo porque es una re ayuda.
    Hace mucho vengo con ganas de diseñar aventuras graficas y me baje el programa y buscando informacion llegue a la pagina y cada lugar te enseña algo .. nuevas formas …
    Yo no tengo la version que usan aca pero igual los script los escribo como me indica en el tutorial. El problema que me surgio es que cuando quiero guardar me dice que en el dialogo «maquina»
    no es un personaje. Al ser un hotspot no me lo toma y por lo tanto no puedo ver los resultados. yo uso Ags 3 si me pueden ayudar les agradeceria porque cada pequeña idea suma . LA pagina muy buena y espero poder contactarme con ustedes para aprender mas …
    Un abrazo
    Syd

  3. Hola Syd,

    Efectivamente el tutorial de AGS de El Chigüire Literario se escribió a lo largo de 2007, cuando la versión más reciente de AGS era la 2.72. Poco después de terminarlo, pues sacaron la versión 3, cuyo editor se escribió de cero en otro lenguaje, y cambió toda su interfaz. Lamentablemente por eso, mi tutorial prácticamente quedó obsoleto 😛

    No he tenido chance de ver de cerca la nueva versión, por lo que me temo que no te puedo ayudar con cosas específicas de esa versión.

    Sin embargo, dices que estás tratando de poner en el script a un ente llamado «maquina», pero maquina es un hotspot. Tengo entendido que los scripts de diálogo sólo son entre characters, por lo que tendrías que hacer un caracter vacío, o con normal view con la forma de la máquina. Intenta de esa manera, puede que sea más largo, pero así está hecho AGS.

    Esto lo digo así medio al aire, igual te recomiendo encarecidamente acercarte a los foros de AGS y preguntar allí (aunque en inglés :-P)

  4. Hola!!

    Me he bajado la ultima version del juego, y tambien buscando ayuda encontre este blog. Lo he seguido completo y ya tengo la aventura funcionando. :D:D

    Syd, para solucionar eso tienes que hacer lo que dice Siro. Creas un caracter Maquina, y le ponene en la habitacion de inicio 0 (asi no sale)
    Eso hace que en el Dialogo te encuentre el personaje.
    Por otro lado en la funcion de interaccion de la maquina de la habitacion
    usas el objeto dMaquina.Start() (o como le hayas llamado).

    Donde mas problemas tube es en poner la baseline del colchon, que tiene que estar mas baja que la de la cama para que el colcchon se viera por encima. Y la llave entre el del colchon y la cama.

    Para que el cofre se abriera y cerrara, use dos objetos poniendolos visibles y invisble ¿Habia otra forma?

    Muchas gracias al autor del blog!!

  5. hola Solo quiero decir que este Blog es Genial resivi mucha ayuda sobre este AGS que ni vien empeze descargandome el 2.27 semanas despues me pase al 3.1.2 que es la version mas resiente; y esta posee al igual que las anteriores un tuto de como iniciar y sobre el lenguaje del scrip PERO en ingles xD (no tuve problema con eso!) al igual que las versiones anteriores. al parecer este a cambiado mucho debido a que 1ro Ya no existe esa "lista de commandos" si es que se llama asi… en la cual elegias una interacion o suceso y automaticamente se creaba en el script .
    pero a falta de esto uno se acostumbra mas al lenguaje de script y vez que hay mas funciones que las que te pintan y mas especificas. otra cosa es lo del mismo script que cambio ligeramente en los nombres algunos comandos o funciones.(algo confunfdor si vienes de la anterior version pero te acostumbras) luego gracias a este aprendi a USAR EL TECLADO EN EL JUEGO xP perdon si esto es muy comun xP y lo mejor de todo es que si creaste tu juego con la anterior version (solo 2.27) lo puedes importar! yo lo hice pero resivi algunos errores de comandos obsoletos basicamente tuve que reescribir entero el Script pero solo por el orden de todo debido a que el script ahora se divide por secciones. asi que no borre nada solo cambia algunos comandos obsoletos y lo oredene todo en base al juego demo que hay en el editor. Luego otra curioisidad por hay es que me di cuenta (viendo el trabajo de otros) que podias solo crear un juego de aventura… si no de PUZZLE de RPG de PELEAS y algunos mas… bueno les recomiendo le hechen un vistazo se que estos comments son antiguos pero yo recien los veo y debe de haber mas gente como yo que recien los vea para ellos dedico este post. todo pueden verlo en la

    Pg oficial en ingles donde tambien se descargan y se suben juegos y los evaluan para los Ags Awards.

    http://www.adventuregamestudio.co.uk/games.php?ca

    bien eso es todo abajo publico una preguntila xD.

  6. Hola de nuevo quisiera preguntar como podria ver los Global messajes en la version 3.1.2 si es que alguien sabe ya que no hay arbol para eso. O si no hallarlos en el mismo Scrip aunque sea… (aunque eh estado revisando y en lo que veo creo que no se puede desde ahi.. :S) pero de todas formas gracias por su tiempo y por magnifico tutorial que fue con el que me inicie en esto.

    1. De nada Luis 🙂 El tutorial lo hice hace tiempo, y poco después salió AGS 3. No he vuelto a utilizarlo desde entonces, así que no te puedo responder preguntas específicas así como a dónde fueron los mensajes globales :-/

  7. Hola, recién comienzo con AGS y este tutorial me viene de perlas. He estado revisando tu minijuego con el que he apredido lo básico. Pero hay algo que se me escapa: En mi aventuraa quiero que aparezcan en la StatusLine los nombres de los diferentes objetos cuando pase el mouse por encima y no tengo forma. ¿Me podrías ayudar?
    Gracias de antemano.

    1. Hola Trios, no recuerdo bien cómo hacer eso, porque hace tiempo que no toco AGS. Busca en los tutoriales sobre interfaces que esos te dirían cómo mostrar el objeto que está debajo del cursor.

Responder a Luis DavidCancelar respuesta