Un motor de misiones de campo geolocalizado, en tiempo real y offline-first.
Diseñado para experiencias de juego presencial con equipos, QR físicos, GPS y minijuegos.
SAGA Engine es una plataforma completa para diseñar y ejecutar misiones de campo gamificadas en el mundo real. Los jugadores reciben una ruta de nodos GPS, escanean QRs físicos, completan minijuegos y acumulan logros — todo ello funciona tanto con conexión como sin ella.
Pensado para escape rooms urbanos, gymkhanas, formaciones corporativas, tours guiados y cualquier experiencia donde quieras convertir el espacio real en un tablero de juego.
- Mapa interactivo basado en Leaflet + OpenStreetMap con nodos de misión geolocalizados
- Indicador de posición GPS del jugador con seguimiento dinámico
- Cálculo de distancia al nodo activo y radio de activación configurable
- Vista de ruta completa y modo "overview" de toda la misión
- Marcadores de equipo en tiempo real sobre el mapa
- Soporte completo de GPS del navegador con retroalimentación de precisión
- Modo debug de geolocalización para pruebas desde escritorio (permite mover manualmente la posición)
- Petición de GPS en el Login con flujo de permiso claro
- Entrada sin GPS permitida, con solicitud de posición simulada en debug
- Service Worker PWA con caché de assets y shell del jugador
- Mission Pack: descarga completa de la misión para jugar sin conexión
- Caché de teselas de mapa (tiles) con precarga configurable antes de salir al campo
- Sincronización automática de progreso offline cuando vuelve la conexión
- Pruebas de campo (fotos) almacenadas localmente y sincronizadas después
Sistema de dos niveles: familias (los motores de ejecución) y juegos (preajustes configurables que apuntan a una familia).
| Juego | Qué hace | Sensores |
|---|---|---|
| Checkpoint / Texto rápido | Llegar al punto y leer la pista | GPS |
| Matriz de circuitos | Reparar una ruta de energía en una cuadrícula | — |
| Simón Dice | Memorizar y repetir una secuencia de cuadrados de colores | — |
| Mosaico del lugar | Reconstruir una foto real del sitio intercambiando piezas | — |
| Laberinto de equilibrio | Guiar una bola inclinando el móvil, con botones de respaldo | Acelerómetro |
| Caza-Señales | Radar de reflejos: tocar chispas verdes y esquivar los ecos rojos | — |
| Desafío de audio | Soplar o hacer ruido para cargar una barra | Micrófono |
| Objeto QR / Llave QR | Escanear una pegatina física del mundo real | Cámara |
| Relevo de equipo | Prueba pensada para varios jugadores o roles | — |
Cada juego tiene editor propio en el panel de administración, con topes que impiden guardar una configuración injugable, y todos funcionan sin conexión.
Las tarjetas impresas con un logo grande encima no las lee ningún escáner estándar: el logo tapa la información de formato y las pautas de temporización, que no están protegidas por corrección de errores.
SAGA incluye un lector propio para esos casos:
- OpenCV (WASM) aislado en un Web Worker, para que un problema de memoria no se lleve por delante la pestaña del jugador.
- Localiza el código, corrige la perspectiva, muestrea la matriz de módulos y la compara con los payloads de la misión ignorando la zona del logo.
- Análisis multi-escala y realces (contraste, escalado) para fotos de campo.
- Umbrales calibrados para que ante una foto dudosa prefiera no leer antes que devolver el código de otro nodo.
/qr-selftest: página de autocomprobación que ejecuta el motor real sobre fotos de referencia y dice si ese móvil concreto reconoce las pegatinas antes de salir al campo.
- Recetas que combinan objetos de la mochila en piezas más potentes
- Los ingredientes que ya tienes se distinguen de los que faltan
- Una pieza fabricada puede ser requisito para desbloquear un nodo
Todo nodo acepta un código de rescate para no dejar a nadie bloqueado en el monte: completa el nodo aplicando una penalización de tiempo. El código impreso en la pegatina es también el código del nodo.
Cada familia tiene editor visual en el panel de administración y runtime propio en el cliente.
- Inventario con objetos recolectables (coleccionables, pistas, ítems de misión)
- Previsualización del siguiente nodo y su juego asociado
- Descripción contextual de cómo se juega cada minijuego
- Guía de herramientas integrada (asistente de campo)
- Descarga de fotos de campo como ZIP
- Perfiles de jugador y equipos configurables desde el admin
- Presencia de equipo en tiempo real (posiciones en el mapa)
- Soporte para modos solo y equipo
- Generación de tarjetas QR físicas desde el admin (QR Studio)
- Validación de QR con lógica de distancia — aviso centrado en pantalla si el jugador está demasiado lejos
- Soporte para tipos de nodo físico: Objeto QR, Llave QR, Pista QR, Bonus Oculto
- Panel de preview de requisitos antes de activar un nodo
- Captura de fotos geolocalizadas desde el cliente jugador
- Visor de fotos sobre el mapa con superposición de posición
- Eliminación de fotos propias
- Descarga en ZIP desde el panel de herramientas del jugador y desde el admin
Interfaz en galego, castellano e inglés, conmutable desde el propio juego. Los textos de la misión se guardan en el idioma que elija quien la diseña; la interfaz se traduce al vuelo al cambiar de idioma.
- Constructor de misiones con nodos, etapas y rutas
- Editor visual de minijuegos por familia
- Gestión de jugadores y perfiles de equipo
- Mapa de misión en admin con vista de posiciones en vivo
- QR Studio para generar y gestionar tarjetas QR imprimibles
- Configuración de la misión, idioma y parámetros globales
- Offline Vault: resumen del estado de preparación offline de cada jugador
saga_engine/
├── main.py # FastAPI app principal
├── requirements.txt # Dependencias Python
├── Dockerfile # Imagen Docker (Python 3.13-slim)
├── frontend/ # App React (Vite + TypeScript)
│ ├── src/
│ │ ├── App.tsx # Router raíz (Login / Player / Admin)
│ │ ├── login/ # LoginApp — selección de jugador + GPS
│ │ ├── player/ # PlayerApp — mapa, HUD, mochila, minijuegos
│ │ │ ├── components/ # PlayerHud, PlayerShell, MapSurface…
│ │ │ ├── minigames/ # Core + familias de minijuegos
│ │ │ ├── offline/ # PWA, Mission Pack, GPS cache…
│ │ │ └── utils/ # GPS, geo, stagePosition…
│ │ ├── admin/ # AdminApp — panel de administración
│ │ └── shared/ # API, tipos, identidad, offline vault…
│ └── public/ # Assets estáticos, manifest PWA, SW
├── scripts/ # Scripts de despliegue y auditoría
└── tests/ # Tests de backend (pytest)
Stack:
- Backend: Python 3.13 + FastAPI + SQLite (vía adaptadores)
- Frontend: React 19 + TypeScript + Vite + Leaflet
- Deploy: Docker (imagen única), desplegable en Raspberry Pi 4 o cualquier servidor Linux
- PWA: Service Worker con estrategia offline-first
- Docker
- (Opcional) Node.js 20+ para desarrollo frontend local
# Clonar
git clone https://github.com/tu-usuario/saga_engine.git
cd saga_engine
# Configurar entorno
cp prod.env.example prod.env
# Editar prod.env con tus valores
# Construir y arrancar
docker build -t saga_engine:latest .
docker run -d \
--name saga_engine_app \
-p 8096:5000 \
--env-file prod.env \
-v $(pwd)/data:/app/data \
saga_engine:latestEl script deploy_saga_safe.sh levanta primero un candidato en puerto alternativo, hace smoke test, y solo promueve si todo va bien:
bash scripts/deploy_saga_safe.sh saga_engine:latest --build --promotecd frontend
npm install
npm run dev
# → http://localhost:5173| Variable | Descripción | Ejemplo |
|---|---|---|
SECRET_KEY |
Clave secreta para sesiones admin | cambiar-en-produccion |
ADMIN_PASSWORD |
Contraseña del panel de admin | mi-password |
SAGA_VERSION |
Versión mostrada en el cliente | 3.0.0 |
SAGA_BUILD_TIME |
Timestamp de compilación | 2026-07-07T14:00:00+0200 |
DATA_DIR |
Directorio de datos persistentes | /app/data |
La misión se configura desde el panel de administración (/admin-react):
- Settings → Nombre de la misión, historia, idioma, jugadores
- Mission Builder → Crear nodos con coordenadas GPS y radio de activación
- Node Editor → Asignar familia de minijuego y configurar sus parámetros
- Physical QR → Generar y descargar tarjetas QR imprimibles
- Players → Gestionar perfiles de jugador y equipos
- Offline Prep → Verificar que todos los jugadores tienen la misión descargada
En entornos sin GPS real (escritorio, pruebas):
- Entra al jugador desde
/player/TU-JUGADOR - En la barra inferior → botón de debug 🐛
- Pulsa en el mapa para simular tu posición
Para pruebas de distancia a nodos, usa el modo debug para colocarte dentro del radio del nodo activo.
El sistema está optimizado para correr en una Raspberry Pi 4 (arm64):
# En la Pi
git clone https://github.com/tu-usuario/saga_engine.git
cd saga_engine
# Primera vez
docker build -t saga_engine:latest .
bash scripts/deploy_saga_safe.sh saga_engine:latest --promote
# Actualizaciones
# (desde el PC de desarrollo, subir los cambios a la Pi y re-ejecutar)
bash scripts/deploy_saga_safe.sh saga_engine:latest --build --promoteEl script gestiona automáticamente:
- Construcción de imagen nueva
- Prueba en puerto alternativo (18096)
- Smoke test de las rutas principales
- Promoción a producción (8096) solo si todo va bien
- Limpieza del candidato
# Instalar dependencias de test
pip install -r requirements-dev.txt
# Ejecutar todos los tests
pytest tests/ -v
# Tests específicos
pytest tests/test_game_state_repository.py -v
pytest tests/test_offline_progression_sync_api.py -vVer CHANGELOG.md para el historial completo de versiones.
MIT — ver LICENSE
Construido con ❤️ para misiones de campo reales.
SAGA Engine v3.0.0 — 2026