Facundo Chavez

Proyectos Motive

¿Qué es Motive?

Este es un videojuego impulsado por IA donde cada partida presenta una nueva escena del crimen a resolver: el jugador debe descubrir el oficio del asesino, el lugar del crimen, la causa de la muerte y el arma homicida. La mecánica es simple pero desafiante: se puede formular cualquier tipo de pregunta, pero la IA solo puede responder por “sí” o por “no”.

Motive banner

¿Cómo nació la idea?

En 2022, cuando conocí ChatGPT y comencé a experimentar pidiéndole poemas y resúmenes, me surgió una pregunta: ¿podría ser el chat un buen anfitrión para un juego de adivinanzas al estilo Clue? Más concretamente: ¿sería la IA capaz de “pensar” en la escena de un crimen y, sin revelarla, responder por “sí” o por “no” a mis preguntas hasta resolver el misterio?

Aunque hoy podríamos intuir la respuesta, en aquel entonces la tecnología era nueva y todavía estábamos explorando sus límites. Pero sí: el experimento fue terrible. Para la IA era imprescindible que la palabra estuviera explícitamente escrita en su contexto; y al no estarlo, comenzaba a alucinar, se contradecía o revelaba el supuesto misterio tras mi primera pregunta. Además, no tardaba en romper la consigna y empezaba a responder con frases que no eran estrictamente “sí” y “no”.

Tras varios ajustes en el prompt, logré que el comportamiento se mantuviera consistente por un tiempo… pero después de unas cinco preguntas, terminaba desvirtuándose igual. Un chat, con su historial conversacional acumulativo, simplemente no es un formato adecuado para este tipo de juegos.

Tiempo después, lancé whatMLmodel, una aplicación con un LLM integrado, y entendí que por primera vez contaba con las herramientas necesarias para comprobar si aquel juego de adivinanzas era algo plausible. Ya sabía cómo utilizar la API de Gemini... ahora quería ver si, manteniendo un contexto acotado y esquematizando las respuestas del modelo, era posible jugar de una forma medianamente satisfactoria a resolver la escena de un crimen.

Clue game

¿Cómo funcionaría?

La idea era que el jugador pudiera enfrentarse a múltiples casos y que, en cada uno, tuviera que descubrir las mismas cuatro consignas: oficio, lugar, causa y arma. Primero pensé en que los casos fueran generados por la IA en tiempo real, pero rápidamente entendí que esta gran base del juego requería criterio humano y no podría delegarse. De todas maneras, me ayudé con ChatGPT dándole una consigna muy simple: crear casos con una dificultad razonable, donde los cuatro ítems estuvieran bien relacionados y que tuvieran algún giro inesperado.

Después de unos ajustes, los resultados fueron tan buenos como “Un entrenador personal que envenena a su víctima con un batido de proteínas en un gimnasio”. Cosas muy ingeniosas, sí, pero que a veces carecían de chispa o rompían la coherencia entre los elementos. Por esa razón, refiné cerca de sesenta casos que se elegirían aleatoriamente al comenzar las partidas.

Los misterios se mantendrían ocultos a los ojos del jugador y se utilizarían para construir prompts con la siguiente información:

  1. El ítem a resolver y su respuesta (por ejemplo, “Oficio del asesino: Entrenado personal).
  2. La pregunta del usuario sobre ese ítem (“¿Tiene que ver con la actividad física?”).
  3. Los otros tres ítems, también con sus respuestas, para enriquecer el contexto.

El modelo devolvería entonces true o false según lo bien encaminada de la pregunta, y el principal desafío en este punto fue lograr que la IA comprendiera el concepto de “adivinar”. En las primeras pruebas, los falsos positivos y negativos aparecían con demasiada frecuencia y, aunque extender el prompt parecía una buena opción para reducir ambigüedades, en realidad se trataba de un arma de doble filo: al contar con ciertas features, la aplicación necesitaba realizar otras consultas —en la misma llamada para optimizar recursos— y esta request compuesta, si no era corta y concisa, hacía que el modelo se confundiera.

En definitiva, necesitaba que la IA tradujera cada pregunta del jugador en un conjunto claro de claves de estado:

  • isGuessed: booleano que indica si la pregunta dio exactamente con la respuesta correcta (por ejemplo: “¿Es un entrenador personal?” → true);
  • isAFact: booleano que señala si la pregunta revela un dato importante sobre la respuesta, aun cuando no la haya adivinado exactamente (“¿Tiene que ver con la actividad física?” → true);
  • factSentence: en caso de que isAFact sea true, contiene la frase derivada de ese dato (“La profesión implica instruir a individuos en el esfuerzo físico.”);
  • isPositive: booleano que indica simplemente si la pregunta del jugador es positiva para la respuesta, por más que isGuessed e isAFact sean false (“¿Requiere estudios avanzados?” → true);
  • isContinuation: booleano que indica si la pregunta actual del jugador está vinculada con sus preguntas anteriores (enseguida explicaré el motivo de este ítem).

Luego veremos qué indicaciones funcionaron para lograr buenas respuesta bajo este esquema, pero lo que realmente optimizó los resultados fue hacer un prompt dinámico: no se trataba solo de insertar la información en un string, sino que el mismo string debía variar según el ítem a resolver. Por eso, definí templates con reglas y ejemplos específicos para oficio, lugar, causa y arma.

Luego, algo importante fue mantener a la IA focalizada y veloz, y para eso necesitaba un contexto lo más reducido posible. El prompt dinámico formaría parte de ese contexto, pero ¿valía la pena reenviar todo el historial de preguntas y respuestas en cada llamada? Mi intuición fue que no; sin embargo, no hacerlo impedía que el juego funcionara como un auténtico chat: no se podían encadenar preguntas como “¿Requiere de estudios avanzados?” y “¿Muy avanzados?”.

Esa es la razón de la clave isContinuation. En cada request se incluye la pregunta actual y, por lo menos, la inmediatamente anterior; si esta última está marcada con un isContinuation igual a true, se incorpora también la precedente, y así sucesivamente hasta que alguna indique false. De este modo fue posible conservar la dinámica conversacional manteniendo solo lo indispensable en el contexto.

El motor del juego

Mi primera intención fue utilizar webLLM (un motor que ejecuta modelos directamente en el navegador: de forma local y sin llamadas a una API), sin embargo, los problemas no tardaron en aparecer: dependencia de WebGPU (poco compatible con teléfonos móviles), tiempos de descarga de modelos muy elevados, bajo rendimiento incluso para preguntas simples y modelos poco confiables, que arrojaban falsos positivos y negativos con demasiada frecuencia. Por todo esto, tomé la misma iniciativa que en whatMLmodel: llamadas a la API de Gemini, cuya capa gratuita resultaba más que suficiente.

El frontend centraliza la lógica en un servicio orquestador que captura la pregunta del usuario, la empaqueta con el estado actual del juego (ítems con sus respuesta y últimos mensajes del chat) y envía todo al servidor. El backend recibe esta request, selecciona el template adecuado según el ítem a adivinar, construye el prompt y realiza la llamada a la API. Aquí implementé una estrategia de fallback entre modelos para asegurar la estabilidad: si el más liviano y rápido falla, la aplicación escala automáticamente a uno más potente —aunque más lento— sin que el usuario lo perciba. Además, diseñé un mecanismo de rotación de claves para ampliar aún más el margen de la capa gratuita: cuatro API keys gestionadas mediante un contador en Firebase.

Pero el corazón de todo fueron los prompt-templates: para cada categoría construí indicaciones que instruyen al modelo para comparar la pregunta del jugador con la solución secreta, y responder únicamente en un formato JSON predefinido. Así, la IA distingue si existe una suposición exacta (isGuessed), un dato relevante (isAFact), una afirmación positiva (isPositive) y una continuación directa de preguntas (isContinuation). Aquí el template correspondiente al oficio del asesino:

El arte

Desde un principio tuve claro que Motive debía ser un juego en pixel art. Se trataba de un gusto personal, pero también de una oportunidad: al no requerir una gran cantidad de ilustraciones, podía tomarme el tiempo de experimentar por primera vez con este estilo.

Me enfrenté a varios desafíos de diseño, pero el verdadero reto llegó con el desarrollo: el elemento más recurrente —en botones, contenedores, etc.— era un cajón pixelado aparentemente sencillo, pero imposible de reproducir con opciones nativas de CSS. Así que tuve que pensar en un componente capaz de adaptarse en alto y ancho, y de renderizar múltiples divs dentro de sí para simular un borde pixelado:

La selección tipográfica fue más sencilla: necesitaba una fuente minimalista para los textos y otra más adornada para el logotipo. Para los textos elegí VP Pixel Simplified (completándola manualmente para soportar caracteres especiales en español) y, para el logotipo, Alagard, que encajó perfectamente con el nombre del juego.

VP Pixel Simplified font
Alagard font

Y sí... Motive necesitaba de ilustraciones para cobrar vida. La idea fue tener el avatar de un detective siempre presente, para que el chat se sintiera como tal. Tras explorar diseños con modelos de generación de imágenes, di con uno que me gustó mucho y lo repliqué manualmente en un layout de 26×26 píxeles. Así nació Motiveman: un personaje que reacciona a las acciones del jugador mediante un sistema de sprites: piensa, asiente y niega según el estado del juego. Este diseño, al mismo tiempo, determinó la paleta de colores. Sumándole efectos de sonido y música de misterio, la experiencia dejó de sentirse como una simple aplicación web para convertirse en un videojuego con identidad propia.

Motiveman normalMotiveman talkingMotiveman thinkingMotiveman hmMotiveman guessMotiveman fact

El resultado

La navegación del menú se basa en un array que funciona como un breadcrumb: tenemos una secuencia de claves —por ejemplo, home/settings/createAccount— y, por cada una, se renderiza un layout diferente. Al hacer clic en una opción, se agrega un ítem al breadcrumb y se anima con un slide hacia la izquierda. Al hacer clic en “Volver”, ocurre lo contrario: primero hay una traslación hacia la derecha y luego se elimina el ítem. El resultado es un sistema versátil que me permitió encadenar tantas pantallas como fuera necesario, sin tener que pensar en flujos específicos.

Al iniciar una partida aparece una introducción y, si es la primera vez que se ingresa, un tutorial que guía al jugador por las funcionalidades. Aquí se me ocurrió justificar la mecánica del “sí” y “no” de una forma bastante simple: se estaría interrogando a un testigo que está en shock y que únicamente puede negar o asentir con la cabeza.

En la parte superior se elige el ítem a investigar y, debajo, se muestra el chat para hacer las preguntas. Además de “sí” y “no”, existe la respuesta “hm…” para preguntas ambiguas o que no pueden responderse de ninguna de las dos formas. Un desafío importante fue lograr que el juego no resultara frustrante, y por eso aparece un mensaje de “Necesitas ser más específico” si la respuesta es “hm…” con demasiada frecuencia.

Cuando se descubre un nuevo hecho, el mismo se agrega a un Panel de hechos. Esta mecánica surgió en una etapa avanzada del desarrollo, pero terminó siendo clave para orientar al jugador. Si aun así se necesita una pista explícita, puede pedirse una mediante una lupa verde que añade una frase —también generada por IA— a esa misma lista.

Resultaba fundamental relevar falsos positivos y negativos. Para ello, diseñé un sistema de reportes que permite describir el problema y marcar respuestas conflictivas. La idea es construir una base de datos sólida que sirva para mejorar el LLM output.

Cuando el jugador considera que ha identificado la respuesta, puede validarla mencionándola explícitamente. Si acierta, el misterio se revela y se resalta en verde. Para este evento, implementé una animación dedicada del avatar, que levanta el pulgar en señal de aprobación.

Hacia el final del desarrollo se me ocurrió algo más: incluir un quinto misterio que le dio sentido al nombre del juego. El objetivo sería entonces identificar el motivo del homicidio, es decir, el móvil que llevó al asesino a cometer el crimen. Para no extender tanto la experiencia, limité esta etapa a una cantidad reducida de preguntas: el detective explica entonces que el testigo necesita descansar y que su abogado accede a concedernos cinco preguntas más. En este punto, la música cambia y el juego adopta un tono más tenso y emocionante.

Al finalizar la partida, se calcula el puntaje considerando factores como el tiempo de juego y la cantidad de pistas solicitadas. Si el usuario no está registrado, el juego lo invita a crearse una cuenta para formar parte del ranking de jugadores.

¡Y eso es todo! Si quieres juegar a Motive, te dejo su link aquí abajo. Cualquier comentario, sugerencia o reporte de errores, es más que bienvenido: