3. Organización, library card, regiones y backdrops

Inform 7: Empezando a programar - capítulo III

Por Xavi C.

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

En el anterior capítulo aprendimos a crear verbos, a programar condicionales, objetos con características tales como contenedores y con cerrojos y también a programar sucesos aleatorios. En esta ocasión veremos como organizar un código fuente en Inform, para que no nos perdamos en él en caso de retomarlo más tarde, a programar regiones y decorados comunes y a profundizar en la programación de puzzles más complejos. ¡Vamos allá!

Cómo organizar el código fuente

Habrás podido observar que nuestro código fuente se hace cada vez más largo, y llega un momento en que es difícil encontrar la parte del código que estamos buscando. Inform nos provee de partes y secciones para hacernos la vida más fácil cuando el código empieza a ser extenso. No hay una única forma de organizar el código y puedes utilizar la que tu quieras; en mi caso voy a dividirlo en cinco partes, a saber: Introducción, Escenario, Reparto, Nudo y Vocabulario (una organización un tanto teatral, pero útil para mí). Dentro de cada parte se pueden poner secciones, así por ejemplo dentro de Reparto puedo poner al jugador, a la serpiente y al náufrago, pues son los personajes de mi juego. Veámoslo, copia las siguientes partes y colócalas donde corresponda en tu código (tendrás que reorganizar algunas partes del mismo):

Part 1 - Introducción

Part 2 - Escenario

Part 3 - Reparto

Part 4 - Nudo

Part 5 - Vocabulario

Por ejemplo:

Part 1 - Introducción

When play begins:

clear the screen;

display the boxed quotation

"La isla.

por Grendelkhan";

show the current quotation;

wait for any key;

Part 2 - Escenario

Bosque is a room. The description is "Te encuentras en un bosque de enormes árboles."

...

Esto puede parecer poco útil al principio, pero a medida que el código crezca será vital. ¿Porqué? Porque puedes navegar por tu código de forma muy ágil a través de la pestaña Index. Vamos a verlo; compila tu código y en la pantalla del juego pulsa la pestaña Index. Verás algo similar a la imagen: aparece un "Contents Index" por el cual podemos navegar si pulsamos las flechitas naranjas que aparecen al lado de cada parte y sección... ¡nunca más nos perderemos al revisar un código fuente!

Los datos bibliográficos

Si sigues mirando por el panel Index, verás que más abajo aparece una sección llamada "Library Card", que son los datos que proporciona el juego acerca de su título, su autor, su año de publicación, etc. Verás que la "Story Genre" es actualmente "Fiction". En Inform los géneros son por defecto los siguientes: Comedy, Erotica, Fairy Tale, Fantasy, Fiction, Historical, Horror, Mystery, Non-Fiction, Other, Romance, Science Fiction, Surreal.

Bien, yo creo que por el momento es una historia misteriosa, así que le pondré "Mystery", pero... ¿dónde? Todo esto lo podemos editar nosotros en nuestro código, y la mejor forma de hacerlo es modificar la parte de la Introducción para que muestre algo similar a esto (copia y modifica el siguiente código y reemplaza la parte de la Introducción anterior de forma similar a la imagen):

The story title is "La isla misteriosa".

The story author is "Grendelkhan".

The story headline is "'Una aventura de impredecibles consecuencias'".

The story genre is "Mystery".

The release number is 1.

The story creation year is 2011.

The story description is "El gran conquistador Hernán Cortés se encuentra a merced del peligro en una tierra exótica buscando un tesoro perdido... ¿logrará encontrarlo? ¡Solo depende de tu pericia en esta aventura singular!".

Como verás, el "story title" cambia el título anterior, por lo que deberás borrar el que había o te dará error. Asegúrate de dejar una línea en blanco siempre tanto arriba como abajo de las "Part" y "Section" o también te dará error. El "[ Datos bibliográficos ]" es solamente un comentario, puedes comentar siempre que quieras tu código poniendo entre corchetes tu comentario. Asegúrate de incluir las extensiones y el mensaje inicial en la Introducción.

Para comprobar que todo ha salido bien, compila tu código y revisa el panel Index, verás que ha cambiado. También puedes teclear "version" para que Inform te de la información bibliográfica. Todo esto será útil posteriormente para la catalogación de tu juego en las diferentes webs, bases de datos y bibliotecas de ficción interactiva de la red.

Describir personajes en su localidad

Y una vez visto esto, vayamos al punto en que lo dejamos en el anterior capítulo, que era: ¿cómo harías para que el náufrago te diera la llave, tras preguntarle por el cofre? ¿cómo mejorarías al náufrago para que se diera una descripción diferente de él tras mirar la localidad? Vamos a posponer la primera cuestión porque es mas complejo programar esto con los personajes, lo veremos más adelante. Una opción para la segunda cuestión sería la siguiente:

The naufrago is a man in the Isla. The printed name of naufrago is "náufrago". The description is "Un hombre vestido con arapos está tumbado sobre la arena, moribundo.". Understand "hombre", "arapos", "moribundo" as the naufrago.

Rule for printing room description details of naufrago:

if the Isla is unvisited, say " moribundo tumbado sobre la arena, por";

if the cofre is carried and Isla is visited, say " mirando con sorpresa tu misterioso cofre, por";

omit contents in listing.

Observa que le hemos puesto "The naufrago", no simplemente "naufrago", para que acompañe un artículo al nombre: así será "un náufrago" (sin embargo, más adelante le quitaremos el "The" puesto que el náufrago tendrá nombre propio, y no queremos que salga "un Antonio", por ejemplo). Por otro lado, en la regla "Rule", le hemos puesto que si llega por primera vez a la isla "if the Isla is unvisited" diga una cosa, y si el jugador lleva el cofre encima "if the cofre is carried" diga otra. Habrá que poner el "and Isla is visited" para que no salgan las dos cosas a la vez en caso de que el jugador llegue por primera vez a la isla cargado con el cofre.

Algo similar podría hacerse para la serpiente:

Rule for printing room description details of serpiente:

if the Bosque is unvisited, say " aproximándose hacia tí desde el sur,";

otherwise say " siseando amenazadoramente, impidiéndote el paso hacia el sur,";

omit contents in listing.

En este caso hemos simplificado las opciones, pues ese "otherwise" significa que "en cualquier otro caso, hagas esto", así de rápido y sencillo.

Planeando puzzles complejos

Ahora toca programar el puzzle del cofre, el más complicado, que será el siguiente: para abrir el cofre debemos conseguir la llave de oro, que nos la dará el náufrago a cambio de agua; el agua se podrá conseguir en un riachuelo que habrá en el interior de la isla, siempre y cuando la cojamos con un recipiente, pues de lo contrario se nos escurrirá entre las manos. ¿Complicado, no? Así es, un poco complicado pero lógico y honesto con el jugador, ¡nadie dijo que fuera fácil para él! Recuerda siempre en planificar bien el puzzle: ¿el jugador sabrá qué hay que hacer? ¿cómo se resuelve? ¿existe más de una manera?

Regiones y backdrops

Empecemos pues por crear el nuevo escenario para el riachuelo, ahora ya sabes como hacerlo, pero lo que no sabes es hacer regiones. Digamos que la isla es una región, y tanto la costa como el riachuelo forman parte de la misma. Habrá que modificar la isla inicial y crear una región. Además, el jugador debería poder nadar en cualquier parte de la isla que dé al mar, esto se consigue con los "backdrop" que veremos a continuación. Aquí va el código (reemplaza la sección de la isla por la siguiente):

Section 4 - La isla

The islas is a region. The Isla, the Isla2, the Isla3 and the Isla4 are in the islas.

The vegetacion is a backdrop in the islas. The description is "Multitud de árboles frutales y flores de vivos colores te sorprenden a tu paso, ¡es un auténtico paraiso!.". Understand "arboles", "plantas", "flores", "flor", "bosque" and "oceano" as the vegetacion.

The arena is a backdrop in the islas. The description is "La playa está cubierta de fina arena, que se te escurre entre los dedos.".

Isla is a room. The printed name of Isla is "Costa de la isla". The description is "[if unvisited]Has llegado a una exótica isla en mitad de la inmensidad del mar. Te sorprende la singular belleza de estas costas, que se extienden de este a oesta hasta donde alcanza la vista.[else]La línea de la costa se extiende de este a oeste en esta paradisíaca isla, hasta donde alcanza la vista.".

Isla2 is west of Isla and east of Isla4. The printed name of Isla2 is "Costa de la isla". The description is "[if unvisited]Continúas explorando la isla. Te sorprende la singular belleza de estas costas, que se extienden de este a oesta hasta donde alcanza la vista.[else]La vegetación es más densa en esta parte de la isla y te obliga a meterte en el agua hasta casi la cintura. La línea de la costa continúa de este a oeste.".

Isla3 is west of Isla4 and east of Isla. The printed name of Isla3 is "Costa de la isla". The description is "[if unvisited]Sigues explorando la isla. Te sorprende la singular belleza de estas costas, pero más adentro, al norte, te llama la atención un camino que conduce a un espeso bosque.[else]La isla se extiende en una larga playa de fina arena hasta donde alcanza la vista. Más adentro, al norte, puedes ver un camino que conduce a un espeso bosque.".

Isla4 is east of Isla3 and west of Isla2 and south of Bosque2. The printed name of Isla4 is "Costa de la isla". The description is "[if unvisited]Continúas explorando la isla. Te sorprende la singular belleza de estas costas, que se extienden de este a oesta hasta donde alcanza la vista.[else]La isla se extiende en una larga playa de fina arena hasta donde alcanza la vista.".

Bosque2 is north of Isla3. The printed name of Bosque2 is "Bosque de la isla". The description is "[if unvisited]Has llegado a un exótico bosque. Las plantas, los árboles y las flores de vivos colores te hacen sentir como si estuvieras en un paraíso.[else]Contemplas la gran variedad de vegetación que hay en la isla, algunas plantas jamás las habías visto antes. Más allá, al sur, se vislumbra la costa.".

Section 4.1 - El mar

The mar is a backdrop in the islas. The description is "Estas aguas son tan bellas como peligrosas, piensas mientras observas la línea de la costa, allá a lo lejos.". Understand "costa", "costas", "playa", "aguas", "agua", "linea" and "oceano" as the mar.

Instead of nadaring en the mar:

say "Decidido y sin temor te adentras en el mar, nadando hacia la costa...[paragraph break]";

wait for any key;

if a random chance of 1 in 5 succeeds:

say "Pero de repente observas una amenazadora aleta de tiburón que se aproxima hacia tí... ¡intentas huir con todas tus fuerzas! Pero...[paragraph break]";

end the game in death;

otherwise:

say "Finalmente, y tras un gran esfuerzo, llegas a la playa...[paragraph break]";

wait for any key;

now the player is in Playa.

Instead of nadaring in the islas, try nadaring en the mar.

Esta parte del código es más larga y ciertamente tiene más complejidad, pero seguro que la entiendes, primeramente le informamos a Inform que habrá una región llamada "islas" en la que pondremos todos los escenarios y localidades de la isla: "The islas is a region. The Isla, the Isla2, the Isla3 and the Isla4 are in the islas.". Esto es especialmente útil cuando queremos que un determinado decorado se repita en muchas localidades, como por ejemplo la arena o el mar. Ahora se podrá nadar en cada localidad con mar gracias a la sentencia: "Instead of nadaring in the islas, try nadaring en the mar.", que hemos modificado de la anterior para que surja efecto en todas las localidades de la región "islas". ¿Parece complicado? No lo es tanto... una vez que lo sabes, claro.

Un decorado para todas las localidades

Para la vegetación, he optado también por un backdrop: "The vegetacion is a backdrop in the islas. ", así resuelvo el tema del decorado con una sola orden, y lo mismo para la arena. ¿Y cómo lo haríamos para programar el sol, si queremos que salga en todas las localidades? Haremos uso de la propiedad "everywhere", así:

The sol is a backdrop. The sol is everywhere. The description is "El sol se muestra imponente en mitad del cielo azul.".

Con ese "The sol is everywhere." conseguimos meter al sol en todas las localidades de nuestro juego. ¿Fácil, no? Todo es cuestión de práctica, Inform es fácil cuando sabes lo que tienes que poner, ya que no es tan evidente la propiedad "everywhere"; una vez más te recomiendo que ante cualquier duda consultes la pestaña Documentation del editor.

Empezando a programar puzzles complejos: objetos escondidos

Vayamos ahora a programar el riachuelo y el recipiente para el agua. Como ya vamos sabiendo un poco más, hagamos que el recipiente, una cantimplora, esté bajo unos tablones de madera de un naufragio, en una de las costas. Ahí va mi propuesta:

Some tablones are in Isla4. They are fixed in place. "Unos tablones de madera procedentes de un naufragio se encuentran tirados por la arena.". The description is "Restos de un naufragio, y por su aspecto no hace mucho que llegaron a estas costas.". Understand "tablas", "tablon", "restos" and "naufragio" as the tablones.

The cantimplora is female. The description is "La cantimplora está algo roñosa, pero parece en buen estado.".

Instead of turning or touching or pushing or pulling the tablones, try taking the tablones.

Instead of taking the tablones for the first time:

move the cantimplora to Isla4;

say "Los tablones pesan demasiado, pero al moverlos has dejado al descubierto una cantimplora.".

Instead of taking the tablones, say "Los tablones pesan demasiado para llevarlos tu solo.".

Como verás, aquí también hay novedades. Introducimos la propiedad "fixed in place", que difiere de la de "scenery" en que el objeto se mostrará en la descripción de la localidad, pero no podrá moverse de ahí (puedes obtener más información sobre los diferentes tipos de objetos en el capítulo 3 del manual integrado en el editor de inform: 3.27. Review of Chapter 3: Things). A continuación he puesto una cadena de texto, así sin "description" ni nada; cuando se pone así Inform lo que hace es escribir esa cadena de texto en lugar del objeto (también podríamos haberlo usado para la serpiente, el náufrago, etc.).

También hemos hecho un uso intensivo de "try" para que el jugador siempre que manipule los tablones lo que Inform entienda es que los quiere coger: "Instead of turning or touching or pushing or pulling the tablones, try taking the tablones.", lo cual será muy útil para que el jugador entienda que no puede hacer nada con ellos. Por último, hemos vuelto a usar la poderosa sentencia "for the first time" para que la cantimplora solo salga la primera vez.

Pruébalo y verás que todo funciona correctamente; se trata de un puzzle simple pero efectivo, tan antiguo como el comer, ¡esconder algo para que lo encuentre el jugador siempre se ha hecho y siempre se hará en ficción interactiva!

Objetos que cambian de estado

Ahora tenemos que programar el riachuelo, en el que conseguiremos el agua con la que llenar la cantimplora. Vamos a ello, primero crearemos el riachuelo en el bosque y después contemplaremos las opciones que se pueden hacer con él con la cantimplora y sin la cantimplora, además tendremos que modificar ligeramente la cantimplora (ya que puede estar llena o vacía). Veamos el código nuevo para la cantimplora:

The cantimplora is female. The cantimplora can be llena or vacia. The cantimplora is vacia. The description is "La cantimplora está algo roñosa, pero parece en buen estado, [if vacia]aunque no contiene nada.[else]está llena de agua.".

Observa ese "The cantimplora can be llena or vacia.", pues esto (llena y vacía) lo hemos creado nosotros, son estados definidos por el programador y son muy importantes, así podemos manejar los diferentes estados de un objeto. Además se pueden utilizar en las descripciones, como puedes ver con ese "[if vacia]". Atrévete a crear tus propios estados, por ejemplo para decir si el jugador está seco o mojado.

Comprobando las acciones del jugador: check

Pero ahora vamos a por el riachuelo, que se las trae, puesto que tendremos que implementar las diferentes acciones que puede llevar a cabo el jugador para tratar de llenar la cantimplora. Con check comprobamos que si las condiciones no están dadas, el flujo de la acción se detenga. Vamos a hacer uso de la sentencia "Check", que comprobará el resultado de una determinada acción, es diferente de "Instead" en que con check realmente se ejecuta la acción, en cambio con instead no llega a suceder. Tal vez lo veas más claro con el siguiente código, copialo y ejecútalo:

The riachuelo is fixed in place in Bosque2. "Un pequeño riachuelo cruza serpenteando el bosque.". The description is "El agua del pequeño riachuelo fluye limpia y clara.". Understand "rio", "agua", "caudal" and "fondo" as the riachuelo.

Instead of turning or touching or pushing or pulling the riachuelo, try taking the riachuelo.

Instead of putting the riachuelo on the cantimplora, try taking the riachuelo.

Instead of llenaring the cantimplora when the player is in Bosque2, try taking the riachuelo. [definimos verbo llenaring en Vocabulario]

Check taking the riachuelo:

if the player carries the cantimplora:

say "Llenas la cantimplora con el agua del riachuelo.";

now the cantimplora is llena;

rule succeeds;

otherwise:

say "Coges el agua del riachuelo con tus manos... y se escurre entre tus dedos.";

rule succeeds.

Por otro lado, tendremos que definir un verbo nuevo (llenaring) para poder poner "llena la cantimplora". Lo haremos así (cópialo en la sección de vocabulario):

llenaring is an action applying to one thing. Understand "llena [something]" as llenaring.

report llenaring: say "No parece que [the noun] pueda llenarse, ¿qué pretendes hacer exactamente?.".

Comprueba como funciona y después elimina todos los "rule succeeds" para ver el efecto de los checks, ¿lo ves más claro?

En el siguiente capítulo

Y ahora sí, ya tenemos programada la primera parte de nuestro gran puzzle, solo faltará darle el agua al náufrago, pero eso lo veremos en el siguiente capítulo, puesto que ya hemos visto suficientes cosas por ahora. Hemos aprendido a organizar el código, a crear regiones y decorados comunes e incluso a ver el funcionamiento de las condiciones y los "chequeos" que hace Inform sobre los objetos. Con todo lo que sabes, ya podrías programar tu propio juego. Para el siguiente capítulo vamos a aprender a programar escenas, a desambigüar objetos y a ver... ¡cocodrilos!