mcpField
G
graph-world

graph-world

github.com/abpilot-cc開発037 回インストール9 週間前に更新
リポジトリ

graph-world について

graph-world は、GraphOS でゲームやアプリのロジックをノード中心のワールドモデルとして設計するスキルです。データ、システム、イベントの規約を定め、後続実装の前にグラフ検証を求めます。

主な機能

  1. 01World と階層化した Context による領域モデル化
  2. 02Variant ノードによる型付き実行時データの定義
  3. 03System でのライフサイクルロジックの構成
  4. 04プレゼンテーション層とロジック層のイベント命名分離
  5. 05シミュレーター状態と実行ログの確認

活用シーン

  1. 01新しいゲームやアプリのワールドモデル設計
  2. 02階層化した Context による領域データの整理
  3. 03ライフサイクルロジック実装前の型付き状態の設計
  4. 04シミュレーターのイベントフローのデバッグ

MCP 対応

graph-world は、グラフの検査とトランザクション API を提供する graph-management に依存します。GraphOS のグラフ操作とシミュレーターのエンドポイントを使いますが、入力には MCP サーバーやクライアントのインターフェースは記載されていません。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/abpilot-cc/graphos --skill graph-world

インストール後、Claude Code で/graph-worldを入力して読み込まれたか確認します。

同梱ファイルWorld.graph.json

詳細

GraphOS スキル:graph-world

ゲームやアプリケーション向けに、ノードファーストのアーキテクチャで GraphOS のワールドロジックを設計します。

このスキルは、グラフの検査とトランザクションの適用 API に graph-management を使用します。

グラフの検証が完了し、タスクが npm/TypeScript プロジェクトのブートストラップ、生成コードの統合、または System と EventSystem のランタイム実装に進む場合は、graph-world-ts を使用してください。

ノードの意味

  • World:モデル全体の単一のルートコンテキストです。World ノードの名前は World に固定されています。
  • Context:World または Context の下に置かれる、階層的なドメイン/データモデルノードです。Context はプレゼンテーション層ではなく、論理/データ層に属しますが、View 層が監視する必要のある状態を公開する必要があります。また、Context には組み込みのストレージセマンティクスがあるため、新しいインスタンスを作成する前に、既存の Context インスタンス/状態の再利用を優先してください。
  • Variant:World または Context の下に置かれる、型付き変数定義です。永続化/保存されるランタイムデータのデフォルトの設計対象です。
  • System:World または Context の下に置かれる、ライフサイクルロジックノードです。一時的なキャッシュや一時的な作業状態は、保存されるグラフデータとしてモデル化するのではなく、所有する System 内で扱ってください。
  • Event:World レベルのイベント定義です。イベント名にはレイヤー境界を明示する必要があります。On で始まる名前はプレゼンテーション層のイベントを表し、ペイロードは最小限にし、できればペイロードを持たせないでください。Logic で始まる名前は内部の論理層イベントを表し、論理層内でのワールド/ドメインのオーケストレーションにのみ使用します。
  • EventSystem:Event の下に置かれる、イベント駆動型のハンドラーです。

イベントの命名境界(必須)

  • プレゼンテーション層のイベントにのみ On プレフィックスを使用してください。
  • On... イベントは、View/プレゼンテーション層へ、またはそこから送信されるシグナルを表します。ペイロードは可能な限り小さくし、View が監視対象の Context データから状態を導出できる場合は、ペイロードを持たせないでください。
  • 内部の論理層イベントにのみ Logic プレフィックスを使用してください。
  • Logic... イベントはワールドモデル内でのドメイン/ランタイムの調整に使用し、プレゼンテーション向けのイベント名には使用しないでください。
  • 1 つのイベント名に、2 つのセマンティクスを混在させないでください。イベントが両方の関心事にまたがる場合は、論理イベントと独立したプレゼンテーションイベントに分割してください。

設定の境界(必須)

  • Graph では、ランタイムロジックの構造のみを定義します。対象は World/Context/Variant/System/Event/EventSystem と、それらの所有関係/トリガー関係です。
  • Graph で設定専用の構造をモデル化しないでください(たとえば、設定カタログ、環境プロファイル、調整テーブル、機能フラグマップ、プラットフォームビルド設定など)。
  • コード生成とランタイム実装では、設定構造をコード内で設計してください(たとえば、src/config.ts、型付き定数/インターフェイス、ローダー/アダプターなど)。それらは Graph トポロジーの外部に保ってください。
  • 実装の設定にのみ必要で、ドメインのランタイム状態ではないフィールドは、Graph の Variant ではなく、コード内の設定に保管してください。

使用する場面

  • 新しいゲーム/アプリのワールドモデルを一から設計する場合。
  • ビジネスドメインを入れ子になった Context ツリーに変換する必要がある場合。
  • ライフサイクルロジックを記述する前に、型付きデータ変数(Variant)が必要な場合。
  • イベント駆動型の初期化やランタイムフロー(たとえば、ゲームの起動)が必要な場合。

前提条件

  1. 最初に graph-management スキルを読み込み、使用してください。
  2. 変更を加える前に、利用可能なノードタイプと現在のグラフ状態を確認してください。
  3. 可能な場合は、設計ステップごとに一貫したトランザクションを 1 つ使用してください。
  4. ルートの命名制約を徹底してください。World ノードの name は 'World' に固定されています。

シミュレーターログの調査

ワールドプラグインのシミュレーターが利用可能で、静的なグラフ構造だけに頼らず、実際のランタイムイベントの流れを調査する必要がある場合に使用します。

  1. 対象の分岐またはシナリオが実行されるまで、シミュレーターを起動するか操作します。
  2. GraphOS ランタイムを通じて /api/world/log に問い合わせます。
  3. まずデフォルトのレスポンスを読み、現在のシミュレーター時刻までのすべてのログを確認します。
  4. 1 つの分岐を調査する場合は、startTime と endTime を指定してクエリを絞り込み、シミュレーション区間を切り分けます。
  5. /api/world/log が大きなペイロードを返す場合は、手作業で調査するのではなく、データを分析するスクリプトを生成します。

/api/world/log の想定される動作:

  • クエリパラメーターなし:シミュレーター時刻が <= current のログを返します。
  • startTime のみ:[startTime, current] のログを返します。
  • endTime のみ:(-∞, endTime] のログを返します。
  • startTime と endTime:[startTime, endTime] のログを返します。

/api/world/log のレスポンスが大きい場合:

  • ログレコードを解析、フィルタリング、グループ化、要約する小さな分析スクリプトを生成します。
  • 生のログ全体を出力するのではなく、スクリプトの出力を優先します。イベント数、時間範囲、対象の Context id、疑わしいエラーパターンなどの簡潔な要約を出力します。
  • グラフやランタイムを変更する前に、調査対象の分岐、Event、System、または Context の変更を正確に切り分けるためにスクリプトを使用します。
  • スクリプトの対象は現在のデバッグ対象に絞り、イベント名、ログタイプ、Context id、シミュレーション時間の範囲などで、フィルター条件を明示します。
  • 必要に応じて、/api/world/log のペイロード全体を手作業で繰り返し読むのではなく、スクリプトのフィルターを調整して調査を繰り返します。

シミュレーターログの調査は、次の用途に使用します:

  • 期待される spawn、change、despawn、event の各レコードが生成されたことを確認します。
  • System または EventSystem が、期待されるシミュレーション区間中に意図した Context データを変更したことを確認します。
  • グラフトポロジーや生成ロジックにパッチを適用する前に、ランタイムの不具合を切り分けます。

シミュレーター制御 API

これらのエンドポイントを使用すると、HTTP 経由でシミュレーターの実行を制御できます。3 つすべてが POST リクエストを受け付け、成功すると { ok: true } を返します。

  • GET /api/world/state — シミュレーターの現在の状態を取得します。{ duration, current, state, scale, fps } を返します。state は 'running' | 'paused' | 'loading' | 'stopped' のいずれかです。
  • POST /api/world/start — 時刻 0 からシミュレーターの時計を開始します。時間の進行とライフサイクルロジックの実行が始まります。
  • POST /api/world/pause — シミュレーターの時計を一時停止します。時間の進行は止まりますが、ログの記録は続行されます。
  • POST /api/world/resume — 一時停止した位置からシミュレーターの時計を再開します。
  • POST /api/world/reset — シミュレーターを初期状態にリセットし、すべてのランタイム状態とログを消去します。
  • POST /api/world/event — クライアントイベントをシミュレーターに送信します。リクエストボディは IEvent インターフェースに準拠する必要があります。シミュレーターは、接続済みのクライアントから発生したかのように、イベントシステムを通じてイベントをディスパッチします。
    interface IEvent {
        type: string;
        [key: string]: unknown;
    }
    
    例:{ "type": "MyEvent", ...additional fields as needed }

変更ルール(必須の順序)

これらのルールは、あらゆる変更ワークフローにおける厳格な制約です。

  1. データモデルとデータロジックの変更は、まず Graph に適用する必要があります。
    • 下流のコード/ドキュメント/タスクを作成する前に、Graph で必要な Context/Variant/System/Event/EventSystem の更新を完了します。
  2. Graph の変更直後に、Graph のロジックが閉ループになっていることを検証します。
    • Step 4 の閉ループチェックを実行し、すべての閉ループの観点で合格することを確認します。
  3. 閉ループ検証に合格した後に限り、ほかのタスクに進みます。
    • 閉ループ検証に失敗した場合は、まず Graph の修正に戻り、Graph 以外の作業を続行しないでください。
  4. Graph の変更に成功するたびに、変更記録を記載して gen/README.md を更新します。
    • 何を追加/変更/削除したか、またその理由を記録します。
    • 変更ログのセクションに追記し、以前の記録を上書きしないでください。
  5. Graph の変更に成功するたびに、現在のプロセス図と閉ループのチェックポイントをすべて含めて gen/GRAPH.md を更新します。
    • 図を実際の Step 0~6 のワークフローと一致させます。
    • チェックに失敗した場合に修正手順へ戻るようにし、図が閉ループを維持していることを検証します。

手順

Step 0: 現状を確認する
  1. get_available_node_types を呼び出し、ノードスキーマを検証します。
  2. get_graph_description を呼び出し、現在のルート、コンテキスト、未対応箇所を特定します。
  3. 既存の領域を拡張する場合は、対象ノードに対して get_graph_node を呼び出します。

完了チェック:

  • World ノードがすでに存在するかどうかを把握していること。
  • World のルートノードの name が正確に 'World' であることを確認していること。
  • 新しい Context/Variant/System/Event ノードをどこに接続すべきかを把握していること。
Step 1: データモデルと Variant を構築する

目標:まず構造モデルを作成し、次にそのデータに型を設定します。

  1. World ルートがちょうど 1 つ存在することを確認します。
    • ルートノード名は正確に World でなければなりません。名前を変更したり、別のルート名を作成したりしないでください。
  2. ドメインの境界に沿って Context ツリーを作成します。
    • 広い範囲から具体的な範囲へ:例:Gameplay -> Player -> Inventory。
    • 同階層の Context はまとまりを保ち、結合度を低くします。
  3. 関連する各 World/Context の下に Variant ノードを追加します。
    • 安定した意味のある名前を name に設定します。
    • type は string|float|integer|boolean|JSONSchema から設定します。
    • type=JSONSchema の場合は、必須フィールドを含む jsonSchema を指定します。
    • required は、実行時に真に必須のデータにのみ設定します。
  4. トランザクションを適用し、グラフを再読み込みします。

判断基準:

  • ドメインの境界や所有範囲をモデル化する場合は Context を使用します。
  • スコープ内の型付きデータをモデル化する場合、特に要件に保存/永続化が含まれる場合は Variant を使用します。
  • 構造化オブジェクトに限り JSONSchema を優先し、それ以外にはプリミティブ型を使用します。
  • データを Graph で定義された状態の一部として保持する必要がある場合は、Variant として設計します。
  • データが一時的なキャッシュ、中間計算結果、またはフレーム単位の作業セットにすぎない場合は、Variant を追加せず、関連する System 内に保持します。
  • データが設定のみを目的とする場合(ビルド/実行時の調整、環境の選択、機能フラグ、ジェネレーターのオプションなど)は、Graph で定義しないでください。生成/実装時にコード設定として定義します。
  • Graph の設計には論理/ドメインの状態のみを含め、プレゼンテーション層のウィジェット、スタイル、アニメーション、描画に関する事項は含めないでください。
  • View 層が監視/バインディングを通じてデータ変更に反応できるよう、Context とその Variant を設計します。
  • View が loading、selected、active、disabled、visible、phase、mode などの明示的な実行時状態に依存する場合は、プレゼンテーション層で暗黙のままにせず、それらを Context/Variant の論理状態としてモデル化します。

完了チェック:

  • すべての中核ドメインに、それを所有する Context があること。
  • 実行時に重要なデータすべてに、明示的な型を持つ Variant があること。
  • 明確な World/Context の親を持たない孤立した Variant がないこと。
ステップ 2:データモデルに基づいてシステムを定義する

目標:ライフサイクルの振る舞いを、既存のデータモデルのスコープに結び付けます。

  1. 振る舞いの単位ごとに、所有する World/Context の下に System を作成します。
  2. 実装コントラクトで必要となるライフサイクルのエントリーポイントを定義します。
    • spawn、despawn、update、change。
  3. 実装する各ライフサイクルメソッドについて、意図、トリガー、対象となるデータスコープを明確に記述します。
  4. システムの責務が、隣接する Context/Variant の所有関係と一致していることを確認します。
  5. トポロジーを適用して検証します。

判断基準:

  • System は、変更対象のデータを所有する最も近いスコープに配置します。
  • 初期化には Spawn、繰り返し実行されるロジックには Update、リアクティブな同期には Change、クリーンアップには Despawn を使用します。
  • 1 つのノードが関連のない責務にまたがる場合は、System を分割します。
  • System の実装には、プレゼンテーション層のロジック(レンダリング、スタイリング、アニメーション、UI オーケストレーション)を含めないでください。
  • System のロジックは、Context/Variant の状態とドメインルールだけを基準にしてください。
  • 一時的なキャッシュデータは、所有する System 内部に保持します。ドメインモデルの一部として保存する必要がない限り、キャッシュ専用の状態をグラフの Variant に昇格させないでください。

完了確認:

  • 実装した各ライフサイクルメソッドに対応する説明があります。
  • System が正しい World/Context のスコープに紐付けられています。
  • 明確なトリガーとデータ対象のないライフサイクルメソッドはありません。

実装への引き継ぎ:

  • ステップ 4 の合格後、graph-world-ts を使用して、具体的な TypeScript の System コード、起動時のブートストラップ配線、生成された型の統合、および src/app.ts への登録を実装します。
ステップ 3:イベントと EventSystem を定義する

目標:データとライフサイクルの基盤が安定した後、イベント駆動型のフローをモデル化します。

  1. World の下に、重要なドメインイベントを表す Event ノードを作成します。
    • 例:GameStarted、UserRegistered、SessionRestored。
  2. イベントペイロードが必要な場合は、各 Event の下に Variant ノードを追加します。
  3. 各 Event の下に、ハンドラーとなる EventSystem を作成します。
    • ハンドラーがどのように Context インスタンスを作成/初期化/更新するかを記述します。
  4. トランザクションを適用し、イベントからハンドラーまでがすべて揃っていることを検証します。

判断基準:

  • Context をまたぐ境界、または明示的なトリガーの境界には Event を作成します。
  • 処理をフレームごとの System ロジックから切り離す場合は、EventSystem を使用します。
  • ブートストラップのフローでは、明示的な起動/ブートイベントとハンドラーの組み合わせを優先します。
  • UI 向けのイベントでは、Event のデータモデルをできる限り小さく保ち、データが厳密に必要な場合を除き、ペイロードフィールドを定義しないことを優先します。
  • プレゼンテーション層のイベントには On プレフィックスを付け、可能な限りシグナル形式に保ちます。
  • 内部ロジック層のイベントには Logic プレフィックスを付け、View 向けの通知ではなく、ドメインのオーケストレーションに使用します。

完了確認:

  • 重要なトリガーすべてに Event があります。
  • すべての Event に、少なくとも 1 つの想定された EventSystem ハンドラーがあります(または、今後の作業として明示的に記録されています)。
  • イベントペイロードの Variant が、ハンドラーの入力要件に合致しています。

実装への引き継ぎ:

  • Graph のトリガーチェーンの検証後、graph-world-ts を使用して、具体的な TypeScript の EventSystem ハンドラーを実装し、./gen/World の型を再生成して、src/app.ts で登録します。
Step 4: 閉ループの検証と完了

目標:モデルがエンドツーエンドで閉ループになっていることを検証し、そうでない場合は不足しているつながりを補って再検証します。

  1. Step 1~3 の後に完全な検証を実行します。
    • get_graph_description を再実行し、想定されるトポロジーと実際のグラフを比較します。
    • 必要に応じて、主要なノード(World、コア Context、bootstrap Event)を get_graph_node で確認します。
  2. 閉ループの各側面を検証します。
    • 構造の閉鎖性:World ルートが 1 つで、孤立した Context/Variant/System/Event/EventSystem がないこと。
    • データの閉鎖性:重要なランタイムデータがすべて型付き Variant として存在し、所有スコープを持っていること。
    • 振る舞いの閉鎖性:実装された各ライフサイクルメソッドに、具体的な説明と対象データがあること。
    • トリガーの閉鎖性:bootstrap および主要なドメイントリガーが、Event → EventSystem → 対象 Context の更新につながっていること。
    • トランザクションの閉鎖性:すべての適用結果が成功しているか、再試行によって部分的な失敗が解消されていること。
  3. いずれかの閉鎖性チェックに失敗した場合、不足箇所を分類し、目的を絞った 1 回のトランザクションバッチで修正します。
    • 構造/データの不足 → Step 1 に戻ります。
    • ライフサイクルメソッドのカバレッジ不足 → Step 2 に戻ります。
    • イベントトリガー/ハンドラーチェーンの不足 → Step 3 に戻ります。
  4. すべての側面で合格するまで、閉ループの検証を再実行します。
  5. 最終検証の概要を作成します。
    • 追加したノード/エッジ。
    • 明示的な理由を添えた、残っている保留項目(ある場合)。
    • モデルが閉ループになっており、次のイテレーションに進む準備ができていることの確認。

完了チェック:

  • 閉ループの 5 つの側面すべてに合格していること。
  • 未解決の重大な不足が残っていないこと。
  • 最終的なグラフの説明が、意図したドメイン設計と一致していること。
Step 5: gen/README.md の変更履歴を更新する

目標:すべてのグラフ変更セッションを、人が読める記録として残します。

  1. gen/README.md を開く(または作成します)。
  2. 以下の形式で、## Change Log セクションの下に新しい変更記録を追加します。
### YYYY-MM-DD — <short summary>

**Added**
- <node type> `<node name>` under `<parent>`: <reason>

**Modified**
- <node type> `<node name>`: <what changed and why>

**Removed**
- <node type> `<node name>`: <reason>

**Notes**
- <any closure gaps deferred, design decisions, or follow-up items>
  1. 以前の記録を上書きしないでください。必ず追記します。
  2. 各エントリーは簡潔にします(ノードの変更ごとに 1 行で十分です)。

完了チェック:

  • gen/README.md が存在し、このセッションの最新の変更記録が含まれていること。
  • 追加/変更/削除したすべてのノードが記載されていること。
  • 保留項目または既知の不足が記載されていること。
Step 6: gen/GRAPH.md の全体フロー図を更新する

目標:現在のワークフローと閉ループを反映した、実行可能なプロセス図を維持します。

  1. gen/GRAPH.md を開く(または作成します)。
  2. エンドツーエンドのプロセスを示す、完全な Mermaid フローチャートを 1 つ維持します。
    • Step 0 から Step 6 までを含めます。
    • 閉ループの各側面と、チェックに失敗した場合の再試行ループを含めます。
  3. グラフ変更セッションのたびに、ステップ、ゲート、または再試行経路に変更があれば図を更新します。
  4. 図の閉ループとしての正しさを検証します。
    • 閉ループのチェック/ゲートに失敗した場合、正しい修正ステップに戻ること。
    • 成功経路が最終検証の概要で終了すること。

完了チェック:

  • gen/GRAPH.md が存在し、最新の完全なフローチャートを含んでいること。
  • フローチャートに、すべての有効なステップ(0~6)と再試行分岐が含まれていること。
  • 図の閉ループが検証済みで、成功/失敗経路に途切れがなく、戻りエッジの欠落がないこと。

品質ゲート(最終レビュー)

  1. 構造ゲート:World ルートがちょうど 1 つで、その name が正確に 'World' であり、Context ツリーに一貫性があること。
  2. 型ゲート:Variant が正しく型付けされ、JSONSchema ノードに有効なスキーマテキストが含まれていること。
  3. 所有権ゲート:System と Variant が、それらのデータを所有するスコープに紐付いていること。
  4. イベントゲート:Event/EventSystem のペアが、bootstrap と主要なドメイントリガーをカバーしていること。
  5. 検証ゲート:各適用後に get_graph_description を再実行し、想定されるノード/エッジの差分を確認すること。
  6. 図ゲート:gen/GRAPH.md が更新され、現在の閉ループワークフローを反映していること。
  7. 設定境界ゲート:グラフに設定専用の構造が含まれていないこと。設定設計は生成コード/ランタイムコードで実装されていること。

推奨するプロンプト入力

  • 「プレイヤー、マップ、戦闘、ブートストラップイベントのフローを備えたローグライクゲームの世界を設計してください。」
  • 「カタログ、注文、決済のコンテキストと、イベント駆動型の注文作成を備えた E コマースのワールドモデルを構築してください。」
  • 「デバイスのコンテキスト、ライフサイクルシステム、デバイス接続イベントの処理を備えたスマートホームアプリのモデルを作成してください。」

参考例

skills/graph-world/World.graph.json は、Merge Chicken タワーディフェンスゲームの完全な実例グラフです。新しいワールドを設計する際の具体的な参考資料として使用してください。

構造の概要
World
└── Game (Context)          — shared game data
    ├── time (float)        — game time (seconds)
    ├── gold (integer)      — gold coins
    ├── wave (JSONSchema)   — current enemy wave {value, state, start_time}
    ├── egg (JSONSchema)    — egg cooldown config {time, cooldown, ...}
    ├── buy (JSONSchema)    — buy-chicken config {gold, increaseGold, ...}
    ├── heal (JSONSchema)   — heal config {gold, value}
    ├── health (JSONSchema) — global game health {value, max}
    ├── grid (JSONSchema)   — map grid {cols, rows, cell_size}
    ├── reward (JSONSchema) — claim-reward state
    ├── status (string)     — game status: none/running/paused/failed/success
    ├── Ally (Context)      — allied units (chickens)
    │   ├── level (integer)
    │   ├── attack (JSONSchema)  — {damage, speed, radius}
    │   ├── skin (string)
    │   ├── pos (JSONSchema)     — grid integer position {x, y}
    │   ├── ally_gold (Variant)  — chicken gold-production config
    │   ├── AllyAttackSystem     — launch attacks and shoot bullets based on attack data
    │   └── AllyGoldSystem       — periodically reward gold; higher level yields more gold
    ├── Enemy (Context)     — enemy units (dogs)
    │   ├── level, attack, health, move (JSONSchema)
    │   ├── skin (string), state (string: idle/walk/attack)
    │   ├── pos (JSONSchema)     — world float position {x, y}
    │   └── EnemyMoveSystem      — movement + attack-range check + self-destruct logic
    ├── Bullet (Context)    — bullets
    │   ├── damage, speed, max_count, radius (float/integer)
    │   ├── pos, dst (JSONSchema) — world float position
    │   ├── skin (integer)
    │   └── BulletMoveSystem     — bullet movement + enemy collision + attack logic
    ├── WaveSystem               — enemy wave spawn scheduling
    └── GameSystem               — initialize Game singleton, config-driven

Events (under World):
  Merge            → MergeEventSystem           — move / swap / merge chickens
  Egg              → EggEventSystem             — spawn chicken (free)
  Buy              → BuyEventSystem             — buy chicken (costs gold)
  Heal             → HealEventSystem            — restore game health
  IncreaseHealth   → IncreaseHealthEventSystem  — permanently increase max health
  Toast            → (tag, message)             — notification message
  Pause            → PauseEventSystem           — pause game
  Resume           → ResumeEventSystem          — resume game
  Reset            → ResetEventSystem           — restart after defeat (clear enemies + restore 50% health)
  ClaimReward      → ClaimRewardEventSystem     — claim stage-clear reward (multiplier supported)
この例の主な設計パターン
  1. 構造化データには JSONSchema を使用:フィールドが関連するサブフィールド(例:attack = {damage, speed, radius})をまとめる場合は、JSONSchema バリアント型を使用してください。スカラー値にはプリミティブ型(float、integer、string)を使用してください。
  2. 設定駆動型システム:GameSystem はシングルトンの Game コンテキストを初期化し、設定可能なすべてのパラメーター(コスト、クールダウン、スケーリング)を Variant フィールドから読み込みます。値をハードコードすることはありません。
  3. シングルトンコンテキストへのアクセス:システムと EventSystem は、子の位置を基準に検索するのではなく、固定 ID(getGameById('id'))で常に Game コンテキストを取得します。
  4. イベントペイロードの最小化:Merge のようなイベントには、必要最小限のペイロード(ally_id、dst)だけを含めます。ハンドラーは残りの状態を Context から取得します。
  5. システムキャッシュ内の一時的な状態:フレーム単位の作業セット(弾丸と敵の衝突候補、フレームごとの移動先など)は、グラフの Variant ではなく、System のクロージャースコープに保持します。
  6. ウェーブの難易度スケーリング:WaveSystem は wave.value を読み取り、敵の数とステータスをスケーリングします。すべてのスケーリングパラメーターは設定可能な Variant であり、埋め込み定数ではありません。
  7. リセットフロー:ResetEventSystem は Reset イベントを処理し、すべての Enemy および Bullet コンテキストをデスポーンさせ、設定可能な割合で体力を回復し、待機時間の後にウェーブのスポーンを再度開始します。

実行に関する注意事項

  • apply_graph_transaction を使用した、原子的な変更バッチを優先してください。
  • 一部のみ成功した場合は、errors を確認し、失敗したインテントだけを再試行してください。
  • 反復的に進化させる際も、ノード ID を安定して維持してください。

完全なプロセス図

flowchart TD
   A[Start: load graph-world skill] --> B[Preconditions\nload graph-management\nread node types + graph state]
   B --> C[Step 0\nRead Current State]
   C --> D[Step 1\nBuild Context tree + Variants]
   D --> E{Step 1 complete?\nno orphan data\nall key variants typed}
   E -- No --> D
   E -- Yes --> F[Step 2\nDefine Systems]
   F --> G{Step 2 complete?\nlifecycle methods + intent docs\nownership aligned}
   G -- No --> F
   G -- Yes --> H[Step 3\nDefine Events + EventSystems]
   H --> I{Step 3 complete?\ncritical events covered\nhandler chain defined}
   I -- No --> H
   I -- Yes --> J[Step 4\nClosed-Loop Validation]

   J --> K{Structure closure?\n(single World, no orphans)}
   K -- No --> D
   K -- Yes --> L{Data closure?\n(typed variants + owner scope)}
   L -- No --> D
   L -- Yes --> M{Behavior closure?\n(system timing -> descriptions -> data target)}
   M -- No --> F
   M -- Yes --> N{Trigger closure?\n(Event -> EventSystem -> Context update)}
   N -- No --> H
   N -- Yes --> O{Transaction closure?\n(apply success/retry resolved)}
   O -- No --> P[Inspect errors\nretry failed intent only]
   P --> J
   O -- Yes --> Q[Quality Gates Final Review]
   Q --> R{All gates passed?}
   R -- No --> J
   R -- Yes --> T[Step 5\nUpdate gen/README.md change log]
   T --> U[Step 6\nUpdate gen/GRAPH.md full flowchart\nand verify diagram closed-loop]
   U --> S[Output final verification summary\nClosed-loop model complete]

コメント