Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,13 @@ save.json.tmp
*.roto
save.test-*.json
test_snapshots/

# Tripo: la key vive en el entorno, los GLB y el visor en la notebook del demo.
.env
.env.*
assets/tripo/
vendor/model-viewer.min.js

# Capturas de documentacion: solo los PNG finales se versionan.
.playwright-cli/
output/playwright/
171 changes: 166 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,166 @@
# RUNA

Un RPG ASCII para terminal donde exploras una ciudad, recorres la pradera y escribes las reglas que usa tu personaje al combatir.
**Un videojuego donde los gráficos evolucionan con vos: un regalo para quienes crecen mientras expanden su propia imaginación.**

**Versión actual: 0.2.0 — Reinos y exploración**
RUNA parte de un mundo ASCII: explorás dos reinos, conseguís equipo y escribís
las reglas que usa tu personaje al combatir. La progresión visual por nivel
es la dirección del proyecto. Hoy el sprite refleja el equipo que llevás y
los modelos generados con Tripo aparecen como animaciones ASCII en el menú,
la creación de personaje y las vistas del yelmo; todavía no hay un cambio
automático de estilo gráfico al subir de nivel.

**Versión actual: 0.2.0 — Reinos, exploración y modelos Tripo en ASCII**

El mundo corre sobre **Bare**, se dibuja con **bare-tui** y mantiene todo el arte dentro de una grilla ASCII estable. El personaje, los NPC y los monstruos se mueven sin borrar el terreno ni romper las líneas de la consola.

![Menú principal de RUNA](docs/screens/menu.png)
![Menú principal de RUNA](docs/screens/tripo-paisaje.png)

## Actualización para el hackathon de Tripo

[Ver la demo grabada (MP4, 68 segundos)](docs/demo/runa-tripo-demo.mp4).
Es un recorrido reproducible por el render real del juego, grabado en un
navegador a partir de entradas y cuadros de Runa. Usa una partida de muestra
en memoria, sin tocar guardados. [Cómo se grabó](docs/demo-walkthrough.md).

RUNA incorpora modelos 3D generados con Tripo **dentro de la terminal**.
Generamos un héroe medieval, un Coloso de piedra, un yelmo de hierro y un paisaje del reino con
texto a 3D, descargamos los GLB y convertimos sus geometrías a cuadros ASCII.
El juego reproduce esos cuadros: no necesita navegador, GPU, API key ni una
conexión a Tripo para mostrarlos. Los cuadros ya están incluidos en el repo.

### Qué cambió y dónde verlo

| Modelo generado con Tripo | Integración en RUNA |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Paisaje del reino | Gira en el menú. Se combina con el héroe y el Coloso ya generados para componer el enfrentamiento fuera de las murallas. |
| Coloso de piedra | Aparece en su arena, reutilizando el modelo generado y conservando la lógica de combate. |
| Héroe con espada y escudo | Gira al crear un personaje y forma parte de la escena del menú. |
| Yelmo de hierro | Gira al seleccionarlo en la armería o en la mochila, cuando hay espacio en la terminal. |

Cada modelo tiene **24 vistas separadas por 15 grados**. Una vuelta tarda
aproximadamente tres segundos. Los cuadros del menú existen en `64×22`, `40×10` y `28×5` caracteres y se
elige el mayor que cabe sin ocultar los controles. Maximizar la terminal
permite ver más detalle.

**El reino y el enfrentamiento en el menú.** El diorama del reino se completa
offline con las geometrías originales del héroe y el Coloso. Tripo generó el
castillo sin los combatientes del prompt; reutilizamos sus modelos para
completar la escena. Es una composición de figuras enfrentadas, sin rig.

![Paisaje del reino con héroe y Coloso en el menú de RUNA](docs/screens/tripo-paisaje.png)

**Coloso dentro del mapa.** Su dibujo utiliza ahora el GLB real convertido a
un lienzo `43×13`. La vida, los ataques, los avisos y las colisiones siguen
controlados por el juego.

![Coloso de Tripo dentro de las ruinas volcánicas](docs/screens/tripo-coloso-mapa.png)

**Creación de personaje.** El héroe generado es una vista previa; el personaje
que camina conserva el sprite compacto, su inicial y el equipo que posee.

![Héroe de Tripo durante la creación de personaje](docs/screens/tripo-personaje.png)

**Yelmo en la armería y en el inventario.** Es la representación del objeto
`iron_helmet` que ya existía: requiere nivel 3, cuesta 75 de oro y aporta
defensa `+2` y velocidad `-0.04`. Se compra con `Enter` en la armería; desde
la mochila (`I`), `Enter` lo equipa y `X` lo quita. La vista previa no cambia
el equilibrio del equipo.

![Yelmo de Tripo seleccionado en la armería](docs/screens/tripo-yelmo-tienda.png)

![Yelmo de Tripo equipado y seleccionado en la mochila](docs/screens/tripo-yelmo-inventario.png)

**Los modelos antes de convertirlos a texto.** El visor local es una herramienta
opcional para inspeccionar los GLB originales; el juego funciona sin él.

![GLB reales del yelmo, héroe, Coloso y paisaje generados con Tripo](docs/screens/tripo-modelos.png)

### Cómo lo hicimos

```text
Prompt de texto
-> Tripo: modelo P1-20260311, 3000 caras, textura y PBR
-> tarea completada y descarga del GLB
-> conversión offline: geometría, luz y 24 ángulos
-> JSON con cuadros ASCII
-> reloj del juego + bare-tui -> animación en la terminal
```

1. [tripo-generate.js](scripts/tripo-generate.js) crea una tarea en la API v3,
consulta su progreso y descarga el GLB cuando termina. Usamos
`P1-20260311`, `face_limit: 3000`, `texture: true` y `pbr: true`. Cada uno
de estos cuatro pedidos reales consumió 40 créditos según la respuesta de
la API. Un pedido interrumpido puede retomarse con `--task`, sin crear otro.
2. [glb-to-ascii.py](scripts/glb-to-ascii.py) lee la escena GLB y aplica las
transformaciones de los nodos. Rota la geometría, proyecta los triángulos
con un buffer de profundidad y convierte la iluminación de sus superficies
en caracteres de la escala `.:-=+*#%@`. Compensa la proporción de las
celdas de terminal, que son más altas que anchas. No muestrea las texturas:
el ASCII conserva la forma y la luz, con el color aplicado por el juego.
3. [assets/ascii](assets/ascii) contiene las 24 vistas de cada modelo en tres
tamaños. [render.js](lib/render.js) las muestra y el reloj de
[game.js](lib/game.js) avanza la animación cada 125 ms aproximadamente.
**Durante el juego solo se carga texto; el procesamiento 3D ocurre antes.**

Los modelos Tripo se usan en el menú, la creación, las vistas del yelmo y el mapa del Coloso.
No hicimos rig ni animación esquelética: el movimiento nuevo es una rotación
de vistas precalculadas.

### Probar la actualización

```bash
npm install
npm start -- --solo
```

Esperá en el menú para ver el paisaje y elegí **Nueva partida** para ver
al héroe. Para inspeccionar el yelmo en detalle, seleccioná la pieza en la
armería o, después de comprarla, en la mochila. No hace falta generar nada
para probar las animaciones incluidas.

Para generar un modelo propio, usá Node 18 o posterior y guardá tu key en
`~/.config/tripo/key.txt` (en Windows, `%USERPROFILE%\.config\tripo\key.txt`)
o en la variable `TRIPO_API_KEY`. La credencial permanece fuera del repo:

```bash
npm run tripo -- --balance
npm run tripo -- --name yelmo "a low-poly iron helmet with a single rune on the brow, game prop"
python3 scripts/glb-to-ascii.py assets/tripo/yelmo.glb --output assets/ascii/yelmo.json
```

La conversión requiere Python 3 y `numpy`. En Ubuntu, podés preparar un entorno
fuera del repositorio:

```bash
python3 -m venv ~/.venvs/runa-ascii
source ~/.venvs/runa-ascii/bin/activate
python3 -m pip install numpy
```

Activá ese entorno antes de ejecutar el conversor. Los GLB se guardan en
`assets/tripo/`, fuera de git. Los JSON se versionan para que cualquier persona
pueda jugar sin credenciales. Para ver los GLB originales:

```bash
node scripts/tripo-viewer.js --fetch-lib
npm run tripo:viewer
```

Abrí `http://127.0.0.1:4173/`. El visor detecta modelos nuevos automáticamente.
En esta máquina usamos `node --use-system-ca scripts/tripo-generate.js ...`
con Node 24 para que HTTPS reconozca los certificados del sistema.

Los prompts utilizados para los tres modelos, el flujo de regeneración y las
limitaciones están documentados en [ascii-turntable.md](docs/ascii-turntable.md)
y [tripo-integration.md](docs/tripo-integration.md).

### Portada ilustrada

También creamos una portada gráfica con una herramienta de generación de
imágenes independiente de Tripo. Se conserva como material visual del proyecto;
la pantalla del juego utiliza ASCII.

![Portada ilustrada de RUNA: héroe, Coloso y torre central](assets/runa-cover.png)

## Novedades de la versión 0.2.0

Expand Down Expand Up @@ -223,8 +377,8 @@ npx bare test/map.smoke.js

Estado revisado de esta versión:

- `140/140` pruebas correctas.
- `1309/1309` aserciones correctas.
- `142/142` pruebas correctas.
- `1337/1337` aserciones correctas.
- Formato y lint limpios.
- RUNA, NOX, fronteras, puertas, portón, pradera y dungeon validados por el smoke test.
- Capturas inspeccionadas y recortadas al borde exacto de la terminal.
Expand All @@ -239,6 +393,13 @@ npx bare scripts/readme-screens.js .readme-screens

Esto evita documentar una ciudad, un héroe o un combate que ya no coincidan con el código.

Las capturas nuevas `tripo-*.png` usan estados reproducibles de `120×44`
celdas. Se captura el elemento `.terminal` de los HTML generados, con un
viewport suficientemente grande para mostrarlo entero. `tripo-modelos.png`
es una captura del visor local con los tres GLB reales cargados. Los estados
de tienda e inventario se preparan con equipo para mostrar las vistas previas;
no representan el inventario de una partida nueva.

## Arquitectura

| Archivo | Responsabilidad |
Expand Down
Loading
Loading