5. Tablas, listas, conversaciones y cambio de jugador

Inform 7: Empezando a programar - capítulo V
Por Xavi C.

Versión 1.2 - Revisión 14/01/11

En el anterior capítulo vimos una aproximación a las tablas de la mano de la extensión "Basic Help Menu SP by Emily Short", que hace uso intensivo de ellas. En esta ocasión aprenderemos a crear nuestras propias tablas y profundizaremos en la creación de conversaciones.


Uso de las tablas

En Inform podemos usar tablas, al estilo de las del Word o el Excel, para clasificar mejor los diferentes objetos y propiedades. ¿Para qué puede servir esto? Tiene una primera utilidad obvia: el orden. Gracias a las tablas, podemos escribir códigos más ordenados y utilizar menos líneas, ahora veremos un ejemplo práctico.

En el capítulo anterior teníamos al náufrago sediento, y solo si le dábamos agua nos ofrecía la llave de oro. Una vez con ella en nuestro poder, podíamos abrir el cofre y conseguir el mapa del tesoro. Por el momento, para probar la tabla, empezaremos con el mapa en nuestro poder. En el mapa pondremos una serie de anotaciones para llegar hasta el tesoro, y las pondremos en una tabla. Fíjate en el siguiente código:

The mapa del tesoro is carried by player. The mapa del tesoro can be seco or mojado. The mapa del tesoro is seco. The description is "¡Parece un mapa auténtico! En el mapa hay varias anotaciones: un dibujo, una cruz, un símbolo y un escrito. Tal vez si logro descifrarlo todo encontraré un tesoro... ¡y seré rico! ¡Ja!".

A anotacion is a kind of thing. The plural of anotacion is anotaciones. They are scenery. Some anotaciones in the mapa del tesoro are defined by the Table of tabla_anotaciones. The description of a anotacion is "[if the mapa del tesoro is seco]Bajo [palabra], está manuscrito lo siguiente: [descripcion].[otherwise]El mapa está mojado e inservible. ¡Deberías haber tenido más cuidado al cruzar a nado la costa!".

Table of tabla_anotaciones
    anotacion       palabra       descripcion  
    a dibujo       "el dibujo de la isla"       "Hay varias islas en este archipiélago del infierno, pero la isla del tesoro es la que está más al norte, y la más peligrosa..."  
    a cruz       "una cruz en el mapa"       "El tesoro se encontró en el barco 'Guadalupe', que fue atacado por los salvajes... si encuentro los restos del barco, encontraré la isla"  
    a simbolo       "un símbolo tribal"       "Este símbolo es la representación del dios de los salvajes que custodian el tesoro, tal vez si me lo tatuara creerían que soy su dios..."  
    a escrito       "un escrito"       "Romualdo Guimaraes, que murió persiguiendo un sueño. Si encuentras este mapa, encontrarás el tesoro o tu muerte."  

The cruz is female.

Before listing contents while taking inventory: group anotaciones together. Rule for grouping together anotaciones: say "en el mapa puedes ver el dibujo de una isla, una cruz, un símbolo y un escrito.".


Primero de todo ponemos que el mapa está en nuestro poder con "is carried by player", y que puede estar seco o mojado. Después, decimos que una anotación es una cosa cuyo plural es anotaciones con ese "The plural of anotacion is anotaciones", y que están definidas en la tabla_anotaciones (importante: no uses los mismos nombres para los objetos y las tablas; de ahí que haya creado una Table of tabla_anotaciones y no una Table of anotaciones, ya que anotaciones es el plural del objeto anotacion).

En la tabla hemos creado cuatro anotaciones: un dibujo, una cruz, un símbolo y un escrito. Estas anotaciones son objetos, pero se han programado en forma de tabla. Como los objetos de la tabla son masculinos, he puesto más abajo que "the cruz is female" para que Inform trate a la cruz en femenino, ¿ves que es un objeto?

Al principio puede ser tedioso lidiar con las tablas, pero es la forma más rápida de crear este tipo de objetos. Y con ellas se pueden hacer cosas mucho más complicadas. O podrías hacer una tabla de decorados para cada localidad, si así lo quisieras. O mejor aún, una tabla de conversación, en lugar de programar por palabras clave mediante Asking como hemos visto en el otro capítulo. Tienes mucha más información en la sección 15 de la documentación (15: Tables).


Listando contenidos

Por último aplicaremos una regla general: "Before listing contents...", que agrupará los objetos de un mismo tipo. Además queremos que en el caso de las anotaciones escriba una frase en lugar de una lista. Esto último puede ser muy útil, porque por lo general, los inventarios que ofrece Inform son exactos pero textualmente pobres. Aquí va mi propuesta:

Before listing contents while taking inventory: group anotaciones together.
Rule for grouping together anotaciones: say "en el mapa puedes ver el dibujo de una isla, una cruz, un símbolo y un escrito.".

Tienes más información al respecto en la sección 17.13. Listing contents of something y la 17.14. Grouping together something de la "Documentation" del IDE de Inform 7, te recomiendo que le eches un vistazo, ya que los jugadores continuamente estarán revisando sus posesiones, y queremos que luzcan lo mejor posible.


Cambiar al jugador

En el anterior capítulo dejamos un cocodrilo a medias: nuestro héroe era en realidad un alumno dormido en clase. Vamos a aprovechar la capacidad de Inform para crear personajes y asignarlos al jugador. Para empezar, crearemos al alumno y al aula (copia y coloca el código en sus secciones correspondientes):


The aula is a room. It is female. The printed name of the aula is "Aula de historia". The description is "Estás en clase de historia. Todos tus compañeros te miran divertidos al ver que te has vuelto a dormir en plena clase.".


Sebastian is a man in the Aula. The printed name of Sebastian is "Sebastián". The description is "Eres un alumno de instituto, aburrido en plena clase de historia."


Y por último, vamos a hacer que cuando el jugador "despierte", se de cuenta de que se ha quedado dormido en clase. Para ello utilizaremos un "Instead of waking up:" para decir que cuando despierte salga un texto y finalmente, pase a ser el alumno de la clase con "now the player is Sebastian". Aquí va mi propuesta:


Instead of waking up:
say "Oyes una voz a lo lejos que te dice: 'Sebastián! ¡Despierta, Sebastián! Otra vez te has quedado dormido en clase... [bold type]¡Sebastián!'[roman type][paragraph break]";
wait for any key;
say "Aturdido, te despiertas de un sobresalto. Te habías quedado completamente dormido en clase de historia, justo cuando el profesor estaba explicando todo el rollo de la colonización... ¿a quién le importará, si ya hace tanto de eso?[paragraph break]'Sebastián, ¿me puedes decir de qué estaba hablando?' te pregunta airado el profesor Antonio...";
wait for any key;
now the player is Sebastian.


Date cuenta que con la orden "now the player is..." podemos asignar como jugador a cualquier personaje del juego... ¡incluso la serpiente! Haz la prueba, pon "now the player is the serpiente." ¿Qué sucede? Funciona pero no acaba de quedar bien, porque no hemos preparado convenientemente a la serpiente. Pero las posibilidades son infinitas... imagínate lo que puedes hacer con esto, por ejemplo: un mago que convierte a príncipes en sapos, un vampiro que se transforma en murciélago, etc.


Profundizando en las tablas: conversaciones

Aprovechando el gran poder de las tablas en Inform, vamos a ver una utilidad para ellas: crear conversaciones. De esta forma ya sabrás dos formas de crear conversaciones. Te recomiendo que le eches un vistazo a la sección 15.13. Topic columns de la documentación, que profundiza bastante en la creación de conversaciones. Bien, vamos a crear al profesor y su tabla de conversación.


Section 4 - El profesor

A profesor is a man in the aula. "El profesor Antonio te mira con severidad.". The description is "Tiene un gran parecido con el náufrago de tu sueño.". Understand "Antonio" as the profesor.

After asking the profesor about a topic listed in the Table of profesor_conversacion, say "El profesor dice: [muse entry]."

Table of Profesor_conversacion
Topic       Muse  
"hola" or "explicacion" or "pregunta"       "'¡Te he hecho una pregunta! ¿Qué es lo que estaba explicando?'"  
"colonizacion"       "'Exacto, Sebastián... veo que por lo menos sabía a qué venías a clase. ¿Quién fue Colón?'"  
"colon" or "cristobal colon"       "'Te he hecho una pregunta, ¿quién fue Colón?'"  
"descubrimiento" or "descubridor"       "'Colón fue un descubridor, Sebastián... ¿y quién fue Hernán Cortés?'"  
"conquistador" or "hernan cortes"       "'Hernán Cortés fue el que conquistó el imperio azteca, lo que hoy es México.'" 
"no se" or "no lo se" or "ayuda"    "'¿Cómo que no sabes? ¡Hablamos del descubrimiento de América!'"
"america" or "continente"    "'Sí, América, lo que descubrió Colón ¿te suena el nombre, Sebastián?'"

¿Comprendes el anterior código? Primero creamos al profesor con "A profesor is a man in the aula.", después llamamos a la tabla de conversación con el "After asking the profesor about a topic listed in the Table of profesor_conversacion". ¿No te parece más fácil que como lo hacíamos antes?
Nota: Tienes que tener especial cuidado en separar cada Topic y Muse con una tabulación, no valen espacios: usa el tabulador.

Ahora podemos crear conversaciones de forma más ordenada y sin tantas líneas de código, pues solo hace falta una tabla. De todas maneras, el uso de las tablas puede ser todo lo complejo que quieras, ahora hemos visto un par de utilidades, pero a medida que sepas programar más te darás cuenta de sus múltiples posibilidades.


Dormir al jugador

¿Y para volver al estado anterior? ¡Claro que sí! Habrá que dormirse. Para ello, nada más fácil que incluir la siguiente regla:

Instead of sleeping:
    if the player is Sebastian:
        say "Lentamente tus ojos se cierran de nuevo y te sumerges en tu sueño...[paragraph break]";
        wait for any key;
        now the player is conquistador;
    otherwise:
         say "Creo que ya estoy durmiendo...".

Compílalo y pruébalo... ¿todo bien?

Sinónimos para verbos existentes

Tal vez compruebes que "dormir" o "duermete" no están de base en el vocabulario de Inform (pero sí "duerme"), no hay problema puesto que podemos asignar sinónimos a verbos que ya están implementados pero que no gozan de suficientes sinónimos. Así que podemos poner lo siguiente:

Understand "duermete", "dormir" as sleeping.

Por ejemplo, podemos crear un sinónimo para "coger" que sea "agarrar", con esta simple sentencia:

Understand "agarra [something]" as taking.

Tenlo en cuenta antes de crear verbos nuevos: a veces no hace falta crear más verbos, sino extender y poner sinónimos a los existentes.


Conversaciones por menús

Es posible una tercera forma de conversación: la conversación por menús. Hasta ahora hemos visto cómo decir palabras mediante sentencias o tablas, pero esto requiere que el jugador sepa qué tiene que decir. Podría suceder que el jugador no se estuviera enterando de nada y no supiera de qué hablar con un personaje. Para ello están las conversaciones por menús, que son más amigables para los jugadores nóveles, aunque un poco más complicadas de programar.

Para empezar, descarga e instala las dos extensiones indispensables para que funcionen las conversaciones por menús: la Reactable Quips SP.i7x y la Quip-Based Conversation SP.i7x, que podrás descargar de aquí.

Una vez instaladas las extensiones vamos a crear un proyecto nuevo, ya que no es correcto poner diferentes sistemas de conversación en un mismo juego (aunque en determinadas ocasiones puede hacerse, depende del contexto del juego). Vamos a crear pues un nuevo proyecto y llamaremos a las extensiones instaladas habituales y además, a la de conversación:

Include Spanish by Sebastian Arg.
Include Basic Screen Effects SP by Emily Short.
Include Quip-Based Conversation SP by Michael Martin.

En efecto, la última es la que hace posible la conversación por menús. 

Imaginemos que el jugador se encuentra en una tienda de ropa y quiere consultar algo con la dependienta. Vamos a crear la tienda y la dependienta:

Tienda is a room. "Te encuentras en una tienda de ropa femenina. Tienes que hacerle un regalo a tu novia y no sabes por dónde empezar a mirar."

a dependienta is a woman in Tienda. The description is "Una impresionante dependienta te observa divertida tras el mostrador."

Hasta aquí, nada nuevo, pero incluiremos la siguiente sentencia:

The litany of the dependienta is the Table of dependienta Comments.

Con la que le decimos a Inform que el discurso o letanía de la dependienta, la "litany", es la tabla "Table of dependienta Comments". Ahora tendremos que crear la tabla de conversación y la tabla de respuestas, pues ambas deben ir juntas. Además tenemos que especificar cuál es la primera opción de conversación. He aquí mi propuesta:

Table of Quip Texts (continued)
quip    quiptext
atender    "'No. Ahora estoy muy ocupada.'"
disculpe    "'¡Ahora no puedo atenderle!'"
nada    "'¡Claro que hago algo: estoy hablando con usted!'"


Table of dependienta Comments
prompt    response    enabled
"Hola, ¿me puede atender?"    atender    1
"¡Ah! Disculpe, es que estoy..."    disculpe    0
"¡Pero si no está haciendo nada!"    nada    0

After quipping when the current quip is atender:
    enable the disculpe quip;
    enable the nada quip.

Compílalo y prueba a hablar con la dependienta. Hemos creado una conversación sencilla pero efectiva con una dependienta un tanto arisca. Como puedes ver, primero hemos creado la tabla de respuestas "Table of Quip Texts (continued)", donde hemos habilitado una respuesta por cada cuestión o "quip". A continuación viene la tabla de "quips", en las que verás un 1 o un 0 al final de cada quip, esto quiere decir que si hay un 1 la cuestión está habilitada, y si hay un 0 está deshabilitada. ¿Cómo se habilitan? En el siguiente bloque lo vemos: "enable the disculpe quip;" que significa "habilita la cuestión disculpa". Si quisiéramos deshabilitar la cuestión, pondríamos "disable".


Un ejemplo de conversación por menús

Existe un ejemplo práctico que se utiliza desde los inicios de las conversaciones por menús en Inform, en el que se incluyen tablas de conversación que llaman a otras tablas de conversación y que pueden hacer terminar el juego. He aquí mi traducción del ejemplo "Joe Schmoe Revisited":

"Conversaciones con Juan"

The story headline is "Hablar por hablar".
Include Spanish by Sebastian Arg.
Include Basic Screen Effects SP by Emily Short.
Include Quip-Based Conversation SP by Michael Martin.
Use no scoring and no deprecated features.

Chapter 1 - The Setup

When play begins, say "¡Habla con Juan!"

Bar is a room. "Estás en el bar."

Juan is a man in Bar. The description is "Aquí está tu colega Juan." The litany of Juan is the Table of Juan Comments.

The greeting of yourself is selftalk.

Casting Xyzzy is an action applying to nothing. Understand "xyzzy" as casting xyzzy. Carry out casting xyzzy: deliver the xyzzy quip; run a conversation on the Table of Magic Followups.

Chapter 2 - The Script

Section 1 - The Text

Table of Quip Texts (continued)
quip    quiptext
selftalk    "Hablar contigo no es particularmente divertido."
who-am-i    "'Mal. Inform me odia.'"
why-hate    "'Intento compilar pero me salen 40 errores.'"
yay-inform    "'¿Has hecho un tutorial? ¡Voy a leerlo!"
hate-you    "'¡Te odio!'[paragraph break] Juan te mata."
hate-you-2    "'¡Te odio!'[paragraph break] Juan te mata.."
hate-you-3    "'¡Te odio!'[paragraph break] Juan te mata."
hate-pedants    "'¡Odio a los pedantes como tú!'[paragraph break] Juan te mata."
yay-monkeys    "'Claro que me gustan los monos.'"
yay-you    "'¡Ahora somos realmente amigos!'"
say-nothing    "Te quedas callado."
ehn-apes    "'Los gorilas molan, claro que sí.'"
ehn-lemurs    "'No tengo una opinión formada sobre los lemures.'"
xyzzy    "¿Cuál es la otra palabra mágica?"

Table of Juan Comments
prompt    response    enabled
"¿Qué tal, Juan?"    who-am-i    1
"¿Porqué te odia Inform?"    why-hate    0
"Ahá... ¿has leído mi tutorial?"    yay-inform    0
"No me extraña..."    hate-you    0
"Ja ja ja, ¡Inform te odia!"    hate-you-2    0
"Hey, ¿te gustan los monos?"    yay-monkeys    1
"¡Solo a los locos les gustan!"    hate-you-3    0
"Pensaba que sabías más sobre simios."    hate-pedants    0
"A mí también me gustan."    yay-you    0
"Mejor me callo."    say-nothing    1

Table of Quip Followups (continued)
quip    option    result
yay-monkeys    "¿Y los gorilas?"    ehn-apes
yay-monkeys    "¿Y los lemures?"    ehn-lemurs

Table of Magic Followups
prompt    response    enabled
"PLUGH"    yay-you    1
"Hay al menos dos más, ¿cuál de ellas?"    hate-pedants    1

Section 2 - Dialogue affects itself

After quipping when the current quip is who-am-i:
    enable the why-hate quip;
    enable the hate-you quip.

After quipping when the current quip is why-hate:
    disable the hate-you quip;
    enable the hate-you-2 quip;
    enable the yay-inform quip.

After quipping when the current quip is yay-monkeys:
    disable the who-am-i quip;
    enable the hate-you-3 quip;
    enable the hate-pedants quip;
    enable the yay-you quip.

After quipping when the current quip is say-nothing:
    enable the say-nothing quip;
    terminate the conversation.

Section 3 - Dialogue affects the game

After quipping when the current quip is hate-you: end the story saying "Estás muerto".
After quipping when the current quip is hate-you-2: end the story saying "Estás muerto".
After quipping when the current quip is hate-you-3: end the story saying "Estás muerto".
After quipping when the current quip is hate-pedants: end the story saying "Estás muerto".
After quipping when the current quip is yay-inform: end the story finally saying "Has ganado".
After quipping when the current quip is yay-you: end the story finally saying "Has ganado".


Como puedes ver, se trata de una conversación de ejemplo bastante estúpida, pero que funciona perfectamente y que puedes modificar para tus propios juegos.

Ahora la historia la terminas tú

Llegados a este punto del tutorial, creo que ha llegado el momento de que tú mismo termines la historia. Ya tienes los conocimientos necesarios para crear cualquier localización, objeto y personaje que imagines, así como todo el vocabulario nuevo que necesites, y también las escenas y tablas que precises.

La historia que yo haga será diferente de la tuya, seguramente. Yo intentaré cruzar las dos historias enlazadas de alguna forma, pero a partir de ahora mi tutorial se centrará en otros aspectos de la programación que no tendrán que ver con la historia de la isla, como podrás ver en el siguiente capítulo...

En el siguiente capítulo

Vamos a ver la diferencia entre un juego en código Z y otro en código Glulx; y además vamos a probar más extensiones, ¿se te ha ocurrido hacer un librojuego con Inform? Verás que es posible...


Comments