|  |  | Por dónde empezar.

## Por dónde empezar.

Evidentemente, antes de nada, tienes que asegurarte de disponer de todos los ingredientes necesarios para la programación con Inform. Asegurate de tener la última versión de todo, para poder seguir este cursillo. Si no sabes lo que necesitas, mira este enlace. Incluso si lo sabes, se recomienda mirarlo, pues se explica además cómo se usan estos ingredientes para "compilar" un juego, algo que tendrás que hacer muy a menudo a lo largo de este cursillo.

Ahora podemos empezar a diseñar el juego. Lo primero, evidentemente, es el guión, que puede ser una idea genérica que se vaya concretando a medida que se programa, o puede ser una historia totalmente detallada, incluyendo incluso los rompecabezas del juego. Cada uno tiene su estilo a la hora de diseñar el guión, pero en este cursillo te lo vamos a dar ya diseñado y con bastante detalle, para que sepas lo que te espera.

### El guión del juego

Estás encerrado en una torre, de la que tienes que escapar. El mapa de la torre es el siguiente, las flechas dobles quieren decir "subir o bajar".

El juego comienza en la habitación llamada `PuertaPrincipal`, pero no se puede salir de la torre desde ahi. La salida de la torre está en la `Mazmorra`. Para salir, el jugador deberá:

- Descubrir la entrada a la mazmorra (que es secreta y se revela sólo empujando una antorcha que hay en la escalera).
- Encontrar un cuchillo registrando el esqueleto que hay en la mazmorra.
- Examinar las camas del `Dormitorio`, para descubrir unas fundas atadas con correas.
- Cortar las correas con el cuchillo y coger la funda.
- Examinar la ventana de la mazmorra para descubrir un barrote suelto, el cual debe quitar.
- Atar la funda de la cama a otro barrote de la ventana.
- Salir por la ventana de la mazmorra.

Antes de lanzarnos a programar todo esto, debemos asentar claramente los principios de programación bajo Inform, que son bien distintos de los de PAWS, por esto iremos muy, muy despacio. No te impacientes, ¡todo llegará!

### El juego Inform más pequeño del mundo

Lo siguiente es el esquema básico que debe seguir todo juego Inform. Más adelante iremos rellenando el esquema. Abre un nuevo fichero en JIF (File -> New, o pulsando sobre ) y copia esto:

    Constant Story "La Torre";
    Constant Headline "^(c) 2000 Zak y Carlos^";
    Include "Parser";
    ! Aqui iría la definición de mensajes de librería.

    Include "Verblib";
    ! Aqui irian las definiciones de las localidades
    ! y los objetos del juego

    [ Initialise ;
    ];

    Include "SpanishG";
    ! Aqui irían los verbos y acciones específicas de nuestro juego.

Copialo todo tal cual, especialmente pon cuidado en los punto y coma. Aunque parezca increible, eso ya es un programa completo en Inform, puedes compilarlo y tratar de jugarlo (Build -> Build All, o pulsando sobre ; y para jugarlo Build->Run). Naturalmente no podrás hacer gran cosa, ya que no hay localidades ni objetos. Aún así, puedes intentar una gran variedad de acciones (intenta saltar, cantar, ir al norte o al sur, e incluso SAVE y LOAD). Verás que el juego tiene respuestas para todo ¿de dónde las saca? ¡No hemos programado ninguna de esas respuestas!

He aquí uno de los principios básicos de Inform que lo diferencia claramente de PAWS. En PAWS, el programador tenía que programar las respuestas a cada posible verbo bajo cada posible circunstancia. Los casos que no eran contemplados por el programador, no existían en el juego. En Inform, en cambio, el programador sólo necesita especificar las respuestas a algunos verbos y en algunos casos. Todos los casos que el programador no contemple, serán manejados de forma automática por la librería. Es la librería la que tiene todas esas respuestas preparadas para las acciones más corrientes que el jugador intentará.

Pasemos a explicar línea a línea el programa que has copiado. Puedes saltarte esto e ir directamente a la programación del mapa si ya estás familiarizado con la sintaxis de Inform.

    Constant Story "La Torre";

Con esto definimos una constante llamada Story. Esta constante debe definirse en todo juego Inform y contiene el título del juego. El valor de esta constante tiene que ser un texto entre comillas. En nuestro caso el texto es `"La Torre"` Observa que al final del todo debe ponerse un punto y coma. En Inform, todas las "declaraciones" van terminadas por punto y coma.

    Constant Headline "^(c) 2000 Zak y Carlos^";

Este es análogo al anterior, sólo que ahora la constante que definimos se llama `Headline` y su valor es `"^(c) 2000 Zak y Carlos^"`. La constante `Headline` debe existir también en todo juego Inform y es el "subtítulo" del juego. El signo `^` representa un salto de línea, es decir, causa que antes de imprimir el texto el cursor pase a la línea siguiente (y otro salto tras escribir el texto, puesto que hay otro `^` al final).

    Include "Parser";

`Include` es lo que se llama una "directiva", esto es, una orden que le das a Inform para que haga algo. En este caso lo que le estás ordenando es que coja el fichero llamado `Parser.h` (la `h` se la pone automáticamente) y lo inserte en este punto. El resultado es el mismo que si hubieras copiado a mano tú mismo todo el contenido de `Parser.h` en este punto del fichero, sólo que usando `Include` el código fuente del juego queda mucho más limpio y legible (¡el fichero `Parser.h` son miles de líneas!)

El fichero `Parser.h` contiene el parser de Inform. Es una parte de la librería que se ocupa de leer lo que el jugador escribe, tratar de comprenderlo y generar acciones dentro del juego. Enseguida veremos qué es eso de las acciones.

    ! Aqui iría la definición de mensajes de librería.

Esta línea es lo que se llama un "comentario". Si Inform encuentra un signo de exclamación (!) que no esté formando parte de un texto entrecomillado, automáticamente ignorará todo lo que sigue en esa misma línea. Esto lo usaremos para poner anotaciones en el código. Estas anotaciones nunca formarán parte del juego final, una vez compilado, puesto que Inform las ignora.

En este caso la anotación es un recordatorio de dónde tendríamos que poner nuestras definiciones de mensajes de librería, si quisieramos ponerlas. En este juego no las pondremos de momento. Las definiciones de mensajes de librería son un poco como la tabla de mensajes de sistema de PAWS. Es donde se definen textos como "No puedes ir por ahi", "Cogido", "Cantas fatal", etc... Es decir, las respuestas por defecto de la librería ante cada posible acción. Si no definimos nosotros unas, la librería proporcionará otras ya preparadas. Puedes cambiar algunas de ellas si no te gustan sin necesidad de redefinirlas todas (y sin tener que modificar la librería). Luego veremos cómo.

    Include "Verblib";

De nuevo mediante `Include`, cargamos en nuestro juego el fichero `Verblib.h`, que contiene el código mediante el cual la librería sabe qué es lo que debe hacer ante cada posible acción. (Enseguida veremos qué son las acciones, son un concepto clave de Inform)

    ! Aqui irian las definiciones de las localidades
    ! y los objetos del juego

Ahora se trata de unos comentarios recordándonos dónde irán los objetos y las localidades. Por el momento no hay ni objetos ni localidades.

    [ Initialise ;
    ];

Esto es una rutina "libre". En Inform hay dos tipos de rutinas, las rutinas "libres" y las rutinas "incrustadas en objetos". Las libres son las que aparecen, como esta, en medio del código, las incrustadas en objetos aparecen siempre dentro de un objeto, luego daremos más detalles.

Una rutina no es más que un conjunto de instrucciones a las que hemos decidido agrupar y dar un nombre. En cierta manera se parece al concepto de "proceso" del PAWS, solo que en PAWS los procesos se identificaban mediante números (proceso 6, proceso 7,...) y en inform se identifican mediante nombres (rutina Initialise, rutina LugarNuevo, ...)

Todas las rutinas libres tienen la misma estructura:

    [ Nombre_de_la_rutina v1 v2 v3;
      instruccion1;
      instruccion2;
      ...
    ];

Es decir:

- El signo `[` indica que comienza la definición de una rutina "libre".
- A continuación va el nombre de la rutina, que es cualquier combinación de letras, números y el signo `_` (no se pueden poner acentos ni eñes)
- Seguidamente, separados por espacios, los nombres de las "variables locales" de la rutina. El concepto de "variable" es nuevo si vienes del PAWS, pero te será familiar si usas otros lenguajes de programación. En Inform simplemente se declaran los nombres de las variables, pero no sus tipos, ya que no hay tipos en Inform. En el ejemplo, habría tres variables locales, llamadas `v1`, `v2` y `v3`. Más adelante veremos más cosas sobre variables.
- La lista de variables locales se termina mediante un punto y coma (`;`)
- A continuación viene la lista de instrucciones que componen la rutina. Cada instrucción se separa de la siguiente mediante un punto y coma (`;`) Puedes poner varias instrucciones en la misma línea (separadas por punto y coma), o en líneas diferentes, el verdadero delimitador de instrucciones es el punto y coma, y no el salto de línea, que para Inform es lo mismo que un espacio.
- La definición de la rutina finaliza con el signo `]`
- Al final de la definición, un punto y coma (`;`)

Miremos otra vez el código que has escrito

    [ Initialise ;
    ];

En nuestro caso, la rutina se llama `Initialise`, su lista de variables locales está vacía (pues no hay nada entre el nombre de la rutina y el primer punto y coma), y también está vacío su "cuerpo", es decir, la lista de instrucciones que la componen (puesto que no hay nada entre el primer punto y coma y el signo `]` que da por terminada la rutina).

En esencia: la rutina `Initialise` que hemos escrito es una rutina totalmente vacía que no hace nada de nada. ¿Por qué la ponemos entonces? La razón es que esta rutina tiene que existir en todo programa Inform, o de lo contrario Inform se negará a crear tu juego. Prueba a quitarla y lo verás.

| Para probar a quitar trozos de código mientras estás de pruebas, basta poner un signo de admiración delante de cada línea que quieras quitar. Esto convierte el código en "comentarios", por lo que se hace invisible a ojos de Inform. Si más tarde quieres restituir el código, basta borrar el signo de admiración. Para realizar esto in JIF, simplemente selecciona una sección de texto y pulsa sobre el botón . Para descomentar una sección, seleccionala y pulsa sobre

Normalmente esta rutina se ocuparía de especificar cuál es la localidad en que comienza el juego, y de imprimir algún mensaje de bienvenida, pero en este primer esbozo la hemos dejado vacía. Aún así funciona, no es ilegal escribir una rutina que no haga nada, aunque resulta poco útil.

### Programando el mapeado

Vamos a escribir el código de cada localidad. En Inform, cada localidad es un objeto. Esto puede sonarte un poco raro si pensabas que los objetos eran cosas como "una piedra", "una espada", etc. Pero es que el concepto de Objeto de Inform es mucho más amplio.

| En PAWS se llamaba "objetos" a las cosas que el jugador podía coger y llevarse. En Inform el concepto es muchísimo más amplio: Para Inform, un objeto es en realidad un elemento del juego. Por tanto, los lugares son objetos, los PNJ son objetos, el propio jugador es un objeto, un "tema de conversación" puede ser un objeto. Prácticamente cualquier elemento de los que componen el juego son objetos (excepto las acciones o el vocabulario). Por eso se dice que Inform es orientado a objetos.

Aunque todos los objetos tienen siempre una misma estructura, no vamos a entrar aún a describir la estructura general de los objetos, y nos centraremos de momento en la estructura de los objetos que representan lugares. Esta es su estructura:

    Object nombre_interno "nombre corto"
    with   description "Descripción larga de la localidad",
           n_to ... ,
           s_to ... ,
           e_to ... ,
           w_to ... ,
           u_to ... ,
           d_to ... ,
           in_to ... ,
           out_to ... ,
    has light;

Es decir:

- La palabra `Object`, que le dice a Inform que aqui va una definición de un objeto. La definición terminará en un punto y coma (que ocurre al final del todo, tras la palabra `light`)
- Un "nombre interno", que es el que usaremos como programadores para referirnos a cada localidad. Son lo que en PAWS eran el número de localidad. Si te gusta pensar con números, puedes asignar a tus localidades nombres internos como `loc1`, `loc2`, `loc3`, etc... Pero te aconsejo que vayas olvidando la "forma PAWS de pensar" y uses nombres lógicos para referirte a tus localidades, nombres como `PuertaPrincipal`, `Dormitorios`, `EscaleraCaracol`, etc. Estos nombres nunca los verá el jugador. No pueden llevar acentos ni eñes ni espacios. Sólo letras, números y el signo `_`.
- Un "nombre corto", que es por asi decir el "título" de cada localidad. Esto sí que lo verá el jugador, será de hecho lo primero que se imprima cuando entre en la localidad, y lo que aparecerá en la barra de estado del juego. Puede ser algo como "Puerta Principal", "Dormitorios", "Escalera de Caracol", etc. Debe ir encerrado entre comillas dobles.
- La palabra especial `with` que indica a Inform que a continuación viene una lista de "propiedades" de esa localidad. Cada propiedad se separa de la siguiente mediante una coma.
- La primera propiedad que ponemos es `description`. Las propiedades son parejas, el primer elemento de la pareja es el nombre de la propiedad (`description`) y el segundo elemento es el valor de esa propiedad (o sea, la descripción en concreto de ese lugar). Entre ambos elementos de la pareja hay un espacio.

  La descripción es normalmente un texto, por lo que debemos encerrarlo entre comillas dobles. El texto puede ser muy largo por lo que ocuparía varias líneas de tu programa, no obstante los lugares por donde cortes las líneas no influyen en lo que el jugador verá. Su intérprete cortará las líneas siempre por el lugar adecuado según el ancho de su pantalla. Si quieres forzar un salto de línea, debes usar el signo `^` (como en la constante `Headline`).

  Recuerda que una vez terminado el texto y cerradas las comillas, debes poner una coma para separar esta propiedad de las siguientes.

- La siguiente propiedad se llama `n_to` y su valor indica a dónde se llega desde este lugar si se sale hacia el norte. Los puntos suspensivos que hay después están representando el nombre interno de otra localidad. Y detrás una coma.
- De forma análoga, las propiedades `s_to`, `e_to`, etc indican a dónde llevan las restantes salidas de la localidad. No es necesario listar todos los puntos cardinales, sino sólo los que realmente llevan a algún sitio. Los que no se listan, se entiende que son direcciones sin salida. (También existen las direcciones `nw_to`, `sw_to`, `ne_to` y `se_to` no usadas en el ejemplo)
- Una vez finalizada la lista de propiedades, se inicia la lista de atributos, la cual comienza por la palabra especial `has` (que en inglés significa "tiene").
- Los atributos son como ciertos flags de PAWS, se trata de indicadores para señalar cosas como si el objeto es comestible, si es una prenda, si da luz, etc... En el caso de las habitaciones, el atributo más usual es el llamado `light`, que como puedes suponer indica que el lugar está iluminado. ¡Si olvidaras poner ese atributo el jugador no podría ver la descrcipción de la localidad a menos que llevara consigo algún objeto con `light`!

| Para los autores que usan informATE!, puede parecerles dificultoso tener que lidiar ahora con los nombres de propiedades, atributos, etc en ingles. Para aliviar un poco el asunto, INFSP provee la extensión `Alias.h`, la cual da soporte para que se puedan seguir usando los atributos y propiedades en español (como en informATE!).

Una vez comprendida la estructura de las localidades, codificar el mapa es pan comido. Copia el siguiente código en la zona donde estaba el comentario `"Aquí irían las definiciones de las localidades y los objetos del juego"`. Observa que, de momento, ponemos conexión "normal" en lugar de la puerta secreta.

    Object  PuertaPrincipal "Puerta Principal"
     with   description "Estás junto a la puerta principal.
                A su lado puedes ver una mesa de guardia y en la pared
                norte hay una chimenea.",
            e_to Dormitorio,
     has    light;

    Object  Dormitorio "Dormitorio"
     with   description "Varios maltrechos catres se amontonan en esta
                habitación.",
            w_to PuertaPrincipal,
            e_to EscaleraCaracol1,
     has    light;

    Object  EscaleraCaracol1 "Escalera de caracol"
     with   description "El viento ulula a través de la empinada
                escalera de caracol, una vieja armadura parece vigilar
                la escalera.",
            u_to EscaleraCaracol2,
            w_to Dormitorio,
     has    light;

    Object  Mazmorra "Mazmorra"
     with   description "Una silenciosa estancia débilmente alumbrada
                por los rayos de luna que se filtran a través de un
                pequeño ventanuco. El suelo está lleno de paja, colgando
                de unos grilletes en la pared observas un esqueleto
                humano.",

            e_to EscaleraCaracol2,
     has    light;

    Object  EscaleraCaracol2 "Escalera de caracol"
     with   description "Los desgastados peldaños de piedra resbalan en
                ocasiones. A mitad de la escalera una antorcha en la
                pared impide que la oscuridad sea completa.",
            d_to EscaleraCaracol1,
            w_to Mazmorra,
            u_to AltoTorre,
     has    light;

    Object AltoTorre "Alto de la torre"
     with   description "Una gran cama preside la estancia, los gruesos
                barrotes no permiten la salida por la ventana, aunque de
                todos modos estaría demasiado alta.",
            d_to EscaleraCaracol2,
     has    light;

Unas notas sobre el código anterior:

- No puede haber en el juego dos objetos con el mismo nombre interno. Por eso he llamado a una parte de la escalera `EscaleraCaracol1` y a la otra `EscaleraCaracol2`.
- Sin embargo nada impide que tengan el mismo "nombre corto", simplemente el jugador verá el mismo "título" en ambas localidades.

Ahora será necesario también modificar la rutina `Initialise` para indicar en cuál de esas localidades comienza el juego.

En Inform, existe una variable global llamada `location` que contiene siempre la localidad en la que se halla el jugador. El concepto de variable global es muy similar al concepto de "Bandera" de PAWS, si bien en PAWS las banderas se identificaban mediante un número (así la bandera que indicaba dónde está el jugador, era la bandera número 254), mientras que en Inform se identifican mediante un nombre (`location` es el nombre de esta "bandera"). Otras importantes diferencias son que en PAWS el número de banderas estaba limitado a 255, y no era necesario "declararlas" de antemano, mientras que en Inform no hay límite al número de variables globales, pero es necesario declararlas de antemano (es decir, "anunciar" a Inform de que vamos a crear una nueva variable global, indicándole el nombre que vamos a darle). La variable `location` es declarada en `Parser.h`, el fichero que hemos incluido al principio. Otra diferencia importante es que en PAWS una bandera sólo podía servir para almacenar un número entre 0 y 255, mientras que en Inform puede usarse para almacenar un número entre -32768 y +32767, o también una palabra, una frase, un objeto, un lugar.. ¡cualquier cosa!

Para hacer que el lugar de comienzo sea la puerta principal, basta cargar en la variable `location` el objeto `PuertaPrincipal`. La carga de una variable es algo análogo al condacto `LET` del PAWS, pero en Inform se usa la siguiente sintaxis:

      variable = valor;

Así, por ejemplo:

      v2 = 32;

Guardaría el número 32 dentro de la variable `v2`, de forma análoga a lo que hacía el condacto `LET`, mientras que:

      v1=v2;

Copiaría el valor de la variable `v2` en la variable `v1`, de forma análoga a lo que hacía el condacto `COPYFF`

De modo que ahora debes modificar la rutina `Initialise` para que ponga:

    [ Initialise ;
       location = PuertaPrincipal;
    ];

Observa que ahora `Initialise` ya no está vacía. Tiene una sola instrucción que sirve para asignar un valor a la variable `location`. Recuerda que la instrucción debe terminar con punto y coma.

Otra interesante variable de Inform es una llamada `lookmode`, que controla si la descripción de la localidad debe repetirse o no cada vez que el jugador vuelve a entrar en una localidad en la que ya había estado. El valor por defecto de esta variable implica que la descripción sólo se le muestre una vez, y si desea volver a verla debe escribir el verbo MIRAR. Si prefieres que la descripción se muestre siempre, debes hacer que esta variable tenga el valor 2 cuando el juego comience, es decir, modifica `Initialise` para que sea:

    [ Initialise ;
       location = PuertaPrincipal;
       lookmode=2;
    ];

Es importante que te acostumbres desde el primer momento a "comentar" tu código, para que otros puedan comprenderlo y para que tú mismo lo entiendas cuando lo mires unas semanas más tarde. Añadir comentarios al juego no lo hace crecer de tamaño ¡recuerda que Inform ignora tus comentarios! Así que una rutina `Initialise` más "profesional" sería así:

    [ Initialise ;
        ! Lugar de comienzo: la puerta principal
        location=PuertaPrincipal;

        ! Activamos esta variable para que la descripción de los lugares
        ! se repita siempre, incluso si el jugador ya ha estado allí
        lookmode=2;
    ];

Es habitual también incluir en la rutina `Initialise` algún mensaje de bienvenida al juego, o una introducción para situar al jugador. El comando para mostrar texto en Inform es `print`, seguido del texto en cuestión encerrado entre comillas dobles. Por ejemplo:

      print "¡¡Bienvenido a mi primer juego!!^^";

Como ya sabes, el signo `^` representa un salto de línea. Poniendo dos seguidos dejamos una línea en blanco debajo del texto anterior. Observa que en Inform no hay tablas de mensajes de usuario. No necesitas guardar tus textos en una tabla para después acceder a ellos mediante un número, sino que el texto lo pones directamente a continuación del print. No olvides encerrarlo entre comillas.

Los juegos conversacionales escriben mucho texto. En juegos complicados esto significa que habrá que usar muchas veces la orden `print`, por ello Inform permite una abreviatura especialmente útil, pero un poco peligrosa para los principiantes. Consiste en no poner `print`, sino simplemente el texto entre comillas. Cuando Inform encuentra un texto entrecomillado en un lugar donde esperaba una instrucción (o sea, dentro de una rutina), lo que hará será imprimir ese texto como si hubieras puesto `print` delante, añadir un salto de línea al final (como si hubieras puesto un `^` justo antes de cerrar las comillas), y terminar la ejecución de la rutina (algo equivalente al DONE del PAWS).

| Esto es muy importante, merece la pena repetirlo: una cadena entrecomillada en lugar de una instrucción equivale a un `print` de la cadena, seguido de un salto de línea y seguido del retorno inmediato de la rutina en que aparece.

Por tanto, si queremos escribir un mensaje de bienvenida desde nuestra rutina `Initialise` , tenemos varias posibilidades. En primer lugar, usando `print` (forma recomendada a los principiantes):

    [ Initialise;
        ! Lugar de comienzo: la puerta principal
        location=PuertaPrincipal;

        ! Activamos esta variable para que la descripción de los lugares
        ! se repita siempre, incluso si el jugador ya ha estado allí
        lookmode=2;

        ! Mensaje de bienvenida
        print "¡¡Bienvenido a mi primer juego!!^^";
    ];

La orden `print` puede aparecer en cualquier lugar dentro de `Initialise` , a fin de cuentas da lo mismo imprimir la bienvenida antes o después de haber inicializado las variables. La segunda forma, para programadores más expertos, es usar la abreviatura en la que no se pone `print`. Quedaría así:

    [ Initialise;
        ! Lugar de comienzo: la puerta principal
        location=PuertaPrincipal;

        ! Activamos esta variable para que la descripción de los lugares
        ! se repita siempre, incluso si el jugador ya ha estado allí
        lookmode=2;

        ! Mensaje de bienvenida
        "¡¡Bienvenido a mi primer juego!!^";
    ];

En este caso, observa con atención los detalles siguientes:

- La cadena tiene ahora solo un `^` en su interior, en vez de dos, ya que cuando se omite `print`, siempre se añade un salto de línea automáticamente al final del texto.
- La instrucción de imprimir debe ser la última de la rutina, puesto que justo después de haber impreso eso, la rutina se abandona, sin ejecutar lo que hubiera debajo. Si hubiésemos colocado el texto de bienvenida al principio de la rutina, las instrucciones que inicializan `location` y `lookmode` no llegarían a ser ejecutadas nunca (Inform te avisa de esto al compilar).

Puedes ver el código fuente con todo esto ya tecleado aqui. Copialo, pegalo en JIF y compila pulsando sobre . Para que puedas jugarla y comprobar cómo puedes deambular por el mapa, haz Build-> Run o pulsa sobre .

Prueba a cambiar la descripción de una localidad, no tengas miedo de experimentar, es la única forma de aprender. ¿Cómo modificarías el programa para que bajando desde la `PuertaPrincipal` se llegue a un `Sotano`? ¡Hazlo! ¿Cómo eliminarías la conexión que hay entre la `EscaleraCaracol1` y la `Mazmorra`? ¡Hazlo!

|  |  | Por dónde empezar.