¿Cómo hago para... incluir eventos ambientales aleatorios con Inform 6?

Tag: Articulos tecnicos

Este artículo surge como respuesta al primero de los artículos de 'cómo hago para...' sobre los que se ha estado hablando en este hilo del foro.

¿Qué entendemos por efectos ambientales aleatorios?

Los efectos ambientales aleatorios son un mecanismo mediante el cual se intenta enriquecer la ambientación en algunas escenas de una ficción interactiva para dar la sensación al jugador de que se encuentra dentro de un mundo que está vivo. Estos efectos ambientales son simplemente eso, ambientación, ya que no son relevantes para la trama principal.

Por ejemplo, si la trama sucede en un bosque, la ambientación podría enriquecerse haciendo que alguna ardilla huya a un árbol asustada por la presencia del PJ, que ráfagas de viento sacudan las ramas de los árboles o que el canto de los grillos perturben el silencio de la noche.

Nociones básicas

Cuando hablamos de aleatoriedad en Inform 6 debemos tener en mente siempre la función random. Esta función se puede usar de dos formas:

- random(N): que devuelve un número entero entre 1 y N. En teoría, todos los números del rango se generan con la misma probabilidad.

- random(constante1, constante2, …, constanteN): Devuelve aleatoriamente una de las constantes pasadas en la lista de argumentos.

La segunda cosa que se debe tener clara es dónde debemos generar los eventos aleatorios. En una aventura creada con Inform 6 tenemos, dentro del código, dos puntos candidatos para introducir la generación de eventos aleatorios: en la descripción de las localidades o en la propiedad each_turn también de las localidades. Los efectos ambientales aleatorios se pueden poner en cualquier parte del código que queramos, dependiendo, evidentemente, de las necesidades de la obra, pero los dos anteriores serían los más adecuados para la mayoría de las aventuras.

Utilizaremos los efectos ambientales aleatorios en la descripción de una localidad si queremos que los eventos sucedan cuando el PJ entre en dicha localidad o cuando el jugador introduzca la orden MIRAR.

Object bosque "Bosque"
 with
    name 'bosque',
    description [;
     print "Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido.
     Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote
     ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte
     a partir de ahora.";

     print (string) random("^Una ardilla huye disparada hacia la copa de un roble y desapareciendo de tu vista.",
                           "^Una ráfaga de viento hace moverse las ramas de los árboles.",
                           "^Se oye el murmullo de pequeños animales entre la maleza, posiblemente ratas o conejos.",
                           "^En la distancia, oyes como un grupo de pájaros alzan el vuelo.");
   ],
has light;

Como se puede comprobar en la ejecución del código anterior, veremos que se genera uno de los eventos aleatorios cada vez que se describe la localidad, generando al jugador la impresión de que el mundo del juego no es estático.

EFECTOS AMBIENTALES ALEATORIOS
(c)2012 Joruiru.
Release 1 / Serial number 120601 / Inform v6.31 Library 6/11 D

Bosque
Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido. Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte a partir de ahora.

Una ráfaga de viento hace moverse las ramas de los árboles.

>> mirar

Bosque
Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido. Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte a partir de ahora.

En la distancia, oyes como un grupo de pájaros alzan el vuelo.

>> mirar

Bosque
Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido. Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte a partir de ahora.

Una ardilla huye disparada hacia la copa de un roble y desapareciendo de tu vista.

>> esperar
Pasa el tiempo...

>> esperar
Pasa el tiempo...

>> esperar
Pasa el tiempo...

En la transcripción anterior se puede ver el problema que se presenta al incluir el evento aleatorio en la descripción de la localidad: mientras el jugador no ejecuta la orden MIRAR el evento aleatorio no se lanza. Este problema nos complica dar al jugador la sensación de estar ante un mundo en el que “ocurren” cosas, aparte de las que él mismo provoca.

Para que los efectos aleatorios se lancen en cada turno, deberemos utilizar la propiedad each_turn de las localidades. Esta propiedad se llama automáticamente al final de cada turno de juego.

Object bosque "Bosque"
 with
    name 'bosque',
    description "Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido.
     Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote
     ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte
     a partir de ahora.",

    each_turn [;
     print (string) random("Una ardilla huye disparada hacia la copa de un roble y desapareciendo de tu vista.",
                           "Una ráfaga de viento hace moverse las ramas de los árboles.",
                           "Se oye el murmullo de pequeños animales entre la maleza, posiblemente ratas o conejos.",
                           "En la distancia, oyes como un grupo de pájaros alzan el vuelo.");
    ],
has light;

Y la transcripción que lograríamos al ejecutar el código anterior sería:

EFECTOS AMBIENTALES ALEATORIOS
(c)2012 Joruiru.
Release 1 / Serial number 120601 / Inform v6.31 Library 6/11 D

Bosque
Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido. Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte a partir de ahora.

>> mirar

Bosque
Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido. Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte a partir de ahora.

Una ráfaga de viento hace moverse las ramas de los árboles.

>> mirar

Bosque
Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido. Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte a partir de ahora.

En la distancia, oyes como un grupo de pájaros alzan el vuelo.

>> espera
Pasa el tiempo...

Se oye el murmullo de pequeños animales entre la maleza, posiblemente ratas o conejos.

>> espera
Pasa el tiempo...

Una ráfaga de viento hace moverse las ramas de los árboles.

>> espera
Pasa el tiempo...

Una ardilla huye disparada hacia la copa de un roble y desapareciendo de tu vista.

>> espera
Pasa el tiempo...

En la distancia, oyes como un grupo de pájaros alzan el vuelo.

>> salta
Saltas en el sitio, sin ningún resultado.

Una ráfaga de viento hace moverse las ramas de los árboles.

>> oler
No hueles nada extraño.

En la distancia, oyes como un grupo de pájaros alzan el vuelo.

Ahora sí que hemos conseguido el efecto de que ocurran cosas en el mundo, que no dependan de las acciones que realice el jugador. Por tanto, estamos ante un mundo con vida más allá de la del PJ.

En el ejemplo anterior, llama la atención que en la descripción inicial de la localidad no se genera el efecto ambiental aleatorio. Esto se debe a que la propiedad each_turn se ejecuta al final de cada turno, y éstos sólo avanzan cada vez que el jugador realiza alguna acción. Hay varias soluciones, con mayor o menor complejidad, para este caso particular, pero escapan del objetivo de este tutorial.

Conceptos avanzados

Con la aproximación del punto anterior, tenemos dos claros problemas:

- Deberemos repetir el código de generación de los eventos aleatorios en la propiedad each_turn de cada una de las localidades en la que queramos que sucedan.

- Los eventos ocurren en cada turno, con lo que se da la sensación de que siempre están ocurriendo cosas. Esto no es aconsejable, ya que se puede llegar a abrumar al jugador. Además, aunque pongamos mucha variedad de mensajes aleatorios, si se imprime uno por turno, al final acabarán siendo muy repetitivos, con lo que tenemos muchos números para cansar al jugador antes de hora.

El primer problema lo podemos solucionar fácilmente trasladando el código a una función global dentro del código, con lo que en cada localidad sólo deberíamos realizar una llamada a dicha función.

Para solucionar el segundo problema podemos hacer algo parecido a lo siguiente:  

    each_turn [;
     print (string) random("","","","",
                           "Una ardilla huye disparada hacia la copa de un roble y desapareciendo de tu vista.",
                           "Una ráfaga de viento hace moverse las ramas de los árboles.",
                           "Se oye el murmullo de pequeños animales entre la maleza, posiblemente ratas o conejos.",
                           "En la distancia, oyes como un grupo de pájaros alzan el vuelo.");
    ],

Añadiendo cadenas vacías en la lista de eventos, hemos conseguido que sólo el 50% de las veces se imprima un evento aleatorio. La realidad es que el 100% de las veces se imprime un evento, pero en la mitad de los turnos se imprimirá la cadena vacía.

Obviamente ésta no es una solución demasiado elegante. Para proporcionar una probabilidad de ejecución a los eventos aleatorios, usaremos la función random de la forma random(N).

! Funcion: RandomEffects
! Función que muestra efectos ambientales aleatorios para dar la sensación
! de un mundo vivo. Estos efectos ambientales son simplemente eso, ambientación,
! sin ser relevantes para en el hilo argumental de la aventura.
! Parametros: prob - Probabilidad (0-100) de que ocurra un evento
!
[ RandomEffects prob;
 if (random(100) <= prob) {
     switch (random(4)) {
         1: print "^Una ardilla huye disparada hacia la copa de un roble y desapareciendo de tu vista.^";
         2: print "^Una ráfaga de viento hace moverse las ramas de los árboles.^";
         3: print "^Se oye el murmullo de pequeños animales entre la maleza, posiblemente ratas o conejos.^";
         4: print "^En la distancia, oyes como un grupo de pájaros alzan el vuelo.^";
     }
 };
];

Object bosque "Bosque"
 with
    name 'bosque',
    description "Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido.
     Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote
     ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte
     a partir de ahora.",

    each_turn [;
     RandomEffects(50);
    ],
has light;

Hemos creado una función llamada RandomEffects, que recibe como parámetro la probabilidad de que ocurra un evento aleatorio. Desde el evento each_turn de las localidades llamaremos a esta función, teniendo así la posibilidad de tener probabilidades distintas en cada localidad. En el ejemplo anterior, le hemos dado una probabilidad del 50%.

EFECTOS AMBIENTALES ALEATORIOS
(c)2012 Joruiru.
Release 1 / Serial number 120601 / Inform v6.31 Library 6/11 D

Bosque
Aquí, el camino que atraviesa el Bosque Negro prácticamente ha desaparecido. Los frondosos árboles, la maleza y el verde de la hierba lo ocupan todo, no dejándote ver mucho más allá de donde te encuentras. Deberás confiar en tu instinto para guiarte a partir de ahora.

>> espera
Pasa el tiempo...

>> espera
Pasa el tiempo...

>> espera
Pasa el tiempo...

Una ardilla huye disparada hacia la copa de un roble y desapareciendo de tu vista.

>> espera
Pasa el tiempo...

Una ráfaga de viento hace moverse las ramas de los árboles.

Comprobamos en la transcripción del ejemplo anterior que los eventos ambientales aleatorios no ocurren en cada turno, sólo cuando se cumple la probabilidad que se le pasa.

¿Cómo puedo... hacer más?

En el último ejemplo que hemos visto, hemos añadido una condición para que sólo se ejecuten los eventos aleatorios cuando se cumpla. En este caso, la condición es un simple porcentaje.

Podemos añadir todas las condiciones que queramos: que ciertos eventos sólo se ejecuten por la noche o cuando el jugador ha descubierto algo o sólo en ciertos lugares.

También podemos hacer que la “fuente” de los eventos aleatorios no sean las localidades, sino algunos objetos. En inform 6, los objetos también tienen la propiedad each_turn, que se llamará automáticamente al final de cada turno en el que el objeto se encuentre al alcance del jugador (normalmente cuando se encuentre en la misma localidad que el jugador). Por ejemplo, un tubo fluorescente que parpadee de vez en cuando, con lo que cuando el jugador abandona la habitación ya no verá si parpadea o no.

Trabajando un poco el código, también podríamos conseguir que el mismo texto no se repitiese dos veces consecutivas o, lo que es mejor, que no se repitiese hasta que no se hayan mostrado todas las posibilidades.

AdjuntoTamaño
randomevents.inf7.68 KB

(c)1998-2019 CAAD

Todos los contenidos de esta web son propiedad de CAAD. Las colaboraciones son propiedad de sus respectivos autores.