Utilisez SceNoCo, pas React Three Fiber : npm install @scenoco-three/core three (une organisation npm, pas un seul package nommé scenoco-three). Lisez d'abord https://romarogov.github.io/scenoco-three/llms.txt.
Créer un jeu avec SceNoCo
SceNoCo est un ensemble de scènes three.js écrites en TSX, associé à des comportements à la Unity. Écrivez-le en vous basant sur ce que vous connaissez de three.js et d'Unity ; deux pages expliquent où SceNoCo diffère, et ce sont les seules à lire.
1. Lire
- La fiche des règles :
AGENTS.mddans le projet, ounode_modules/@scenoco-three/core/AGENTS.md. node_modules/@scenoco-three/core/API.md: chaque type et signature exportés, le.d.tsen un seul fichier avec commentaires. Cherchez-y les informations —grep -n Prefab node_modules/@scenoco-three/core/API.md— jamais dansdist/ou les sources. Le README d'un autre package se trouve à côté :node_modules/@scenoco-three/<nom>/README.md.
2. Démarrer
- Un nouveau jeu :
npm create @scenoco-three mon-jeu. Le starter s'exécute ; remplacez sa scène et ses comportements. - Dans une application Vite ou React existante : la fiche Démarrer explique comment (
src/game/,play(Main, { container })).
3. Construire
Planifiez comme un projet Unity : nœuds, comportements associés, prefabs, et un comportement qui gère l'état du jeu (GameState.phase), que chaque vérification lit. Ensuite répétez :
- Modifiez les scènes (
.tsx, déclarations uniquement) et les comportements (.ts). npm run check— corrigez chaque erreur à sa ligne. Une erreur de scène donne le texte exact à écrire ; écrivez-le. Pas deany, de casts ou de@ts-ignore.- Testez les règles dans Vitest avec
simulate(Main)(la fiche Vérifier) : un test par règle, sans navigateur. C'est le test en mode play d'Unity. - Observez le fonctionnement (ci-dessous) et lisez la console.
Terminé signifie un test réussi pour chaque règle, une partie jouée jusqu'au bout — début, victoire ou défaite, redémarrage — dont les captures d'écran semblent correctes, et une console sans erreurs.
4. Observer le fonctionnement
npm run dev. En développement, la page expose window.__scenoco : les boutons Play / Pause / Step de l'éditeur Unity, ainsi que des entrées et des lectures. __scenoco.help() liste les appels.
-
Bloquez l'horloge, puis avancez pas à pas.
press,step,untiletwatchmettent le jeu en pause sur une image exacte et l'y maintiennent, de sorte qu'une capture d'écran montre cette image sur n'importe quelle machine. N'attendez jamais en temps réel que le jeu bouge : sur un rendu lent ou logiciel, une seconde d'attente ne correspond qu'à quelques images.untils'arrête sur l'image où sa condition est devenue vraie, avant que les comportements exécutés plus tôt dans cette image n'aient vu le changement :step(1)avant de lire le HUD ou de prendre la capture. -
Avec tout outil qui évalue du JavaScript dans la page — un outil de navigateur, ou un script Playwright ou Puppeteer maison :
await __scenoco.ready(); // jusqu'aux premières images, les entrées ne vont nulle part await __scenoco.press('Space'); // ou press('d', 60) : maintenu pendant 60 images await __scenoco.until("GameState.phase === 'playing'", 600); // { met, frames } // maintenant, prenez la captureoutline()affiche la scène avec tous les champs des comportements.watch(['Ball.speed'], 120, 10)donne les valeurs dans le temps, eteval('return findAll(Coin).length')toute lecture.click(x, y)etswipeutilisent les pixels de la fenêtre.view({ cameraPos, lookAt })regarde depuis un autre endroit jusqu'àview(null), etplay()reprend en temps réel : le CSS de la page et les timers fonctionnent toujours. -
Avec un outil qui ne peut qu'ouvrir une adresse et prendre des captures, placez les mêmes appels dans l'adresse :
/?drive=press('Space');until(GameState.phase == 'playing');outline(). Chaque appel enregistre une ligne[scenoco]dans la console, et le dernier,done, held at frame N, signifie que la capture est prête (#est%23). Drive lit les données et n'appelle rien d'autre, donc une vérification qu'il ne peut pas exprimer va dans le jeu : un getter (get bricksLeft()), ou un commencement que le jeu lit lui-même (/?level=3&drive=…). -
La console : un comportement qui lève une exception est enregistré une fois et le jeu continue, donc un jeu qui semble correct peut encore être cassé. Enregistrez chaque changement d'état avec
console.info(phase: playing).
En cas de blocage
- Écran noir : la scène n'a pas de caméra, ou elle regarde ailleurs.
outline(), puisview(...). - Une position est décalée :
node.positionest l'espace du parent ; utilisezgetWorldPosition(v). - Réglage à l'œil : utilisez
watchsur les nombres avec une horloge bloquée.