godot-composition-apps について
Control、EditorPlugin、ツールウィンドウ向けのGodotアプリ・UI設計スキルです。Orchestratorがコンポーネントを調整し、上方向のシグナルと下方向の呼び出しで結合を抑えます。
主な機能
- 01Orchestratorとコンポーネントの構成パターン
- 02上方向のシグナルと下方向の呼び出し
- 03型付き依存性注入とライフサイクル
- 04ロジックとビジュアルの同期
- 05UI状態向けの永続化コンポーネント
活用シーン
- 01設定パネルやフォームのロジックを整理
- 02EditorPluginのツールウィンドウを構築
- 03再利用可能で文脈に依存しないコンポーネントを分離
- 04UIやツールの状態を保存
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-composition-appsインストール後、Claude Code で/godot-composition-appsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/app-orchestrator-examples.mdmigration-notes.mdresources/auth_component.gdtheme_manager.gdscripts/clipboard_copier.gdcomp_ability_sequencer.gdcomp_base_component.gdcomp_data_driven_config.gdcomp_dependency_injector.gdcomp_health_component.gdcomp_hitbox_component.gdcomp_logic_visual_syncer.gdcomp_orchestrator_base.gdcomp_persistence_component.gdcomp_rock_test_boilerplate.gd詳細
Godot のコンポジションとアーキテクチャ(アプリと UI)
判断ゲート — アプリかゲームプレイエンティティか
| ルートノード/タスク | 振り分け先 |
|---|---|
| Control、EditorPlugin、ツールウィンドウ、設定ドック、フォーム UI | ここに留まる — オーケストレーター+コンポーネント |
| Player、Enemy、Weapon、Hitbox、ゲームプレイ用 CharacterBody | godot-composition — このスキルの対象外 |
アプリ専用ゲート: ノードがゲームプレイアクター(Player/Enemy/Weapon/Hitbox)の場合は、godot-composition を使用してください。このスキルは Control/EditorPlugin/ツールのコンポジションを担当します。
基本理念
リトマス試験(岩テスト)
スクリプトを書く前に、次のように自問してください。「このスクリプトを文字どおり岩にアタッチしても、機能するだろうか?」
- 合格: 岩にアタッチした
AuthComponentによって、その岩がログインできます。(コンテキストに依存しない) - 不合格: 岩にアタッチした
LoginFormスクリプトが、岩には存在しないテキストフィールドを取得しようとします。(密結合)
必須: 新しいコンポーネントは comp_rock_test_boilerplate.gd で検証してください。
バックパックモデル(Has-A > Is-A)
ルートノードは空のバックパックとして扱ってください。
- 誤り:
SubmitButtonがAnimatedButtonを継承し、AnimatedButtonがBaseButtonを継承します。 - 正しい: ルートノードは
AnimationComponentを HAS-A で持ち、NetworkRequestComponentを HAS-A で持ちます。
権限の階層(通信ルール)
| 方向 | 送信元 → 送信先 | 方法 | 理由 |
|---|---|---|---|
| 下方向 | オーケストレーター → コンポーネント | 関数呼び出し | マネージャーがワーカーを管理します。 |
| 上方向 | コンポーネント → オーケストレーター | シグナル | ワーカーは状況を把握しません。 |
| 横方向 | コンポーネント A ↔ コンポーネント B | 禁止 | 兄弟コンポーネント同士が直接やり取りすることはありません。 |
横方向のやり取りの解決方法: コンポーネント A がオーケストレーターにシグナルを送信し、オーケストレーターがコンポーネント B を呼び出します。
利用可能なスクリプト
必須:パターンを実装する前に、対応するスクリプトを読んでください。オーケストレーターの配線をインラインで独自に作り直さないでください。
comp_rock_test_boilerplate.gd
最初に必ず読むこと — アタッチ候補を文字どおりの岩に取り付けるハーネスです。密結合されたコンポーネントを早期に検出し、失敗させます。
comp_orchestrator_base.gd
アプリ/UI のルートを作成する際は必須 — シグナルを上方向に送り、呼び出しを下方向に行う配線の骨組みです(ビジネスロジックの計算は 0%)。
comp_logic_visual_syncer.gd
VLS には必須 — ロジックが state_changed を発行し、ロジックが AnimationPlayer/Theme を認識しなくても、ビジュアル/アニメーションが反応します。
comp_base_component.gd
アプリのワーカー向けに、共通のコンポーネントライフサイクルと依存関係の検証を提供します。
comp_dependency_injector.gd
型付きエクスポート/レジストリ注入により、オーケストレーターが壊れやすい $ パスに依存せずに済むようにします。
clipboard_copier.gd
コンテキストに依存しないクリップボードワーカーです。オーケストレーターのトースト通知パターンと組み合わせます(参考資料を参照)。
comp_data_driven_config.gd
ツール設定とフォームのデフォルト値に対応する、リソースベースの設定です。
comp_persistence_component.gd
保存可能な UI/ツールの状態には必須 — ビジュアルに I/O を持ち込まずに、Saveable グループと get_save_data() を登録します。
comp_ability_sequencer.gd
ウィザードのページやエクスポートパイプラインなどの複数ステップから成る順序付きツールワークフローを、子ステップとして構成します。
comp_health_component.gd / comp_hitbox_component.gd
アプリ/ツールがエンティティをシミュレートする場合に限り使用してください。実際のゲームには godot-composition を推奨します。
オーケストレーターパターン
ルートスクリプト(LoginScreen.gd、UserProfile.gd、EditorPlugin のドックルート)はオーケストレーターです。
- 数学/ロジック:0% · 状態の配線:100%
- 役割:コンポーネントのシグナルをリッスン → 他のコンポーネントメソッドを呼び出す
必須: comp_orchestrator_base.gd のパターンを拡張してください。
| 概念 | アプリ/UI の例 |
|---|---|
| オーケストレーター | UserProfile.gd / Editor ドックルート |
| ロジックコンポーネント | AuthValidator |
| VLS | comp_logic_visual_syncer.gd 経由の AuthVisualSyncer |
| テーマの所有権 | テーマ専用コンポーネント — フォームのロジック内では決して変更しない |
| フォーカスの所有権 | オーケストレーターが Control のフォーカスを設定/解除する。コンポーネントが兄弟のフォーカスを奪うことはない |
実装基準
- 型安全性 — コンポーネントには
class_nameを指定し、中核アーキテクチャで型指定を省略しないでください。 - 依存性注入 —
@export var auth: AuthComponent(インスペクター/%UniqueNames)。コンポーネントに対してget_node("Path/To/Child")を決して使用しないでください。 - ステートレスなワーカー — オーケストレーターは関数にデータを渡します。コンポーネントが兄弟の Control を調べることはありません。
禁止事項(エキスパート向けアーキテクチャルール)
階層と依存関係
- データを取得するために get_parent() を決して使用しないでください —
@exportまたは関数の引数で注入します。 - 横方向に呼び出さないでください — シグナルを上位に送り、オーケストレーターが下位を呼び出します。
- 壊れやすい Node パスを決して使用しないでください —
@export/%を優先します。
ロジックと状態
- オーケストレーターにビジネスロジックを決して入れないでください —
_on_signalの委譲処理だけにします。 - 個々のコンポーネントにグローバル状態を決して保存しないでください — 共有 Context Resource または Autoload を使用します。
- コンポーネントの親が特定の型であると決めつけないでください — Rock Test で失敗します。
仕上げとオーケストレーション
- シグナルのクリーンアップを決して省略しないでください — 終了時に切断するか、適切な場合は CONNECT_ONE_SHOT を使用します。
- ロジックに Visuals を決して認識させないでください — シグナルを発行し、VLS / オーケストレーターがアニメーションを再生してテーマを適用します。
壊れやすいアプリのワークフロー:保存可能な要素とテーマの所有権
フォームの Control 内に保存 I/O やテーマの変更を入れないでください。コンポーネントを経由させます。
- オーケストレーター(または専用の Saveable 子ノード)に comp_persistence_component.gd を必ず追加します —
add_to_group("Saveable")とget_save_data()を使用します。 - テーマ/StyleBox の変更はテーマコンポーネント(theme_manager.gd)に任せ、ロジックが成功/失敗したというシグナルの後、オーケストレーターが下位に呼び出します。
- フォーカス:ロジックが Control に依存しないよう、検証に失敗した後の
grab_focus()はオーケストレーターが管理します。
# settings_dock_orchestrator.gd (pattern — wire via @export, not $)
extends Control
@export var persistence: CompPersistenceComponent
@export var theme_mgr: Node # theme_manager.gd API
@export var form_logic: Node
func _ready() -> void:
form_logic.settings_valid.connect(_on_settings_valid)
form_logic.settings_invalid.connect(_on_settings_invalid)
func _on_settings_valid(payload: Dictionary) -> void:
theme_mgr.apply_user_theme(payload.get("theme_id"))
# Save systems collect via Saveable group — persistence component stays dumb
func _on_settings_invalid(field: StringName) -> void:
# Orchestrator owns focus; logic never touches sibling LineEdits
var target := get_node_or_null("%" + String(field))
if target is Control:
target.grab_focus()
エキスパート向けコンポジションパターン(アプリ)
1. アプリレベルのサービスロケーター
多数の Autoload Node の代わりに、軽量な非 Node サービス(Auth、Config)には Engine.register_singleton() を優先してください [6]。
2. ビジュアル・ロジック・シンカー(VLS)
comp_logic_visual_syncer.gd を必ず使用してください — ロジックから AnimationPlayer.play() を呼び出すことはありません。
3. O(1) コンポーネントレジストリ
ダッシュボードモジュールにはオーケストレーターの Dictionary レジストリを使用します — 横方向の呼び出しは禁止です。レジストリはオーケストレーター内だけで使用する検索手段です。
クリップボード/共有オーケストレーターの例とサービスロケーターの詳細については、app-orchestrator-examples.md を必ず参照してください。comp_orchestrator_base.gd で画面の要件を満たせる場合は、読み込まないでください。
参考資料
段階的開示:特定の API を調べる場合にのみ公式ドキュメントのリンクを開いてください。関連するスキルは、隣接する分野に処理を委ねる場合に読み込みます。関連するすべての資料を事前に読み込まないでください。
公式ドキュメント
- シーンの構成 — シグナルを上方向に、呼び出しを下方向に流す所有権の基本パターンです。オーケストレーターがコンポーネント同士を結び付け、兄弟間の結合を避けられます。
- すべてにノードを使うのを避けるべき理由と方法 — 純粋なデータやロジックサービスにはリソース/RefCountedを使い、コンポーネントを軽量で徹底的にテスト可能な状態に保ちます。
- Godotのインターフェース — ダックタイピングによるメソッド契約(
has_method)を使うことで、深い継承ツリーを作らずにコンポジションを実現できます。 - Godotのクラスとは? — 再利用可能な振る舞いには、従来のIs-A階層よりもシーンコンポジション(Has-A)をGodotが重視する理由を説明します。
- シグナルの使用 — コンポーネントからオーケストレーターへの上方向のイベント通知により、ワーカーが親や兄弟を参照せずに済みます。
- GDScriptのエクスポート — 型付きの
@exportによる依存性注入を使い、インスペクターで脆弱なget_nodeパスを置き換えます。 - シーン固有ノード —
%UniqueNameを使うことで、オーケストレーター内のControl/Buttonを、文字列パスに依存せず接続できます。 - リソース — データ駆動の
.tres設定により、値をロジックコンポーネントの外部に保持できます。 - グループ — 一括登録(例:Saveable/Components)を使うと、兄弟への直接参照なしでオーケストレーターのレジストリを構成できます。
- 自動読み込みと通常のノードの比較 — アプリ/UIのコンポジションでは、グローバルなAutoloadよりシーンローカルなオーケストレーターが適している場合を説明します。
- シングルトン(Autoload) — アプリ全体で共有するロケーターが正当化される場合に、シーンをまたぐサービスを安全に登録する方法を説明します。
- ゲームの保存 — モジュール式の保存可能なコンポーネントに適用しやすい永続化パターンを紹介します。
関連スキル
前提条件
- godot-project-foundations — オーケストレーターやコンポーネントが組み込まれるプロジェクト構成、Autoloadの登録、シーンの所有権について説明します。
- godot-gdscript-mastery — 依存性注入と徹底的にテスト可能なコンポーネントに必要な、型付きエクスポート、シグナル、
class_nameの習熟を扱います。 - godot-composition — Has-Aコンポーネントモデルの基礎(ゲーム向けの兄弟スキル)です。このスキルでは、同じルールをアプリ/ツール/UI向けに特化して扱います。
補完スキル
- godot-signal-architecture — Orchestrator が上位への接続に使用するフラグ、ゴーストのクリーンアップ、EventBus パターンを接続します。
- godot-autoload-architecture — シーンローカルの状態ではなく、薄いグローバルサービスが必要な場合の起動順序と所有権について説明します。
- godot-resource-data-patterns — データ駆動型コンポーネントにデータを提供するカスタム Resource と、ホットスワップ可能な
.tres設定について説明します。 - godot-ui-containers — 意図を上位へ通知し、Orchestrator がレイアウトを操作する Control ツリーについて説明します。
- godot-ui-theming — VLS パターンでは、テーマ/ビジュアルの同期処理を認証/フォームのロジックから分離します。
- godot-scene-management — シーンの切り替え時は、横方向の兄弟リンクを使わずにエクスポートを再注入し、Orchestrator の配線を再接続する必要があります。
- godot-testing-patterns — コンポーネントがコンテキストに依存しないことを証明する Rock テストとシグナルスパイについて説明します。
下流/利用側
- godot-save-load-systems — モジュール式のアプリ状態管理に、Saveable グループの永続化コンポーネントを利用します。
- godot-ability-system — 継承ツリーを使わず、Orchestrator が順序を制御する子コンポーネントとして Ability ノードを扱います。
- godot-state-machine-advanced — 状態ノードをロジック/ビジュアル同期処理と並べて構成します。FSM が遷移を管理し、兄弟間のやり取りには介入しません。
マスター
- godot-master — ライブラリのルーターおよびミラーされたモジュールのエントリです。複数領域にまたがるアーキテクチャ上の課題を担当する Domain Skill を特定する際に参照してください。