Patrones de comportamiento complejos con Planner

(Por Mastodon, 05/02/2011)

Introducción

Planner, y su complemento Basic Plans, son dos extensiones para Inform 7 escritas por Nate Cull que nos van a permitir, de una forma flexible, la implementación de agentes reactivos en nuestra obra de ficción interactiva. ¿Qué es un agente reactivo? La idea está inspirada en un concepto de inteligencia artificial que teóricamente permite desarrollar entidades autónomas capaces de reaccionar ante un entorno cambiante. En el ámbito que nos ocupa, se trata de una librería para programar dichas entidades -básicamente personajes-, que por una parte son capaces de actuar según un plan establecido, pero que pueden modificarlo según la información cambiante que vayan obteniendo de su entorno.

Veámoslo con un ejemplo práctico.

Comenzando

Nuestro "agente reactivo" va a ser Rafa, un retoño de 2 años con una simple idea en la cabeza: comerse un caramelo.

Para empezar, instalamos en el IDE las dos extensiones, si aún no lo hemos hecho, y empezamos a escribir, comenzando por un sencillo escenario con dos localidades y el personaje.

"Caramelos" by Anonymous

Include Spanish by Sebastian Arg.

Include Planner by Nate Cull.

Include Basic Plans by Nate Cull.

The Sala de estar is a room. The description is "Una sala de estar confortable, aunque algo desordenada por las inquietudes exploratorias de Rafa."

The Cocina is east of Sala de estar. The cocina is female. In the cocina is a caramelo. The description of the caramelo is "Glucosa solidificada, y el primer vicio de todo ser humano."

Rafa is a man in the Sala de estar. The description is "Una encantadora criatura, especialmente cuando duerme."

Ahora vamos a indicar que el caramelo es objeto de deseo de nuestro "agente". En esta primera aproximación basta con una simple línea en el libro de reglas Every turn.

Every turn:

have Rafa plan an action for being-carried-by with caramelo and Rafa.

Lo que hemos hecho es decirle al parser que cada turno desarrolle un plan para establecer una relación de tipo being-carried-by entre el caramelo y Rafa. Luego explicaré lo que significa una relación y la filosofía general de la extensión. También por qué es necesario meterlo en una regla Every turn. De momento, baste saber que es la única regla necesaria para darle un comportamiento, si no inteligente, al menos pseudo-racional, a nuestro personaje.

Y una regla más para terminar el juego cuando el chaval consiga su objetivo:

Every turn when Rafa has the caramelo:

if Rafa is in the location:

say "Rafa levanta el caramelo mirando al cielo en señal de triunfo, y procede a engullirlo en un trago memorable (para su edad).";

otherwise:

say "Oyes gruñidos de placer desde [the location of Rafa], y al cabo de un rato aparece Rafa enseñando desafiante su roja lengua para restregarte su triunfo.";

end the story saying "FIN".

Prueba a compilar el código anterior (te lo puedes descagar aquí), ejecuta y... ¡Voilá! Si seguimos al pequeño sin interferir en su acción lo veremos salir raudo hacia la cocina, coger el caramelo y engullirlo, todo ello él solito. Ahora prueba a coger el caramelo y dejarlo en la sala de estar. Rafa notará el cambio y se vendrá para el salón, si es que estaba en la cocina, procediendo de idéntica manera. En fin, de momento nada del otro mundo, aunque para una sóla línea de código no está nada mal.

En este punto habrás notado que cuando cogemos el caramelo, ni nos sigue, ni intenta pedírnoslo, y que de hecho se queda como congelado. Una vez soltamos el caramelo, el proceso vuelve a su proceder normal y esperado. Esto es porque hemos establecido un objetivo excesivamente simple. Fácil de solucionar cuando entremos en el uso real de la extensión, pero antes vamos a complicar un poco el escenario, sin tocar ni una sóla coma del objetivo de Rafa, para ilustrar la potencia de la Planner.

Vamos a añadir una puerta (suponemos que el niño es capaz de abrirla por simplificar) y además el caramelo ahora estará en un frasco cerrado encima de la encimera. Sustituimos el párrafo de la cocina:

The Cocina is east of Sala de estar. The cocina is female. In the cocina is a caramelo.

Por este otro con el nuevo escenario:

The puerta is a female door. It is east of Sala de estar and west of the Cocina. The puerta is openable and closed. The cocina is female. In the cocina is a encimera. It is a female supporter. On the encimera is a frasco de golosinas. It is a openable closed transparent container. In the frasco is a caramelo.

(Puedes descargártelo aquí)

Volvemos a compilar y ejecutar. Ahora las condiciones para obtener el preciado tesoro han cambiado. Seguimos el devenir de Rafa y comprobamos con satisfacción contenida de padres que la criatura abre la puerta, se dirige a la cocina, abre el frasco y consigue el caramelo. ¡Wow! Esto ya es más interesante. Como he explicado antes, podemos modificar la situación del mundo cogiendo el frasco, llevándolo al salón, cerrando la puerta, etc, y el parser sabrá re-elaborar siempre el plan adecuado para la consecución del objetivo por parte de nuestro retoño.

Este es un buen momento para complicar un poco el patrón de comportamiento del protagonista, pero antes necesitamos entender la lógica del planificador de objetivos.

La planificación de agentes reactivos

El modelo de planificación de agentes reactivos, también conocido como planificación dinámica, procede del ámbito de la inteligencia artificial. Su propósito es otorgar a entidades artificiales la capacidad de establecer planes de actuación para la consecución de objetivos, adaptándolos en tiempo real a los cambios que se produzcan en el contexto del entorno tal y como lo perciben.

Lo que vamos a hacer para cada agente (personaje, animal o una entidad más abstracta como pueda ser el clima...) es definir un conjunto de objetivos a cumplir. El objetivo puede ser tan sencillo como 'saltar' o más difuso, como sacar un 9 en el examen de geografía, en cuyo caso debemos indicar un plan de sub-objetivos para conseguirlo. Los elementos de este plan, a su vez pueden ser simples, o nuevos sub-sub-objetivos. El algoritmo, mediante una técnica de comprobación hacia atrás (backwards), calcula el mejor camino, en término de los objetivos definidos, para lograrlo. En el ejemplo anterior, la cadena de evaluación sería algo como lo siguiente ("<<<" significa implica que).

Coger el caramelo(el objetivo) <<< abrir el frasco <<< llegar al frasco <<< ir hacia el este <<< abrir la puerta.

Abrir la puerta es un objetivo de cumplimiento inmediato (y de hecho una acción), ya que Rafa comienza en el salón, por lo que es el primer paso a realizar. En el siguiente turno la cadena se habrá acortado a:

Coger el caramelo(el objetivo) <<< abrir el frasco <<< llegar al frasco <<< ir hacia el este.

Si por ejemplo, cogiéramos el frasco estando los dos en la cocina, y nos lo llevamos al salón, en la siguiente re-evaluación del plan, se generaría una cadena de planificación completamente distinta:

Coger el caramelo(el objetivo) <<< abrir el frasco <<< llegar al frasco <<< ir hacia el oeste.

La extensión hermana de Planner, Basic Plans, contiene un conjunto de relaciones predefinidas y listas para usuarse, como being-in -estar en una localidad concreta o en la localidad de un objeto-, being-open -abrir un objeto-, being-visible-by, being-touchable-by, being-carried-by, being-worn-by... Todas ellas son capaces de tener en cuenta y actuar en consecuencia frente a inconvenientes básicos como que el objeto destino esté en otra localidad, en un contenedor cerrado, o que haya puertas en el camino.

Si las relaciones predefinidas no son suficientes -algo esperable en cualquier creación seria, y lo que realmente hace interesante a la extensión- debemos afinar o implementar nuevas relaciones, así como proporcionar al planificador toda la información necesaria para que pueda integrarlas en su algoritmo de cálculo de objetivos, para lo cual debemos manejar tres conceptos:

    1. Una relación (planning-relation) es un vínculo entre dos objetos que se debe poder responder con una respuesta si/no: Being-in -¿está en la localidad?, Speak-in -¿Rigoberto habla francés?.

    2. Una comprobación de relación (planning-testing) que responda si la relación se cumple o no, tomando información del estado del mundo en un momento dado.

    3. Un plan de consecución del objetivo, si la comprobación de la relación es negativa. Este plan a su vez puede hacer uso de otras relaciones o bien disparar acciones (planning-action) si se dan las condiciones para llevar a cabo el siguiente paso.

Para entender todo este embrollo vamos a ver cómo está implementado uno de los objetivos predefinidos más sencillos: being-worn-by (llevar puesto algo).

El plan para que un personaje lleve algo puesto se reduce a 1) Tener la prenda 2) ponérsela. A su vez para tener la prenda es necesario haberse desplazado a su localidad, que sea "cogible", etc. Pero eso se lo vamos a dejar a la relación being-carried-by, y esa es parte de la magia -en palabras de su autor- de este sistema: podemos expresar objetivos en términos de otras relaciones.

Comenzaríamos por crear una nueva relación:

Being-worn-by is a planning-relation.

Ya está. Ahora definiríamos la comprobación consecución del objetivo o relación. Esto se hace añadiendo una regla al libro Planning-testing, con la condición que especifica la relación a tener en cuenta y, si procede, otras comprobaciones:

Planning-testing when the desired relation is being-worn-by (this is the basic being worn rule):

if the desired param2 wears the desired param1, rule succeeds;

rule fails;

Básicamente, comprobar si personaje lleva o no la prenda, y responder en consecuencia. Desired-relation, desired param1 y desired param2 son las variables globales de la extensión que almacenan los elementos que integran la relación actual.

Por último, indicar el plan a seguir, caso de que la respuesta de la regla anterior sea negativa. Aquí estamos añadiendo también una regla, pero en este caso al libro Planning.

Planning when the desired relation is being-worn-by and the desired param2 is the planning actor (this is the basic wearability rule):

plan 1;

suggest being-carried-by with the desired param1 and the planning actor;

suggest doing-wearing with the desired param1;

rule succeeds;

Pues eso, buscarse la vida para tener la prenda (suggest being-carried-by) y luego ponérsela. La frase "plan1;" es una partícula a incluir cuando definimos un nuevo plan, y que evita tener que poner una serie de comprobaciones de la librería que quedan transparentes de cara al programador.

Doing-wearing no es una relación, es una acción, que queda definida mediante la siguiente sintaxis casi inmediata:

Doing-wearing is a planning-action.

Planning-acting when the planned action is doing-wearing (this is the basic executing wearing rule):

try the planning actor trying wearing the planned param1;

Al igual que en el plan, hay una serie de variables globales para identificar los elementos, en este caso, de la acción a llevar a cabo: planned action, planned param1, planned actor.

Con esto hemos terminado la definición del nuevo objetivo, pudiendo utilizarlo por sí sólo, o como parte de un nuevo plan más complejo, donde en algún punto especificaríamos algo como:

suggest being-worn-by with the chaqueta antibalas and the guardaespaldas;

Finalizada la parte aburrida, continuamos con nuestra aventura.

Modificación de los objetivos y planes básicos

La mayoría de las veces no vamos a necesitar implementar todo el conjunto de definiciones del apartado anterior. Eso sólo será necesario en el caso de que estemos creando una relación de nuevo cuño, con su conjunto de acciones y planes asociados. Por el contrario, es más probable que necesitemos hacer ajustes, para nuestro caso concreto, mediante la inclusión de reglas restrictivas o nuevas acciones que conduzcan la acción al objetivo deseado.

Volvemos al problema del caramelo cuando lo tenemos en las manos. En ese caso las reglas por defecto simplemente no saben qué hacer, por lo que no son capaces de indicar a Rafa ese nuevo paso a realizar en el turno actual al carecer de solución la cadena de objetivos. Resultado: el personaje se queda parado.

En este caso vamos a hacer que si tenemos el caramelo, nos siga, y además nos implore que se lo entreguemos.

Añadimos una nueva regla al libro Planning relativa al objetivo inicial (being-carried-by), para cuando el caramelo esté en nuestro poder.

Planning when the desired relation is being-carried-by and the desired param1 is the caramelo and the desired param2 is Rafa and the player encloses the caramelo:

plan 1;

suggest being-in with Rafa and the location of the player;

suggest imploring-for-candy;

rule succeeds.

Imploring-for-candy es una nueva acción coercitiva que forma parte del plan para perseguirnos cuando tengamos el caramelo.

Imploring-for-candy is a planning-action.

Planning-acting when the planned action is Imploring-for-candy:

say "Rafa solloza y patalea señalando al caramelo.";

Vuelve a compilar y ejecutar (el nuevo fuente completo aquí). Realmente no hemos creado nada nuevo, sólo hemos afinado el comporamiento del objetivo principal - being-carried-by - para el caso concreto, utilizando los libros de reglas establecidos para cada caso necesario.

Ingenio precoz

Ya tenemos un modelo de comportamiento bastante creíble (no voy a decir razonable, tratándose de quien se trata). Pero podemos forzar la imaginación siempre creativa de nuestro personaje añadiendo un par de elementos más al escenario. Pondremos el tarro de caramelos en una estantería fuera del alcance del agente, y también una silla en la sala de estar, que empujada y colocada convenientemente bajo el estante, permitirá a sus pequeñas manitas hacerse con el objetivo.

Un rápido análisis con el nuevo conocimiento adquirido respecto a la estructura de la librería nos revela los elementos a necesarios.

    • Los nuevos elementos del escenario, por supuesto: la silla y el estante.

    • Nueva relación pushing-chair-under que permita establecer un plan para llevar la silla bajo el estante.

    • Nuevas acciones no contempladas por la extensión Basic Plans, doing-pushing para empujar la silla por las distintas localidades de la casa, y doing-getting-on para subirse a la silla.

    • Un mecanismo sencillo para darle credibilidad a la "memoria" de Rafa. Es decir, sólo irá a buscar la silla cuando haya constatado la imposibilidad de acceder a los caramelos por sí mismo.

    • Finalmente vamos a reorganizar todo bajo un objetivo planificado específico y creado por nosotros, taking-candy, para no abusar de la semántica de la relación being-carried-by, que hemos aprovechado para la primera aproximación sencilla, y de esta forma objener un código más sencillo de entender y reaprovechable. Este objetivo se encargará de redirigir el plan del personaje hacia la mejor manera de obtener el caramelo en función de la información disponible.

Definición del escenario y el personaje

Comenzamos con un proyecto nuevo, ya que son varios los cambios a realizar sobre la versión anterior. Definimos los encabezados y el escenario de la aventura:

"Caramelos" by Anonymous

Include Spanish by Sebastian Arg.

Include Planner by Nate Cull.

Include Basic Plans by Nate Cull.

Part - El escenario

The Sala de estar is a female room. The description is "Una sala de estar confortable, aunque algo desordenada por las inquietudes exploratorias de Rafa.".

In the sala de estar is a silla. It is a female enterable portable supporter. It is pushable between rooms. Check the player pushing silla to: if the silla is carried, say "(dejas la silla en suelo antes)[line break]"; try silently dropping silla. Check the player taking the silla: if there is something on the silla begin; say "La silla está ocupada, no es cuestión de hacer malabares."; stop the action; end if.

The puerta is a female door. It is east of Sala de estar and west of the Cocina. The puerta is openable and closed. The cocina is female. In the cocina is a encimera. It is a female supporter.

In the cocina is a estante. It is a supporter.

On the estante is a frasco de golosinas. It is a openable closed transparent container. In the frasco is a caramelo. The description of the caramelo is "Glucosa solidificada, y el primer vicio de todo ser humano.".

La silla es un elemento con el que hay que tener cuidado, ya que se trata de un objeto para empujar entre habitaciones, pero además es portable. Hay que tener en cuenta si está ocupada, para no generar situaciones inverosímiles. Por simplicidad evitamos que se pueda coger si tiene objetos (o a Rafa) encima. También la dejaremos automáticamente, caso de tenerla en las manos, antes de ejecutar la orden de empujarla hacia algún sitio.

Seguidamente el código base del personaje Rafa.

Part - El personaje

Rafa is a man in the Sala de estar. The description is "Una encantadora criatura, especialmente cuando duerme."

Every turn:

have Rafa plan an action for taking-candy with rafa and the caramelo;

Every turn when Rafa has the caramelo:

if the location encloses Rafa:

say "Rafa levanta el caramelo mirando al cielo en señal de triunfo, y procede a engullirlo en un trago memorable (para su edad).";

otherwise:

say "Oyes gruñidos de placer desde [the location of Rafa], y al cabo de un rato aparece Rafa enseñando desafiante su roja lengua para restregarte su triunfo.";

end the story saying "FIN".

El único cambio respecto de la versión del apartado anterior es que hemos sustituido el nombre del objetivo. Ahora está descrito en términos generales como taking-candy, y es una relación nueva que vamos a definir posteriormente.

Y un pequeño parrafo para implementar la memoria de Rafa en relación a la situación conocida del caramelo. Esta situación no tiene por qué coincidir con la real, y le dará un aspecto más realista al plan de comportamiento.

Rafa has a truth state called candy-in-estante-remembered. The candy-in-estante-remembered of Rafa is usually false.

Every turn when Rafa can see the caramelo:

if the estante encloses the caramelo:

if the candy-in-estante-remembered of Rafa is false, say "Rafa extiende sus manos para alcanzar el caramelo, sin lograrlo.";

now candy-in-estante-remembered of Rafa is true;

otherwise:

now candy-in-estante-remembered of Rafa is false.

Plan general

Y por fin, el nuevo modelo de comportamiento que responderá al plan taking-candy que hemos aplicado al personaje.

Para hacer más entendible el código vamos a basarlo en los objetos concretos con los que estamos trabajando (el caramelo, la silla, el estante...). Esto es una práctica desaconsejada fuera de este tutorial, y en aras de la reutilización deberíamos usar los términos parametrizables y genéricosque proporciona la extensión: planning actor, planning, param1, planning param2...

Volviendo al plan general, este consiste en los siguiente: 1) si el caramelo está fuera del alcance de Rafa, colocar la silla bajo el estante y subirse. 2) Coger el caramelo. Trasladamos lo anterior casi literalmente a código:

Section - Los planes

[Plan para objetivo global]

Taking-candy is a planning-relation.

Planning-testing when the desired relation is taking-candy:

if Rafa carries the caramelo, rule succeeds;

rule fails;

Planning when the desired relation is taking-candy:

plan 1;

if candy-in-estante-remembered of Rafa is true, suggest pushing-chair-under;

suggest being-carried-by with the caramelo and Rafa;

rule succeeds;

Al tratarse de una relación nueva, debemos declararla y especificar la condición de testeo (planning-testing) y el plan de consecución (planning). En el plan de consecución, notar que trabajamos con el conocimiento de Rafa sobre la situación del caramelo, y no sobre la situación real de este. Being-carried-by es una relación de la extensión Basic Plans, por lo que no es necesario hacer más con ella.

Moviendo sillas

En cambio, pushing-chair-under es una nueva sub-relación que concreta el plan (sub-plan) a seguir cuando Rafa ha decidido que tiene que colocar la silla bajo el estante.

Pues vamos a ello:

[Plan para conseguir el caramelo utilizando la silla]

Pushing-chair-under is a planning-relation.

Planning-testing when the desired relation is pushing-chair-under:

if the silla is in cocina and Rafa is on the silla, rule succeeds;

rule fails;

Planning when the desired relation is pushing-chair-under:

plan 1;

suggest being-in with Rafa and the location of the silla;

suggest being-pushing with the location of the estante;

suggest doing-getting-on;

rule succeeds;

Como ya vamos cogiendo el tranquillo a eso de definir relaciones, no hace falta explicar los tres párrafos del código. El plan consiste en 1) Ir a la localidad de la silla, 2) empujarla hacia la localidad del estante y 3) subirse. El punto tres es una acción de consecución inmediata (una vez las dos anteriores se han logrado) y la vamos a definir por tanto como una planning-action.

Doing-getting-on is a planning-action.

Planning-acting when the planned action is doing-getting-on:

try the planning actor trying entering the silla.

Empujar la silla hasta el estante es un plan de varios turnos que debemos definir, nuevamente en un sub-nivel a su vez del plan para llevar la silla a él. Todo esto puede parecer complejo para una acción más bien sencilla (o no) como llevar la silla bajo el estante. Como he indicado antes, en nuestra implementación "seria" de estos algoritmos no deberíamos trabajar con objetos concretos, o lo que es lo mismo, el resultado debería ser un plan para que cualquier personaje pueda alcanzar un objeto alto empujando y subiéndose a cualquier supporter.

He aquí la última definición del nuevo plan.

[ Plan para empujar la silla entre habitaciones]

Being-pushing is a planning-relation.

Planning-testing when the desired relation is being-pushing:

if the silla is in the cocina, rule succeeds;

rule fails;

Planning when the desired relation is being-pushing:

plan 1;

let the way be the best route from the location of Rafa to the desired param1, using doors;

if the way is a direction:

suggest doing-pushing with the way;

rule succeeds;

rule fails;

Doing-pushing is a planning-action.

Planning-acting when the planned action is doing-pushing:

if the player is on the silla:

say "Rafa te empuja y te mira con cara de pocos amigos, parece que estando en la silla interfieres con sus planes.";

otherwise:

try Rafa pushing the silla to the planned param1;

En este caso se trata de elaborar un "plan", si se puede llamar así, para empujar la silla un pasito hacia la localidad objetivo. Para ello tomamos la siguiente dirección a seguir mediante la frase best route de las Standard Rules e invocamos la acción doing-pushing en la dirección retornada. La acción doing-pushing se limita a invocar una acción push to con Rafa y la silla, teniendo en cuenta la posibilidad de que en ese momento estemos sentados en la silla.

Resumen del plan

Recapitulando, podemos resumir el plan completo mediante una estructura arbórea como la siguiente:

Plan para conseguir el caramelo (taking-candy)

    • Si cree que está en el estante

      • Colocar la silla bajo el estante (pushing-chair-under)

        • Ir a buscar la silla

        • Empujar la silla hasta la localidad del estante (being-pushing)

          • Obtener la dirección hacia la que está el estante

          • Empujar hacia la dirección del estante (doing-pushing)

        • Subirse a la silla (doing-getting-on)

    • Llegar hasta el caramelo y cogerlo

Finalización y cierre

Lo que es el meollo de la nueva aventura ya está creado. Ahora sólo queda pulir y mejorar algunas respuestas para darle un aspecto más acabado.

Trasladamos el comportamiento implorante tal cual, para cuando tenemos el caramelo en nuestras manos:

[Plan para ir detrás de papá pidiendo el caramelo]

Planning when the desired relation is taking-candy and player encloses the caramelo:

plan 1;

suggest being-in with Rafa and the location of the player;

suggest imploring-for-candy;

rule succeeds.

Imploring-for-candy is a planning-action.

Planning-acting when the planned action is Imploring-for-candy:

say "Rafa solloza y patalea señalando al caramelo.";

La frase de la Standard Rules para seguir una ruta no contempla bajarse de objetos de soporte (como es la silla), así que si cogemos el frasco de caramelos cuando el niño está subido a la silla, se quedará clavado en esa posición. Lo solucionamos aplicando una regla restrictiva a la relación being-in:

[Añadido para being-in que contemple bajar de la silla]

Planning when the desired relation is being-in and the desired param1 is on the silla (this is the bajarse de la silla rule):

plan 1;

suggest doing-getting-off with the silla;

rule succeeds.

Bajarse de la silla rule is listed before the basic travel with best route rule in the Planning rules.

Doing-getting-off is a planning-action.

Planning-acting when the planned action is doing-getting-off:

try the planning actor trying getting off the planned param1;

Debemos poner atención si creamos nuevas reglas para rulebooks existentes, ya que el orden es importante. En este caso hemos tenido que forzar la posición de la nueva regla "bajarse de la silla" para que sea evaluada antes que el resto, so pena de disparar una de las reglas predefinidas que no contemplan la nueva situación.

Finalmente modificamos alguno de los mensajes por defecto para darle un toque personal a la historieta:

Part - Ajustes finales y mensajes por defecto

Report Rafa entering the silla:

say "Rafa culebrea entre las patas de la silla y consigue encaramarse al asiento." instead.

Report Rafa getting off the silla:

if Rafa was on the silla, say "Rafa se desliza torpe pero efectivamente desde el asiento de la silla hasta llegar al suelo." instead.

Report Rafa going a direction (called the way-pushed) with the silla:

if Rafa is in the location:

say "Ves aparecer a Rafa desde [the opposite of the way-pushed] arrastrando la silla de una pata." instead;

otherwise:

say "Rafa comienza a tirar de la silla, alejándose ruidosamente hacia [the way-pushed]." instead;

Compila y ejecuta el código. Puedes bajártelo aquí, o probar la versión definitiva online con parchment. Observa el comportamiento del personaje, interactúa con el entorno, modifica la posición de los objetos. Verás que es capaz de reaccionar a los cambios y establecer el plan más acorde en cada momento.

Impresiones finales

Planner es una extensión potente y fácil de utilizar, una vez se ha entendido el mecanismo. Sin embargo tiene sus limitaciones, como habrás podido comprobar a lo largo del tutorial.

La más llamativa es una omnisciencia crónica que afecta a todos los personajes y que va en detrimento del realismo. El modelo de agentes reactivos se supone fundado en la percepción del entorno por el agente, como no puede ser de otra manera si aplicamos el algoritmo a entidades reales, como pueda ser un robot que limpia nuestra casa. En cambio, en un mundo simulado como la ficción interactiva, es de esperar que los personajes no conozcan en todo momento los hechos de los que no han sido testigos, desde la localización exacta de un objeto hasta la existencia de un evento que modifica el estado del mundo, y que se produce fuera de la percepción del personaje. En esos casos es necesario implementar, como en el ejemplo del estante, algún tipo de "memoria" que siga la pista a la última situación conocida de objetos y eventos, y obligar al plan a actuar en función de ese conocimiento difuso en vez del estado real de los objetos.

El desarrollo de un módulo epistemológico para todos los personajes y objetos no parece utilizable en la práctica, y más dadas las limitaciones de I7 en cuanto a la creación de estructuras de datos con índices complejos. Por el contrario, es más efectivo llevar control sólo sobre aquellos objetos o eventos de los que cada personaje deba hacer seguimiento según indique su propio plan de comportamiento establecido.

Otro aspecto al que hay que prestar atención es la eficiencia. Precisamente por tratarse de agentes reactivos, el sistema carece de una memoria de acciones ejecutadas, valiéndose sólo del estado -es decir una foto- del mundo en cada turno. Para esto es necesario invocar las reglas de todos los agentes haciendo uso del rulebook Every turn. Con objeto de mantener la eficiencia bajo control, hay que evitar abusar de los scripts planificados si se puede. Una relación debe proporcionar la ventaja de la aplicabilidad sobre una gama completa de objetos y situaciones para merecer incluirse dentro del plan de acción. Para comportamientos o sub-comportamientos más específicos o que se produzcan en situaciones muy concretas quizás sea más eficiente codificarlos fuera del ámbito de Planner, o evitar la sub-planificación si dicho nivel no aporta valor fuera del ámbito de la planificación superior (al precio de complicar el código asociado al plan de la relación).