jueves, febrero 09, 2012

Sistemas para crear aventuras conersacionales (I)

Las aventuras de texto es uno de los géneros dentro del mundo de los videojuegos que cuenta con mas herramientas para crearlos. Tal vez debido a la relativa sencillez, ya que es una terea posible para una única persona, desde  casi los principios del genero se han creado diferentes compiladores, herramientas, parsers y todo tipo de complementos para ayudar a crear estos mundos virtuales. 

En esta serie de articulo vamos a echar a un vistazo a unos cuantos sistemas para crear aventuras desde en lenguajes de programación genéricos hasta los parsers mas especializados.

Mi principal motivación es que me gustan tantos las aventuras conversacionales como la retro-programación. Así que para mi esta es la combinación perfecta; en realidad estoy escribiendo los artículos que me gustaría leer a mi.


Adventure


Impresión de una partida de Advent en un PDP-10, via Wikipedia

O "Cave Adventure" o la "Aventura Original". Un juego que definió el genero y siguió influyendo a nuevos juegos creados muchos años después. La autoria es compartida, Crowthers creo un juego de exploración de cuevas para entretener a sus hijos y Woods la amplio y añadió un toque más fantástico, pero tecnicamente usan la misma estructura.

El juego esta programado en Fortran y los datos se encuentran en un fichero de texto con la información del juego. Este fichero se encuentra divido en bloques. Primero tenemos una tabla con las descripciones de los escenarios del juego. Tiene este aspecto
1 YOU ARE STANDING AT THE END OF A ROAD BEFORE A SMALL BRICK
1 BUILDING . AROUND YOU IS A FOREST. A SMALL
1 STREAM FLOWS OUT OF THE BUILDING AND DOWN A GULLY.
2 YOU HAVE WALKED UP A HILL, STILL IN THE FOREST
2 THE ROAD NOW SLOPES BACK DOWN THE OTHER SIDE OF THE HILL.
2 THERE IS A BUILDING IN THE DISTANCE.
Es una simple tabla con un identificador seguida de una linea de texto, siempre en mayúsculas por las limitaciones del hardware de la epoca. Las lineas con el mismo identificador corresponden a diferentes lineas de una misma descripción, una estructura muy sencilla. un -1 como identificador indica el final de cada bloque.

El siguiente bloque son las descripciones cortas para los lugares ya visitados. A continuación hay una tabla numerica con las conexiones de cada habitación, con la estructura id-de-habitacion id-habitacion-destino lista-de-ids-de-vocabulario. Por ejemplo la primera entrada
1 2 2 44 
Para ir de la habitación 1 a la 2 se pueden usar las palabras con id 2 o 44.
La siguiente es la lista de vocabulario, organizada de una manera especial. Todo el vocabulario es de la forma id palabra, usandose ids duplicados para representar sinónimos. De esta forma
1002 LAMP
1002 HEADL
El objeto 1002 es la famosa LAMP; o tambien HEADLamp. Dado que una word de memoria del PDP-10 en que se programo caben 5 caracteres, el numero de caracteres que reconoce el parser esta tambien reducido a estos 5, aumentando la compresión y facilitando las comparaciones.

En este caso el numero de id añade un significado especial. Los 70 primeros se pueden usar como verbos de movimiento, (aunque estrictamente no todos son verbos, nos podemos mover con comandos como "door" o "rock"). Los siguientes, empezando en los miles definen los objetos que se pueden coger, en los dos miles los verbos y en los tres miles algunos comandos especiales como el de ayuda.

El siguiente bloque son unos mensajes de estado que reflejan cambios permanentes en el escenario o que son mostrados cuando hay un objeto presente, con la misma estructura que los mensajes normales.

A continuación a otro bloques de mensajes, que esta vez hacen referencia a eventos, como cuando aparece ese enano que nos lanza flechas.

Y con un 0 termina este fichero de datos. Si bien la mayor parte del contenido esta definido en este fichero; una parte muy importante, las logica en si del juego no esta aqui, si no en la parte en Fortran. Por lo tanto se pueden editar los textos, objetos y conexiones del juego, pero no cambiar significativamente los resultados de las acciones ni por supuesto crear un juego diferente.

El parser es muy simple, reconociendo la estructura verbo nombre, con alguna de Si/No en ciertas situaciones. La longitud de palabra limitado al tamaño de la memoria real hace que las comparaciones sean casi triviales y el parsing muy sencillo.

Pensando cuando fue creado y para que, me parece que tiene una estructura sencilla y inteligente, aun mirandolo desde la perspectiva de hoy en día.


A-Code

El éxito de Adventure fue fulgurante, y su fama se extendió por Arpanet, la precursora de internet. Al estar su código disponible, no tardaron en surgir variaciones, clones y re-interpretaciones del original. Una de las ampliaciones mas famosas dentro del ambiente de los main frames era la Adventure de 550  puntos de Dave Platt, creada alrededor de 1979.

Esta versión usaba un lenguaje propio para crear aventuras, de forma que se podían crear todo tipo de juegos (mas o menos parecidos a Adventure), el llamado A-Code. En principio era un lenguaje que generaba un binario que era interpretado después, pero debido a la lentitud de este metodo, se modifico para generar código Fortran (y mas tarde C) que debía ser procesado por el compilador correspondiente, disparando la velocidad de ejecución.

Dado que el A-Code es un lenguaje pensado para soportar cualquier tipo de aventura, es un lenguaje más generico. Los mensajes de texto se definen con la palabra clave TEXT identificador y el texto en la siguiente linea, sacada de la aventura de 550 puntos:
TEXT     DWARFBLOCK
         A little dwarf with a big knife blocks your way.
Para definir una localidad se usaba la palabra clave PLACE de esta manera
PLACE     ROAD
          You're at end of road again.
         %You are standing at the end of a road before a small brick building.
          Around you is a forest.  A small stream flows out of the building and down a gully.
Como podeis ver se puede especificar un nombre clave para cada localidad, una descripción corta que se usa a partir de la segunda vez que se visita (poco usado en las aventuras europeas), la descripción normal y una descripción larga (precedida de &).

Los objetos se definen de una forma parecida
OBJECT    LAMP
          Brass lantern
         %There is a shiny brass lamp nearby.
         %There is a lamp shining nearby.
Los nombres de los objetos quedan automaticamente registrados en el vocabulario que reconoce el juego (el parser no es mucho mejor que el de Adventure). Una de las características de las descripciones en A-Code, es que se puede escribir mas de una descripción por objeto, para mostrar variaciones aleatorias o dependiendo del estado del objeto, como en el caso de esta reja:
OBJECT    GRATE
         {Grate}
         %The grate is locked.
         %The grate is open.
Que puede estar abierta o cerrada. Tambien se pueden crear sinónimos de identificadores de esta forma:
SYNON     LAMP,HEADLAMP,LANTERN
Pasando a como se organizan internamente las respuestas, se trata de un pequeño lenguaje de programación que permite variables:
VARIABLE LAMPLIFE
Ademas todos los objetos y localidades tienen una variable de estado, que puede accederse bit a bit como flags. Para condiciones locales se utiliza:
AT       BUILDING
         MOVE ROAD,ROAD
         MOVE OUT,ROAD
         MOVE OUTDOORS,ROAD
         MOVE WEST,ROAD
         IFLT  CLOSURE,2      {is the cave open?}
            SMOVE XYZZY,DEBRIS,FOOF
            SMOVE PLUGH,Y2,FOOF
         FIN
AT       BUILDING
         ANYOF STREAM,DOWNSTREAM
         SAY   PIPEFIT
         QUIT
Que define las salidas en el primer bloque (puedes moverte escribiendo tanto las direcciones como el nombre de las localidades adyacentes). Y luego condiciones como chequear si ya se ha abierto la cueva (comprueba que la variable CLOSURE sea menor que 2 y entonces activa las palabras magicas)o mostrar una descripción con el comando SAY al examinar el riachuelo.

Las respuestas a acciones se definen de una forma parecida:
ACTION   DIG
         SAY   NEEDSHOVEL
         QUIT
En este caso si intentas cavar te dira que necesitas una pala. Tanto con AT como con ACTION se pueden  escribir tantos iguales como se quiera. Se iran ejecutando en orden  hasta que se encuentre un comando QUIT. Como se puede ver es un lenguaje potente, pero no deja ser un lenguaje estilo assembler, con un comando y sus parámetros. Eso si, a parte de los típicos CALLs  a subrutinas (con  etiquetas declaradas con LABELs), tambien se pueden utilizar IF, como en el ejemplo, lo que simplifica un poco la programación

Proviniendo dentro del mundo de los main frames, donde la memoria no era tan escasa como en los micros, los juegos de A-Code incluyen muchas descripciones y muchos pequeños detalles para las acciones del jugador. Así que los juegos incluyen innumerables AT y ACTION...

Este es solo un vistazo por encima, el A-Code tiene muchas mas detalles para crear aventuras complejas muy elaboradas (la de 550 puntos es enorme pero existe incluso una version de 770 puntos de Adventure mantenida hasta hoy en dia!), y ademas fue evolucionando con los años.

Por último una nota más. En el mismo año (1979) la casa inglesa Level 9 desarrollaría tambien un lenguaje para aventuras llamado A-Code pero que no tiene ninguna relación con este. Hablaremos del A-Code de Level 9 en otra ocasión.


Pagina sobre A-Code.
La aventura de 550 puntos original de Dave Platt.


Conclusión

Proximamente hablare otros sistemas que precisamente buscan ejecutarse en maquinas con tremendas limitaciones de memoria y eso condicionara todo el sistema. Aun así algunos conceptos del A-Code, aunque probablemente no directamente, pasaron a estas aventuras de micros (como las respuestas encadenadas y la diferenciación de variables-flags).

En principio, para la segunda parte estoy preparando las aventuras de Scott Addams, y luego tendremos las de Infocom, EAMON,  Quill/PAW, GAC y algunos sistemas menores (¿alguien conoce Genesis de CRL?).