Muchos de los textos que una aventura de AGE muestra al jugador son textos que el autor del juego no necesita escribir explícitamente, porque ya están programados en el AGE. Éstos son lo que llamamos mensajes por defecto. Por ejemplo, en la siguiente interacción:
> coger el asdfasdf
¿Qué pretendes coger?
> inventario
No tienes nada.
> coger la piedra
Coges la piedra.
Los tres mensajes que muestra como salida el AGE son mensajes por defecto. En el caso de los dos primeros, todo el texto que se muestra (“¿Qué pretendes coger?” y “No tienes nada.”) es texto puesto por el sistema sin necesidad de que el jugador lo especifique en ninguna parte. En el tercer caso, el texto “Coges” proviene asimismo del sistema, mientras que el sintagma “la piedra” se genera dinámicamente porque le hemos dado a esa entidad el nombre para mostrar “piedra” y el género femenino que implica el artículo “la”.
En ciertos mundos puede resultar conveniente cambiar los mensajes por defecto, si es que los que vienen de base con el AGE no nos gustan por algún motivo. Por ejemplo, en un juego de ambientación medieval podríamos querer que el sistema se dirigiera al jugador con un tratamiento más arcaico: “¿Qué pretende coger vuesa merced?” o “Cogéis la piedra.” Por supuesto, el AGE proporciona la posibilidad de hacer esto, para lo cual existen varias maneras.
En primer lugar, observemos el fichero “lang/messages.lan” que está dentro de “AgeCore.jar” (este fichero .jar se puede abrir como si fuera un .zip para ver dicho fichero .lan). En él, podemos ver entradas como:
#Cuando intentas coger algo que no está en la habitación
get.what=¿Qué pretendes coger?\n
#Mostrar inventario (vacío)
you.have.nothing=No tienes nada.\n
#Cuando coges el objeto $item
you.get.item=Coges $item.\n
Estas entradas describen mensajes por defecto de AGE, en concreto, los vistos en el ejemplo anterior. La línea que empieza con # en cada entrada es simplemente un comentario que explica de qué trata el mensaje. El texto anterior al signo “=” en cada línea sin comentario es el nombre que identifica ese mensaje por defecto. Lo que hay a la derecha del signo “=” es el mensaje en sí, donde los identificadores que tienen el símbolo del dólar se van a sustituir por nombres de entidades (normalmente debería ser obvio por el contexto cuáles: por ejemplo, en el último de los mensajes de ejemplo, el identificador $item se sustituye por el nombre de la cosa que el jugador esté cogiendo, con su artículo correspondiente).
Si cambiásemos los mensajes de este fichero, estaríamos modificando los mensajes por defecto de AGE. Pero no es esto lo que queremos hacer, sino modificarlos para un mundo en particular. Sin embargo, abrir el fichero “messages.lan” es útil para esta tarea porque para cambiar mensajes para un mundo concreto necesitaremos saber el nombre de los mensajes que queremos redefinir (lo que viene antes del signo =, como you.get.item) así como los parámetros que soportan (en este caso, $item). Sabido esto, existen dos maneras de cambiar los mensajes:
Para cambiar un mensaje individual, por ejemplo, si quisiéramos que el parser nos tratara de “vos” al coger una cosa, hacemos lo siguiente:
world.getMessages().setMessage( "you.get.item" , "Cogéis $item" );
El método getMessages()
de la clase World nos proporciona un objeto de la clase Messages que encapsula los mensajes por defecto, y el método setMessage
nos permite cambiar cada uno de ellos.
Este cambio de mensaje será permanente, es decir, a partir de la llamada a este método se imprimirá “Cogéis …” cada vez que un jugador coja una cosa. Sin embargo, en ocasiones también querremos que se imprima un mensaje por defecto en particular sólo en una ocasión. Para ello, también existe la posibilidad de cambiar el mensaje sólo para la próxima vez que se imprima. Así, si por ejemplo quisiéramos que al coger un cubito de hielo se nos mostrara un mensaje diciendo que está frío, podríamos poner en el código para la orden “coger” sobre el cubito se hiciese algo como:
world.getMessages().setNextMessage( "you.get.item" , "Coges $item. ¡Buf, qué frío está!" );
De esta manera conseguiríamos que se mostrase un mensaje distinto sólo al coger el cubito; pero no con el resto de las cosas del mundo.
Si queremos personalizar una aventura completa, es posible que queramos cambiar gran parte de los mensajes por defecto, o incluso todos. En ese caso, es más sencillo utilizar este método:
world.loadMessages(world.getResource("nombrefichero.lan"));
Si no se van a cambiar los mensajes a lo largo de toda la aventura, como sería lo más común, lo normal sería ejecutar uno de estos códigos en el método intro (ya que se ejecuta al principio). Si se quieren tener diferentes mensajes o juegos de mensajes en distintas partes de la historia, estos métodos se pueden ejecutar en cualquier punto de la misma para cambiarlos a partir de ese momento (se pueden tener varios ficheros de mensajes, o se pueden cambiar los mensajes uno por uno varias veces sin problema).
Si en una aventura interesa que los mensajes por defecto sean muy dinámicos y cambiantes (por ejemplo, que cada vez que cojamos un objeto se elija un mensaje diferente de un conjunto de alternativas de forma aleatoria, o alguna otra cosa que requiera procesado); es posible controlar mediante código BeanShell el mostrado del mensaje, pasando por encima tanto de los mensajes por defecto definidos por AGE como de los establecidos para el mundo según lo visto en la sección anterior. Para ello, en el objeto mundo, redefinimos el método
String getMessage ( String messageName , Object[] arguments )
donde como parámetro se nos pasa el nombre del mensaje que AGE quiere mostrar (por ejemplo, “you.get.item”) y un array con todas las entidades u otros objetos relevantes al mensaje (en este caso, el array tendría longitud 1 y sólo contendría la cosa que se está cogiendo y que se utilizaría por defecto para sustituir $item).
El método debe devolver el mensaje que queremos que se muestre en ese caso, o bien null si no queremos alterar el comportamiento para ese mensaje y objetos sino delegar en el mecanismo por defecto de mensajes del mundo o de AGE.