godot-game-architecture について
Godot Game Architecture は、Godot プロジェクトのゲーム状態、シーン遷移、マネージャー、永続化の設計を支援するスキルです。各値に単一の管理者を割り当て、変更前にライフサイクルや保存・読み込みを確認する方針を示します。
主な機能
- 01定義・実行時・表示・スナップショット状態の分類
- 02ライフサイクルに応じた状態の所有者決定
- 03シーンとオートロードの責務に関する指針
- 04シーン遷移とオーバーレイの設計
- 05バージョン管理された保存境界
- 06ライフサイクルと永続化の検証
活用シーン
- 01状態をシーンとオートロードのどちらに置くか判断
- 02ゲーム遷移ごとのリセット動作を計画
- 03保存・読み込み・移行の境界を設計
- 04古い参照やシーンノードの残存を調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pbzona/ godot-skills --skill godot-game-architectureインストール後、Claude Code で/godot-game-architectureを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/managers-and-scene-flow.mdpersistence-boundaries.mdstate-and-data-ownership.md詳細
Godot ゲームアーキテクチャ
ゲームフローを満たす最も短いライフタイムにおいて、すべての状態に単一の権威ある所有者を割り当てます。
対象範囲
以下の場合にこのスキルを使用します。
- 状態をライフタイムで分類し、権威ある書き込み元を選ぶ。
- 静的な定義、ライブシミュレーション状態、プレゼンテーション、永続化されたスナップショットを分離する。
- コーディネーターをシーンとオートロードのどちらに配置するかを決める。
- マネージャーの責務と、公開する変更境界を定義する。
- メニュー、ゲームプレイ、結果、再読み込み、オーバーレイのシーンフローを調整する。
- 新規セッション、リセット、チェックポイント、保存、読み込み、マイグレーション、破損時の動作を設計する。
- シーン遷移時のノードの残留や古い参照の保持を防ぐ。
基本的なノード選択、シーンのインスタンス化、カスタムリソース構文、Input Map の設定、エディターの操作にはこのスキルを使用せず、基礎スキルを使用してください。SOLID、シグナルの仕組み、コマンド、プーリングを教える目的では使用せず、プログラミングパターンのスキルを使用してください。アーキテクチャではイベントやコンポーネントの境界を選択できますが、その実装の詳細はパターンのスキルが担当します。
設計前の調査
project.godotを見つけ、config/featuresを調べて Godot 4.x の正確な対象バージョンを確認します。[application]を読み、メインシーンを特定します。また、[autoload]を読み、プロセスのライフタイムにわたって存在するノードとその順序を把握します。- プロジェクトのシーン、スクリプト、リソース、データの配置を調べます。命名規則、フォルダー構成、型付け、依存関係の慣例を維持してください。
- 現在のすべてのシーン遷移とオーバーレイを追跡します。遷移を開始する要素、解放されるもの、存続するもの、次のシーンが想定するものを記録します。
- 状態の一覧を作成します。各値について、書き込み元、読み取り元、ライフタイム、リセット規則、定義元、永続化の有無を記録します。
- 共有フィールドへの直接書き込み、グローバル参照、
get_tree().root.add_child()、マネージャー参照、ユーザーファイルへのアクセス、起動時のシグナル発行を検索します。 - 基準となるフローを再現します。新規起動、新しいゲーム、シーン変更、リトライ、メニューへの復帰、該当する場合は保存と読み込みを確認します。
- スキーマや所有権を変更する前に、既存のテストと保存用フィクスチャを調べます。
既存の所有者とオートロードを評価する前に、新しいマネージャーを追加しないでください。
状態の分類
以下の4つの概念を分けて扱います。
- 定義データ: インスタンス間で共有される、アイテムのコストやユニットの基本速度などの作成時に定められた事実。多くの場合、リソースとして扱います。
- ランタイム状態: 現在の体力や発見済みの部屋など、このエンティティ、部屋、マッチ、セッションに固有の変更可能な事実。
- プレゼンテーション状態: 選択中のタブ、アニメーションの進行状況、表示中のツールチップなど、一時的なビューの詳細。
- スナップショットデータ: 永続化の境界を越える、バージョン管理されたプリミティブ値。
1つの共有リソースを、この4つすべてに使用しないでください。特に、ランタイムの進行状況を保存するために定義リソースを変更すると、すべての利用者に影響し、保存も複雑になります。
ライフタイムに基づく所有権の割り当て
最も近い安定した所有者を選びます。
- エンティティの状態は、そのエンティティまたは責務を限定したコンポーネントに属します。
- 部屋またはレベルの状態は、その部屋/レベルのコーディネーターに属します。
- マッチの状態は、マッチのルート、またはそれが所有するマッチモデルに属します。
- レベルシーンをまたぐランの状態は、これらの遷移後も存続するセッション所有者に属します。
- プロフィールの進行状況と設定は、明示的な永続化 API を備えたプロフィール/設定サービスに属します。
- UI は状態を表示しますが、ゲームプレイ状態の権威ある保存先にはしないでください。
各状態値につき、書き込み元は1つにします。他のシステムはメソッドを通じて変更を要求し、読み取りやイベントを通じて結果を確認します。すべてのシーンが直接編集する公開辞書は避けてください。
マネージャーのライフタイムを決める
状態をシーンとともに破棄する場合は、マネージャーをシーン内に配置します。レベルディレクター、エンカウントトラッカー、マッチの審判役は、通常ゲームプレイのルートの下に配置します。
次の条件を少なくとも1つ満たす場合に限り、オートロードを使用します。
- 現在のシーンを置き換えた後も、その機能が必要です。
- 複数の無関係なルートシーンで、プロセスのライフタイム全体にわたる同じサービスが必要です。
- シーンの置き換え自体を調整します。
- ライフタイムがそれらのシーンをまたぐと定義された、セッションまたはプロフィールの状態を保持します。
オートロードは、シーンの終了後もそのシーンに属する通常のノードを保持してはいけません。通常の状態、安定した ID、または再取得した参照を保存します。start_new_*、reset、restore メソッドを明示的に用意してください。プロセスのライフタイムは、リセット方針ではありません。
シーンフローを設計する
- 現在のシーンを置き換える権限を、1つのコーディネーターに持たせます。
- UI やアクター全体で文字列パスを繰り返すのではなく、エクスポートされた
PackedScene値または一元管理されたルートマップで遷移先を表します。 - 同じフレーム内に複数の入力や終了条件が発生したことで、遷移が重複しないようにします。
- 置き換えとオーバーレイを別の操作として扱います。相互に排他的なルートは置き換え、ポーズ、ダイアログ、読み込みのオーバーレイは、意図した所有者の下に追加します。
- ランタイムに作成したゲームプレイノードは現在のシーンの下に置き、シーンの置き換え時に解放されるようにします。
- 初期化に遷移先シーンのノードが必要な場合は、
SceneTree.scene_changedを待ちます。 - シーンの準備ができてから初期状態を取得します。後から登録したリスナーが受け取れない可能性のある、グローバルな起動イベントに依存してはいけません。
- 死亡、リトライ、次のレベル、メニューに戻る際に、実行状態を維持するのかリセットするのかを定義します。
永続化の境界を定義する
- ノード、Callable、シグナル接続、またはライブのリソース参照ではなく、スナップショットを保存します。
- ゲームオブジェクトを、安定した ID を持つプリミティブな辞書や配列に変換します。
- ユーザーデータは
user://の下に保存し、インポート済みのres://コンテンツには保存しません。 - スキーマのバージョンを含め、サポートする旧バージョンごとに、移行または拒否の方針を定義します。
- ライブ状態を変更する前に、型、範囲、ID、必須の関連性を検証します。
- まずクリーンなモデルに復元し、そのモデルをもとにシーンを構築または更新します。
- ディスク I/O とシリアル化はゲームプレイエンティティの外部で行います。
- 保存のタイミングと失敗時の動作を定義し、各サブシステムが個別に書き込まないようにします。
実装ワークフロー
- 影響を受ける状態とフローだけを対象に、所有関係のマップを作成します。
- 権限を持つ所有者の、範囲を絞った公開 API を定義します。
- 現在の動作を維持しながら、すべての変更をその所有者経由にします。
- ビューは最新のスナップショットで初期化し、その後の変更を監視するようにします。
- コーディネーターは管理対象のライフタイムに配置し、利便性のためにシーン内の状態をオートロードに昇格させないようにします。
- シーンの置き換えを一元管理し、すべてのルートについてリセットの意味を定義します。
- スナップショットの変換、検証、バージョン管理、保存は、別々の手順として追加します。
- すべての読み取り側が権限を持つ管理元を使うようになってから、不要になった重複状態を削除します。
- 正常なケースだけでなく、ライフサイクルと永続化のマトリックスをテストします。
検証
既存のプロジェクトチェックを実行し、該当する場合は次のケースを確認します。
- ユーザーデータがない状態での初回起動。
- メインシーンの直接実行と、設定されたエントリーシーンを介した通常の起動。
- 同じプロセスで前回の実行後に新しいゲームを開始する。
- メニュー、ゲームプレイ、結果、リトライ、次のレベルへの遷移を繰り返す。
- 同じフレーム内に2つの遷移リクエストが発生する。
- タイマー、await、または実行時に作成されたノードがアクティブな状態でシーンを終了する。
- 状態がすでに変化した後に UI を作成する場合でも、現在の値が表示される。
- クリーンなセッションに保存データを読み込む一連の往復。
- 保存データの欠落、切り詰め、不正形式、未知のバージョン、および一部のみ有効な状態。
- 作成時のコンテンツの名前が変更または削除された場合の安定 ID の解決。
- 実行状態が誤って保存されることなく、プロフィールや設定が永続化される。
- 数回ループした後のリモートシーンツリーとオブジェクト数。古いルートやシーンへの参照が残っていないこと。
検証した状態の所有者、リセットポリシー、遷移フロー、スキーマバージョンを報告します。
障害モード
- **すべてが自動読み込みになる:**利便性を優先して所有権が失われています。状態を、最も適切なシーンまたはモデルのライフタイムに移動します。
- **マネージャーが何でも入る箱になる:**無関係なシステムがフィールドを直接書き換えています。一貫性のある機能ごとに分割し、変更メソッドを公開します。
- **画面に入ると UI が古い:**過去のイベントを待っていました。初期化時に現在の状態を読み取り、その後の変更を購読します。
- **新しいゲームに古い値が残る:**プロセスのライフタイムを持つ状態に、明示的なリセット方法がありません。
- **シーン変更でアクターが残る:**ノードが
current_sceneより上位に追加されているか、長寿命のオブジェクトがノードを保持しています。 - **自動読み込みが存在しない HUD ノードを呼び出す:**グローバル初期化が遷移先シーンの準備完了前に実行されました。
scene_changedの後に処理するか、シーン側から状態を取得します。 - **2つの所有者が異なる状態を示す:**UI、マネージャー、エンティティ、またはリソースで状態が重複しています。唯一の権威となる所有者を選び、残りはそこから導出します。
- **共有定義が変更される:**テンプレートとして使用されている
.tresが、実行ごとの進行状況も保持しています。定義モデルと実行時モデルを分離します。 - **読み込みが一部だけ適用される:**検証と変更が交互に行われていました。まず完全な一時スナップショットを解析して検証します。
- **古いセーブデータでクラッシュする:**スキーマバージョン、マイグレーション、デフォルト値、または未知の ID に対するポリシーがありません。
- **遷移文字列がばらばらになる:**パスがボタンやアクターに分散しています。ルーティングを一元化するか、シーンリソースをエクスポートします。