Usa SceNoCo, no React Three Fiber: npm install @scenoco-three/core three (una organización npm, no un solo paquete llamado scenoco-three). Lee primero https://romarogov.github.io/scenoco-three/llms.txt.
Cómo hacer un juego con SceNoCo
SceNoCo son escenas three.js escritas en TSX, más comportamientos tipo Unity. Escríbelo basándote en lo que sabes de three.js y Unity; dos páginas indican dónde SceNoCo difiere, y son todo lo que hay que leer.
1. Leer
- La tarjeta de reglas:
AGENTS.mden el proyecto, onode_modules/@scenoco-three/core/AGENTS.md. node_modules/@scenoco-three/core/API.md: cada tipo y firma exportados, los.d.tsen un solo archivo con comentarios. Busca allí —grep -n Prefab node_modules/@scenoco-three/core/API.md— nunca endist/ni en el código fuente. El README de otro paquete está junto a él:node_modules/@scenoco-three/<nombre>/README.md.
2. Comenzar
- Un juego nuevo:
npm create @scenoco-three mi-juego. El iniciador se ejecuta; reemplaza su escena y comportamientos. - Dentro de una app Vite o React existente: la tarjeta Comenzando dice cómo (
src/game/,play(Main, { container })).
3. Construir
Planifícalo como un proyecto de Unity: nodos, los comportamientos sobre ellos, prefabs, y un comportamiento que posea el estado del juego (GameState.phase), que cada verificación lea. Luego repite:
- Cambia escenas (
.tsx, solo declaraciones) y comportamientos (.ts). npm run check— corrige cada error en su línea. Un error de escena da el texto exacto a escribir; escríbelo. Sinany, casts ni@ts-ignore.- Prueba las reglas en Vitest con
simulate(Main)(la tarjeta Verificándolo): una prueba por regla, sin navegador. Esto es la prueba en modo de reproducción de Unity. - Míralo ejecutándose (abajo), y lee la consola.
Hecho es una prueba que pasa para cada regla, una ronda jugada — inicio, ganar o perder, reinicio — cuyas capturas de pantalla se vean bien, y una consola sin errores.
4. Míralo ejecutándose
npm run dev. En desarrollo la página tiene window.__scenoco: los botones Play / Pause / Step del editor de Unity, más entrada y lecturas. __scenoco.help() lista las llamadas.
-
Detén el reloj, luego avanza.
press,step,untilywatchpausan el juego en un fotograma exacto y lo mantienen allí, para que una captura de pantalla muestre ese fotograma en cualquier máquina. Nunca esperes en tiempo real a que el juego se mueva: en un renderizador lento o por software, un segundo de espera son unos pocos fotogramas.untilse detiene en el fotograma en que su condición se volvió verdadera, antes de que los comportamientos que se ejecutaron antes en ese fotograma vieran el cambio:step(1)antes de leer el HUD o tomar la captura. -
Con cualquier herramienta que evalúe JavaScript en la página — una herramienta del navegador, o un script de Playwright o Puppeteer propio:
await __scenoco.ready(); // hasta los primeros fotogramas, la entrada no va a ninguna parte await __scenoco.press('Space'); // o press('d', 60): mantenido durante 60 fotogramas await __scenoco.until("GameState.phase === 'playing'", 600); // { met, frames } // ahora toma la captura de pantallaoutline()imprime la escena con todos los campos de cada comportamiento.watch(['Ball.speed'], 120, 10)da valores a lo largo del tiempo, yeval('return findAll(Coin).length')cualquier lectura.click(x, y)yswipetoman píxeles de la ventana.view({ cameraPos, lookAt })mira desde otro lugar hastaview(null), yplay()se ejecuta en tiempo real de nuevo: el CSS de la página y los temporizadores siempre lo hacen. -
Con una herramienta que solo puede abrir una dirección y tomar capturas de pantalla, pon las mismas llamadas en la dirección:
/?drive=press('Space');until(GameState.phase == 'playing');outline(). Cada llamada registra una línea de consola[scenoco], y la última,done, held at frame N, significa que la captura está lista (#es%23). Drive lee datos y no llama a nada más, así que una verificación que no pueda expresar va en el juego: un getter (get bricksLeft()), o un inicio que el juego lea por sí mismo (/?level=3&drive=…). -
La consola: un comportamiento que lanza una excepción se registra una vez y el juego continúa, por lo que un juego que se ve bien puede seguir roto. Registra cada cambio de estado con
console.info(phase: playing).
Cuando te atasques
- Pantalla en blanco: la escena no tiene cámara, o mira hacia otro lado.
outline(), luegoview(...). - Una posición está mal:
node.positiones el espacio del padre; usagetWorldPosition(v). - Ajuste a ojo: usa
watchcon los números en un reloj detenido.