Alexei Rojas Quiroga
← Todos los proyectos

Proyecto personal

The Gauntlet

RPG de texto de fantasía oscura: un motor determinista manda y un LLM narra

Estado
En desarrollo
Rol
En solitario: diseño del juego, motor, integración de IA, frontend, herramientas y despliegue
GitHub

Arquitectura

  • Motor puro; el LLM solo narra
  • 10 capítulos autorales validados
  • Narrador local de respaldo
  • Pruebas de partida automática
  • Multijugador opcional

El jugador actúa, el motor lo resuelve con los datos del capítulo, emite eventos y guarda; el narrador convierte esos hechos en texto por la ruta del servidor, o localmente si falla el LLM.

Arquitectura · 9 nodos · 2 flujos
LO QUE CONSTRUÍReact 19 · Nex…Interfaz del juegoTerminal, combate ypersonajeTypeScriptMotor de juegoDados, combate,intención y puzlesIn-processBus de eventos dedominioHechos resueltos parael narradorTypeScriptCliente narradorConstructor de prompt ypresupuestoNext.js routeProxy de narraciónLlamada al LLM desde elservidorNaN Builders A…Proveedor LLMNarración y generaciónde capítulosTyped data + Z…Datos de capítulose historiaGrafo de historia,monstruos, 10 capítuloslocalStorageSistema de guardadoGuardados, checkpointsy migraciónTypeScriptNarrador localNarración porplantillas si falla elLLM1234567
  • Servicio / cómputo
  • Almacén de datos
  • Cola / mensajería
  • IA
  • Cliente
  • Síncrono
  • Asíncrono / bucle
Desplázate hacia los lados para ver todo el diagrama

Cómo fluye, paso a paso

Haz clic en un paso para saltar a él. Haz clic en un componente para ver detalles.

Qué hace

Un RPG de fantasía oscura bilingüe en el navegador, con creación de personaje, combate D20 por turnos, puzles, inventario y una campaña de varios capítulos. El motor de juego es dueño de cada regla y resultado, mientras un LLM convierte eventos resueltos en narración y genera capítulos nuevos que deben pasar validación de esquema y de jugabilidad antes de poder jugarse.

El problema

Los juegos dirigidos por LLM se desvían: los modelos olvidan la campaña, inventan resultados y rompen reglas. El objetivo era un Dungeon Master con IA expresivo pero incapaz de alterar el estado autoritativo del juego.

Qué construí

  • Separación estricta entre un motor de juego puro (combate, dados, intención, puzles, campaña) y una capa de narración LLM que nunca modifica el estado.
  • Los capítulos son datos estandarizados y validables, con diez capítulos escritos y un grafo de historia de decisiones y condiciones en lugar de flujo fijo.
  • Un arnés de partidas sin interfaz recorre el motor con cada arquetipo y origen, resolviendo y abandonando puzles, y comprueba que el jugador nunca queda atascado.
  • Sistema de guardado con migración de versiones previas y consolidación del progreso de campaña, de modo que la persistencia no depende de que el modelo recuerde la historia.
  • Un bus de eventos de dominio alimenta al narrador; la longitud de la narración es un único presupuesto compartido por el prompt y el cliente, así la salida se escribe dentro del límite y no se recorta.
  • Generación de capítulos con LLM: una ruta del servidor pide al modelo un esquema y un capítulo bilingüe completo, lo valida con un esquema Zod y un validador de grafo, y lo repara hasta en tres intentos.
  • El validador rechaza cualquier capítulo con un estado alcanzable desde el que ya no se puede terminar (bucles inescapables), un defecto hallado al ejecutar capítulos generados reales; los fallos de transporte se reintentan aparte de los intentos de reparación del modelo.
  • Servidor WebSocket opcional para salas multijugador.

Decisiones clave y por qué

01

El motor es autoritativo, el LLM solo narra

Dados, combate y estado de la historia son código determinista. El modelo recibe eventos resueltos y devuelve prosa, así los resultados son reproducibles y comprobables y la IA no puede hacer trampa ni contradecir las reglas.

02

Capítulos como datos, no como código

Pasar los capítulos a un formato estándar validado elimina ids fijos del motor y permite cargar capítulos nuevos, incluso generados por LLM, de forma segura y verificable sin conexión.

03

Las llamadas al LLM pasan por una ruta del servidor

El navegador llama a una ruta API de Next.js que guarda la clave y habla con el proveedor, manteniendo el secreto en el servidor y el cliente simple.

04

Los puzles siempre se resuelven sin conexión

Los puzles nunca llaman al LLM y comparten una sola forma entre motor, validador y contrato de capítulo, así la progresión no se bloquea por una mala generación.

05

Los capítulos generados pasan la misma compuerta que los escritos

El servidor nunca devuelve un capítulo que no haya pasado el esquema y el validador completo de alcanzabilidad, así una mala generación devuelve un error (422) en lugar de una campaña rota.

Stack tecnológico

Lenguajes
TypeScript
Frontend
Next.js 16React 19Tailwind CSS 4
Backend
Node.js route handlers
Mensajería
WebSocket (ws)
Otros
Zod
IA
NaN Builders LLM API
DevOps
Docker (multi-stage, pnpm)
Pruebas
tsx validation and playthrough scripts