SceNoCoを使用します(React Three Fiberではありません)。
npm install @scenoco-three/core three
(これは scenoco-three という単一のパッケージではなく、npm organizationです。)。
最初に https://romarogov.github.io/scenoco-three/llms.txt をお読みください。
SceNoCoでゲームを作る
SceNoCoは、TSXで記述するThree.jsシーンと、Unityのビヘイビアを組み合わせたものです。 Three.jsとUnityの知識を元に記述してください。SceNoCoが異なる点を説明するページは2つだけあり、それがすべてです。
1. 読む
- ルールカード: プロジェクト内の
AGENTS.md、またはnode_modules/@scenoco-three/core/AGENTS.md。 node_modules/@scenoco-three/core/API.md: すべての公開型とシグネチャを、コメント付きの単一の.d.tsファイルにまとめたもの。 ここで情報を検索してください —grep -n Prefab node_modules/@scenoco-three/core/API.md—dist/やソースコード内は決して検索しないでください。 他のパッケージのREADMEはその隣にあります:node_modules/@scenoco-three/<name>/README.md。
2. 開始する
- 新しいゲーム:
npm create @scenoco-three my-game。スターターが実行されます。そのシーンとビヘイビアを置き換えてください。 - 既存のViteまたはReactアプリ内: ルールカードの Starting セクションに方法が記載されています(
src/game/、play(Main, { container }))。
3. 構築する
Unityプロジェクトのように計画します:ノード、それらにアタッチするビヘイビア、プレハブ、そしてゲームの状態を所有する1つのビヘイビア(GameState.phase)を定義し、すべてのチェックがそれを読み取ります。その後、以下を繰り返します:
- 変更 シーン(
.tsx、宣言のみ)とビヘイビア(.ts)。 npm run check— 各行のエラーを修正します。シーンエラーは、記述すべき正確なテキストを表示します。その通りに記述してください。any、キャスト、@ts-ignoreは使用しないでください。- ルールをテスト Vitestで
simulate(Main)を使用します(ルールカードの Checking it セクション):ルールごとに1つのテスト、ブラウザは不要です。これはUnityのプレイモードテストです。 - 実行中の様子を確認(下記参照)、コンソールを確認します。
完了とは、すべてのルールに対するテストが合格し、ラウンド(開始、勝利または敗北、再開)を一通りプレイでき、スクリーンショットが正しく見え、コンソールにエラーがない状態です。
4. 実行中の様子を確認する
npm run dev。開発中、ページには window.__scenoco が用意されています。これはUnityエディタの再生/一時停止/ステップボタン、入力および読み取り機能です。__scenoco.help() で呼び出し可能な関数の一覧が表示されます。
-
クロックを停止し、ステップ実行する。
press、step、until、watchは、ゲームを正確なフレームで一時停止し、その状態を保持します。そのため、スクリーンショットはどのマシンでも同じフレームを表示します。ゲームを動かすために実時間待機することは絶対に避けてください。遅いレンダラーやソフトウェアレンダラーでは、1秒待っても数フレームしか進みません。untilは、条件がtrueになったフレームで停止します。これは、そのフレーム内でより早く実行されたビヘイビアが変更を認識する前の状態です。HUDを読み取ったりスクリーンショットを撮影する前にstep(1)を実行してください。 -
ページ内でJavaScriptを評価できる任意のツール(ブラウザツール、PlaywrightやPuppeteerのスクリプトなど)を使用する場合:
await __scenoco.ready(); // 最初のフレームまでは、入力はどこにも届きません await __scenoco.press('Space'); // または press('d', 60): 60フレーム間キーを押し続けます await __scenoco.until("GameState.phase === 'playing'", 600); // { met, frames } // ここでスクリーンショットを撮影outline()は、各ビヘイビアのフィールドを含むシーンを出力します。watch(['Ball.speed'], 120, 10)は時間経過に伴う値を表示し、eval('return findAll(Coin).length')は任意の読み取りを実行します。click(x, y)とswipeはウィンドウピクセルを取得します。view({ cameraPos, lookAt })はview(null)で元に戻るまで別の視点から表示し、play()は再び実時間で実行を再開します:ページのCSSとタイマーは常に動作します。 -
アドレスを開いてスクリーンショットを撮ることしかできないツールの場合、同じ呼び出しをアドレスに記述します:
/?drive=press('Space');until(GameState.phase == 'playing');outline()。各呼び出しは[scenoco]コンソール行をログに記録し、最後のdone, held at frame Nはスクリーンショットの準備ができたことを意味します(#は%23)。Driveはデータを読み取り、他の処理は呼び出さないため、表現できないチェックはゲーム自体に組み込みます(getterget bricksLeft()など)、またはゲーム自身が読み取る開始パラメータとして渡します(/?level=3&drive=…)。 -
コンソール: スローしたビヘイビアは1回ログに記録され、ゲームは続行されます。そのため、見た目が正しいゲームでも壊れている可能性があります。各状態変更は
console.infoでログに記録してください(phase: playing)。
問題が発生した場合
- 真っ黒な画面: シーンにカメラがないか、カメラが別の方向を向いています。
outline()を実行し、次にview(...)を実行してください。 - 位置がずれている:
node.positionは親空間での位置です。getWorldPosition(v)を使用してください。 - 目視での調整: クロックを停止した状態で
watchで数値を確認する代わりに、数値を確認してください。