Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Modelo X: Sistemas conversacionales

Iniciado por Güarmigue, 26 de Agosto de 2007, 08:37:37 PM

« anterior - próximo »

Güarmigue

(Aviso: sé que puede resultar mucho texto, trato de ser ameno y sencillo. Siento que en esta entrega tampoco haya bonitas imágenes que acompañen el artículo pero es un artículo sobre diálogos al fin y al cabo ;P En el blog siempre queda algo más bonito:))

Enlazando con uno de los apartados de la anterior entrega, los diálogos, hoy voy a tratar de responder lo mejor que sepa a la primera petición que he recibido sobre la serie "Modelos de juegos". La sugerencia en cuestión la hizo [Fonet] mediante un privado en el foro de Stratos hace ya más de dos semanas. Le dije que le respondería tras publicar lo que tenía entre manos y, con las vacaciones, ese momento se ha alargado hasta hoy. No me enrollo más y paso a la petición y a la respuesta (a lo CPI :)):

Citar[Fonet] escribió:
   Estaria bien desglosar las aventuras graficas levemente (en general, nada de SCUMM) y un poco mas a fondo los sistemas de conversacion (Ya sea por frases a lo Monkey Island o por temas a lo Broken Sword), ya que veo que es el punto complejo de este genero.

Este es un tema que yo mismo me he planteado varias veces ya que las aventuras gráficas (AG) son un género que me encanta. Hace poco, cuando comencé con un amigo a desarrollar una pequeña AG que ahora mismo está parada en el cajón de "Cuando alguien se ponga conmigo", le metí mano al engine Wintermute y me pareció una solución bastante lógica la que le daba. Primero que todo, si quieres crear una AG y no necesitas crear todo el código para sentirte bien como persona, sino que de verdad te quieres dedicar al argumento, los diálogos, los personajes y demás, debes usar esta herramienta. Wintermute nos provee de un montón de comodidades para crear nuestra aventura e incluso sin saber programar podremos escribir los diálogos y las acciones con un poco de ayuda de los tutoriales que adjunta el programa. Para los que seáis más hardcore y os gustaría programar por completo una aventura o una herramienta conversacional (tal vez para un bot o para otros fines, luego volveré sobre esta parte...) sigamos.

En Wintermute la técnica utilizada es simple y a la vez efectiva: los diálogos funcionan exáctamente de la misma forma que una mákina de estados de las que expliqué la implementación hace varias entregas. Tenemos un switch, un montón de frases con sus identificadores guardadas en memoria, y dependiendo de la entrada del jugador (1, 2, 3, 4, etc al elegir la frase, el icono temático, el botón "abrir", "usar", "hablar", etc. o la imagen de un objeto del inventario...) se ejecuta un case que a su vez dentro tendrá, o bien una serie de impresiones en pantalla con la conversación, o una llamada a una función que gestionará el nuevo sub-diálogo. Además en Wintermute se añade la posibilidad de declarar una variable de estado que indica si esa rama del diálogo ha sido o no elegida con anterioridad, y en caso afirmativo podemos elegir entre permitir o no que se muestre más veces en ese diálogo o en todo el juego. Para muestra un botón:


function dialogoCaracol()
{
 var Responses;
 var selected;

 var loop = true;

 Game.StartDlgBranch(\"dialogCaracol\");

   // Preparamos las respuestas para poder referenciarlas luego fácilmente
   Responses[0] = \"Buenas, soy ornitopato y quiero ser un gran detective\";
   Responses[1] = \"Vengo a resolver EL ASESINATO MISTERIOSO\";
   Responses[2] = \"Disculpe buen tendero, ¿sabe dónde está la pollería de Alcatraz?\";
   Responses[3] = \"Mi Mamá me ha dicho que los caracoles son la representación del mal\";
Responses[4] = \"¿Qué cosas vendes en la tienda?\";
Responses[5] = \"Mmmhn... en realidad no quería hablar con usted\";

 while(loop){

   // fill the response box
   Game.AddResponseOnce(0, Responses[0]);
   Game.AddResponseOnceGame(1, Responses[1]);
   Game.AddResponseOnce(2, Responses[2]);
   Game.AddResponseOnceGame(3, Responses[3]);
   Game.AddResponse(4, Responses[4]);
   Game.AddResponse(5, Responses[5]);

   // let the player choose one
   selected = Game.GetResponse();

   // let the actor say the selected sentence
   // (that's why I use the array for storing the sentences)
   actor.Talk(Responses[selected]);

   //El caracol responde en función de lo que le hayamos dicho
switch(selected){

case 0: dialDetective();
break;

case 1: dialAsesinato();
break;

case 2: dialAlcatraz();
break;

case 3: this.Talk(\"¿Tú eres un hijo de pata verdad?\");
actor.Talk(\". . .  \");
break;

case 4: dialQueVendes();
break;

case 5: loop = false;
break;
}
 }

 Game.EndDlgBranch();
}


En ese trozo de código se implementa la primera lista de opciones del primer diálogo de nuestra aventura, como veréis hay "cases" en los que se desarrolla un pequeño diálogo y otros en los que se invoca a una función, que tendrá el mismo esqueleto que esta y que gestionará esa rama de diálogo. De esta forma vamos creando el árbol de diálogo de forma relativamente cómoda. Para saber más sobre diagrámas o máquinas de estado podéis ir al artículo que me referí arriba clickando AQUÍ.

Una cosa a tener en cuenta en esta forma de implementar los diálogos es que el texto que los conforman se encuentra dentro del mismo código. Esto es un inconveniente a la hora de localizar el juego a otros idiomas. Por tanto, si queremos hacer las cosas bien tendremos que cambiarlo. En Wintermute este problema se soluciona con una herramienta que se encarga, a posteriori, de sacar todas las líneas de diálogo del código y crear un fichero independiente. Pero claro, eso es para que el desarrollador no tenga que mancharse las manos. Si queremos hacerlo nosotros, será mucho más fácil preverlo y crear un archivo con todo el texto que queramos localizar y un identificador para cada linea independiente. Esto podemos hacerlo en un archivo texto plano, en un archivo binario o, preferiblemente, en un XML, que nos permitiría escribir las frases en distintos idiomas como atributos de un mismo identificador o tener varios archivos en los que guardar identificadores y frases con su correspondiente predicado de idioma. En cualquier caso, yo no sé mucho de XML y no me voy a meter por ahí, la idea es esa.

Podríamos tener, por ejemplo, un archivo Español.txt en el que guardemos los trozos de texto uno debajo de otro separados por ';' (para poder usar retornos de carro dentro de los textos) y otro llamado English.txt en el que los textos esté guardados en el mismo orden, solo que en este idioma. A la hora de comenzar el juego pediríamos al jugador elegir el lenguaje del juego y cargaríamos un archivo u otro en función de la elección, asignando un identificador ordinal sucesivo a cada texto.

Esto puede resultar pesado a la hora de escribir el código ya que el resultado será un montón de instrucciones con identificadores que apuntan a los distintos textos de nuestro archivo. Y tenemos otro problema. Necesitamos algún sitio donde tener escrito previamente todo el diálogo de forma comprensible, ya que esta forma de referenciarlo no nos permitirá seguirlo con facilidad. Este problema se va a presentar siempre, usemos la técnica que usemos, a no ser que creemos nosotros mismos una herramienta que nos solucione la conversión. Que yo sepa esa herramienta aún no existe, y si alguien la conoce me encantaría que comentara con un link o algo de información ;) Pero podemos hablar de como sería la ayuda ideal a la hora de escribir los diálogos.

Nosotros, como ayuda poco costosa de construir, simplemente nos inventamos un sistema de colores y punteros para poder dintinguir las distintas ramas de diálogo conforme las escribíamos en una hoja de cálculo. Pero la herramienta ideal a la que me refiero sería una aplicación que nos permitiera ir creando el árbol de diálogo fácilmente y luego lo convirtiera ella misma en el código necesario.



En el dibujo, el diálogo de arriba en un formato más fácil de seguir.

La herramienta debería permitir en cada rama de diálogo, pulsar sobre ella e ir creando nuevos cuadros de diálogo y nuevas hebras con facilidad. Así como identificar a qué personaje consiste cada línea (en el ejemplo todas las frases son del protagonista menos la subrayada que pertenece al caracol maligno), de forma que luego la aplicación tuviera toda la información necesaria para construir el código y los archivos de localización.

No es un trabajo sencillo y sobre todo necesitaríamos definir muy finamente cómo debe ser una salida estandar, es decir, cómo serían los archivos de diálogos de forma que luego pudieran utilizarse desde el juego como si de una librería o una clase se tratara.

Con todas estas fantasías y propuestas le doy fin a este artículo que ya se está alargando demasiado. Creo que he recorrido los principales baches o inconvenientes que nos podemos encontrar a la hora de implementar los diálogos en una aventura, un juego de rol o cualquier otro juego que utilice un sistema conversacional con posibilidad de elección (si el jugador no puede elegir solo tendremos que poner las frases o lanzar los archivos de audio con el tiempo suficiente para que el jugador los lea, uno tras otro y punto.) Haré un pequeño resumen para atar cabos:

* Los diálogos suelen tener que escribirse, al menos, dos veces. Una en la que los creamos sobre papel o un formato electrónico cómodo para nosotros y otra cuando los codificamos. Lo ideal sería escribirlos una vez en una herramienta cómoda que hiciera el trabajo sucio de copiar-pegar al código por nosotros.

* De cara a la localización, el texto debería guardarse en archivos independientes del código que permitan traducir el texto sin tener que tocar los fuentes.

* Tenemos que tener siempre en cuenta y apuntar a qué diálogo dentro del juego pertenece el texto que escribimos, así como a qué rama dentro de esa conversación y a qué personaje de los involucrados. Es importante que todo esté bien apuntado ya que luego a la hora de implementar serán todo identificadores y código.

Escribir los diálogos es, sin duda, la parte más divertida de desarrollar una aventura así que todas estas operaciones no son tan tediosas como puede parecer. Yo me lo pasé muy bien escribiendo los diálogos que tenemos y espero continuarlos pronto (algún día). Pasarlos al código no era tan divertido, pero con Wintermute sí que ves rápidamente el resultado, lo que es muy de agradecer. Los diálogos son una forma divertida (y poco costosa en comparación con otras como las animaciones o los distintos vestuarios) de infundir vida a un personaje de juego, así que ánimo a todos aquellos que hayan pensado meterle mano al tema. Al principio puede parecer confuso, pero ya veréis cómo gana el juego cuando vuestro PJ empiece a soltar frases divertidas, ingeniosas o estúpidas como respuesta a las acciones o a los propios PNJs. ;)

Enlaces relacionados:
Página oficial de Wintermute
url=http://deadchannel.blogsome.com]Dead Channel[/url] - Blog de informática, juegos, tortugas y lo que me viene dando en gana ;P

Dokko

parece interesante, luego en casa me lo leere mejor jeje






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.