Una persona y Claude

Cómo se hizo

El motor, los juegos y esta web, hechos hablando con Claude Code y medidos en la placa de verdad.

En cifras

  • 16.489líneas de C en el motor
  • 33juegos de ejemplo
  • 117pruebas en cada cambio
  • 239commits en el repositorio

Una persona y Claude. El motor, los ejemplos, las herramientas y esta web se escribieron hablando con Claude Code: cada idea se probaba en el simulador, se medía en la placa y se corregía según lo que mostraban las mediciones.

El arte, generado y ajustado. Los aspectos que lo necesitan (Neo Geo, CPS2, 32 bits) usan imágenes generadas con IA. Las herramientas del motor las recortan, las escalan a la altura justa, separan los fotogramas y las reducen a la paleta de la consola. Los aspectos de baja resolución se dibujan con código.

Medido antes de darlo por bueno. Cada ejemplo tiene un guion que lo juega solo. En el ordenador, el guion compara la suma de control de cada fotograma con la guardada; en la placa, anota los fps de cada segundo. Así se comprueba que las optimizaciones no cambian ni un píxel.

Libre de verdad. El código tiene licencia MIT; el arte, el sonido y los vídeos de los ejemplos, CC0. Cógelo, cámbialo y haz tu propia consola.

Un enemigo, del encargo al juego

El goblin del juego mazmorra, paso a paso, con las imágenes reales.

  1. 1 · El encargo

    Un goblin original para un beat 'em up de fantasía: pequeño, enjuto y encorvado, piel verde, orejas enormes, un taparrabos raído y un puñal curvo oxidado. De cuerpo entero, mirando a la izquierda. Estilo: sprite de recreativa de mediados de los noventa, píxeles nítidos, contorno oscuro, unos 15 colores. Fondo transparente.

    Resumido y traducido del encargo, que se escribió en inglés.

  2. 2 · La referencia

    El goblin solo, de cuerpo entero: verde, con orejas puntiagudas y un puñal curvo

    El personaje solo. Se adjunta a cada encargo siguiente para que no cambie de un dibujo a otro.

  3. 3 · La hoja de poses

    Diez poses del goblin en dos filas, sobre un fondo oscuro difuminado

    Diez poses: andar, apuñalar, encajar un golpe y caer. El fondo se pidió transparente y salió pintado.

  4. 4 · El recorte

    Los diez fotogramas recortados, a la misma escala y con los pies en la misma línea

    Las herramientas del motor quitan el fondo, separan los fotogramas, los dejan a la misma escala con los pies alineados y los reducen a 15 colores. Luego se revisa cada uno a ojo.

  5. 5 · En el juego

    Alba, la espadachina, frente a dos goblins en el pasillo de la mazmorra

    En mazmorra salen en grupo, a 60 fps en la consola.

Seis días en el repositorio

  1. El motor nace de dos juegos de aventuras y se mide en la placa: la imagen va directa al panel, por franjas.

  2. Un procesador de imagen virtual, como el de la Game Boy Advance, y juegos en Lua de cualquier género.

  3. Medición y optimización en la consola. El editor web, para hacer juegos sin programar.

  4. Los aspectos de doce consolas, la vista en primera persona, las instrucciones para que un agente haga juegos, la web y la Biblioteca.

  5. La web y el editor en tres idiomas, los juegos de Codex e IL·LUSTRES en la Biblioteca.

  6. El studio de sonido, un secuenciador con sintetizador y efectos. La web, en pestañas, con la pestaña Juega y una página y un ranking para cada juego.

Todo el proceso está en el repositorio: cómo se hace el arte (se abre en una pestaña nueva), la API de Lua (se abre en una pestaña nueva), las instrucciones para agentes (se abre en una pestaña nueva).

ESP32-S3R8 · 240 MHz · PSRAM octal a 80 MHz · pantalla QSPI a 80 MHz

Medido en la consola, no prometido

Cada cifra de esta sección sale de la placa: o un firmware que juega solo siguiendo un guion y anota el rendimiento cada segundo, o un banco de pruebas que repite cada escena cinco veces. Nada de emuladores. A 60 fps, cada fotograma dispone de 16,6 ms.

  • 71%de un núcleo en la escena más pesada: capa afín, cuatro capas y 128 sprites
  • 8,1mspara enviar un fotograma entero al panel; solo el cable se lleva 7,7
  • 3%de un núcleo para el sonido mientras se juega
  • 117pruebas que juegan solas y comparan cada fotograma, en cada cambio

Doce aspectos, en fotogramas por segundo

El segundo más lento y el más rápido de cada ejemplo, jugando en la consola. En gris, la primera medición, antes de optimizar.

Aspectofps
Neo Geoduelo 60–61 fps
CPS2torneo 60–61 fps
Game Boybolsillo 58–61 fps
ZX Spectrumcinta 41–62 fps
PICO-8ladrillos 47–60 fps, antes 46–55
Maquinita LCDhuevos 60–61 fps
PlayStation · Saturn 2Dgotico 60–61 fps, antes 30–31
Super Nintendo · Mega Driveveloz 40–59 fps
Vectorialrocas 61 fps
Game Boy Advanceplataformas 61 fps
Recreativa verticaltormenta 30 fps, antes 20
Primera personalaberinto 38–60 fps, antes 20–31

Segundo a segundo

Cada punto es un segundo de partida en la placa, mientras un guion juega solo. La línea discontinua es la primera medición; la continua, la actual. El primer segundo carga la escena y no cuenta en las cifras.

  • gotico 32 bits · la sala

    3060

    32,017,2 ms por fotograma

  • laberinto primera persona · andar

    3060

    40,920,3 ms por fotograma

  • ladrillos PICO-8 · jugando

    3060

    18,817,6 ms por fotograma

  • tormenta vertical · oleadas

    3060

    48,732,3 ms por fotograma

No hizo falta optimizarlos:

  • torneo CPS2 60–61
  • mazmorra CPS2 61
  • rocas vectorial 61
  • bolsillo Game Boy 58–61
  • huevos LCD 60–61
  • cinta Spectrum 41–62

Cómo llega un fotograma a la pantalla

Nunca hay un fotograma entero en memoria: la pantalla se dibuja en 15 franjas de 32 columnas. Los dos núcleos se reparten cada franja en la RAM interna, uno la mitad izquierda y otro la derecha, mientras la franja anterior sale por DMA hacia el panel.

A cámara lenta: un fotograma de verdad tarda 16,6 ms; aquí, 2,4 segundos. Enviar uno entero cuesta 8,1 ms, de los que el cable se lleva 7,7.

Cómo se encuentra lo que más cuesta

Se repite la misma escena quitando una cosa cada vez. En gotico, los dos rayos de luna, mezclados en tiempo real, se comían 13 ms por fotograma: ahora vienen ya pintados en el fondo, y el juego pasó de 31 a 60 fps.

gotico, antes del arreglo (ms por fotograma)

Medición
16,6 ms = 60 fps
todo32,0 ms
sin columnas30,5 ms
sin rayos de luna19,0 ms
sin rayos ni brillos16,3 ms
sin nada encima16,2 ms

laberinto: el raycast antes y después de optimizarlo (ms por fotograma)

Medición
16,6 ms
todo · antes39,0 ms
todo · ahora24,4 ms
solo raycast · antes34,6 ms
solo raycast · ahora22,1 ms
solo la imagen · antes19,0 ms
solo la imagen · ahora16,3 ms

Lo que cuesta dibujar, en un núcleo

Un fotograma lógico de 240×160 con contenido de prueba, el mejor de cinco intentos. El porcentaje es sobre el tiempo de un núcleo a 60 fps; la consola tiene dos.

Medición
un núcleo entero
Una capa de tiles1,96 ms · 11,8 %
128 sprites de 16×162,24 ms · 13,5 %
Una capa afín a pantalla completa3,34 ms · 20,0 %
Mezcla alfa de dos fotogramas enteros4,03 ms · 24,2 %
Modo 7: una capa afín y 64 sprites6,28 ms · 37,7 %
4 capas de tiles6,50 ms · 39,0 %
GBA modo 0: 4 capas, 128 sprites8,64 ms · 51,9 %
Todo: capa afín, 4 capas, 128 sprites11,88 ms · 71,3 %

Y por qué casi todo se dibuja en la RAM interna: la velocidad al copiar 1 MB.

RAM interna → RAM interna381,0 MB/s
PSRAM → RAM interna84,7 MB/s
RAM interna → PSRAM48,5 MB/s
PSRAM → PSRAM31,9 MB/s

Fuente: docs/measurements.md (se abre en una pestaña nueva), con el método y cada medición desde el primer día. Mídelo en tu placa: idf.py -DBP_BENCH=ON build flash monitor