godot-signal-architecture について
Godot 開発者向けに、ノード階層、シーン間システム、非同期処理でのシグナル設計を案内するスキルです。型付き接続や、通知は上位へ、呼び出しは下位へという方針、接続の整理とデバッグを扱います。
主な機能
- 01シグナルで上位へ通知しメソッドで下位を呼ぶ構成
- 02型付きシグナルと Callable のバインド
- 03グローバルイベントバスのルーティング
- 04非同期シグナルの連続処理
- 05動的接続の解除とデバッグ
活用シーン
- 01子ノードの状態変化を親へ通知
- 02シーン間システムでイベントを伝達
- 03ロード、フェード、生成などの非同期処理の連続実行
- 04監視対象の切り替えと残存接続の診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-signal-architectureインストール後、Claude Code で/godot-signal-architectureを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/implementation-patterns.mdmigration-notes.mdscripts/await_signal_sequencing.gdcallable_bind_context.gdcomplex_signal_sequencer.gddisconnect_ghost_signals.gdglobal_event_bus.gdglobal_signal_bus_router.gdone_shot_deferred_connections.gdsafe_dynamic_connections.gdsignal_debugger.gdsignal_spy.gdsignal_up_call_down_pattern.gdtrack_signal_emitter_source.gdunbind_unwanted_args.gd詳細
シグナル設計で絶対に避けること
- 従来の文字列ベースの
Object.connect()は絶対に使用しないでください — タイプミスがあっても、エラーが通知されずに失敗します。コンパイル時に検証されるよう、必ずsignal.connect(_callback)を使用してください。 - シグナルをトップダウンの動作指示に絶対に使用しないでください — シグナルは過去形のイベント(例:「死亡した」)です。命令(例:「倒す」)には直接メソッド呼び出しを使用してください。
- 同じ Callable にシグナルを二重に接続しないでください — 接続を積み重ねるために
Object.CONNECT_REFERENCE_COUNTEDフラグを使用する場合を除き、実行時にERR_INVALID_PARAMETERが発生します。 - ローカルデータに Global Signal Bus を絶対に使用しないでください — グローバル状態を汚染し、デバッグが難しくなります。シーン固有のロジックにはローカル接続を使用してください。
- コールバックがシグナルのすべての引数を受け取る必要があると絶対に思い込まないでください —
unbind()を使って不要なパラメーターを取り除き、API をすっきり保ちましょう。 - 循環するシグナル依存関係を絶対に作らないでください — A がシグナルを送信し、B が A にシグナルを送り返す場合は、メディエーター(親または AutoLoad)を使ってループを解消してください。
- シグナルの型指定を絶対に省略しないでください — 型のない
signal movedではエディターのサポートが不足します。必ずsignal moved(dir: Vector2)のように指定してください。 - 動的シグナルの接続解除を絶対に忘れないでください — 残った接続によって「null インスタンスに対する呼び出し」エラーが発生します。
_exit_tree()または追跡対象の変更時に接続を解除してください(disconnect_ghost_signals.gd)。 - 発信元に即時の副作用をもたらすシグナルを絶対に発行しないでください —
died.emit()がqueue_free()を呼び出すと、リスナーが応答できない場合があります。先にシグナルを発行してください。 - 高頻度データストリームにシグナルを絶対に使用しないでください — 1 秒あたり 1000 件以上のシグナルを送信すると(パーティクルごとの更新など)、非効率です。共有配列またはダイレクトバッファーを使用してください。
シグナルは上へ、呼び出しは下へ
- 子から親へ: 過去形のシグナル(
health_changed、died)。 - 親から子へ: 直接呼び出し/プロパティ(
apply_damage、play_anim)。 - 兄弟間: 親のメディエーター、または適切に範囲を限定した Autoload バスを使用します。兄弟へのハード参照は使用しないでください。
シグナルを使用する場面: UI の押下、死亡 → ゲームオーバー、戦利品 → インベントリ、シーンをまたぐバスイベント。 直接呼び出しを使用する場面: 親から子への指示、ローカルプロパティへのアクセス。
判断ツリー:接続箇所の選び方
| スコープ | パターン | 必須スクリプト |
|---|---|---|
| 子から親/UI への通知 | 親の _ready 内でローカルに signal.connect | signal_up_call_down_pattern.gd |
| 親による子の統括 | 下方向へのメソッド呼び出し(シグナルではない) | 同上 |
| シーン間/システム間(実績、セーブ) | Autoload バス | global_signal_bus_router.gd / global_event_bus.gd |
| 直線的な非同期ステップ(読み込み → フェード → スポーン) | await によるシグナルシーケンス | await_signal_sequencing.gd / complex_signal_sequencer.gd |
| 追跡対象の切り替え(新しい敵) | 最初に古い接続を解除 | disconnect_ghost_signals.gd |
| 一度限り/物理演算に安全な接続 | CONNECT_ONE_SHOT / CONNECT_DEFERRED | one_shot_deferred_connections.gd |
| 追加コンテキスト/引数の削除 | Callable.bind / unbind | callable_bind_context.gd / unbind_unwanted_args.gd |
利用可能なスクリプト
- signal_up_call_down_pattern.gd — 階層の配線前に必須です。
- global_signal_bus_router.gd / global_event_bus.gd — Autoload バスの設定前に必須です。
- disconnect_ghost_signals.gd — 追跡対象のエミッターを切り替える際に必須です。
- await_signal_sequencing.gd / complex_signal_sequencer.gd — 複数ステップの await に必須です。
- safe_dynamic_connections.gd —
is_connectedガード。 - one_shot_deferred_connections.gd — ワンショット/遅延フラグ。
- callable_bind_context.gd / unbind_unwanted_args.gd — bind/unbind。
- track_signal_emitter_source.gd —
CONNECT_APPEND_SOURCE_OBJECT。 - signal_debugger.gd / signal_spy.gd — デバッグ/テスト用スパイ。
ラムダキャプチャのクリーンアップ(完了)
Godot はノードが解放されると、ほとんどの接続を自動的に切断します。例外: ローカル変数をキャプチャするラムダは、手動で切断する必要があります。
var my_lambda: Callable
func _ready() -> void:
var x := 10
my_lambda = func(): print(x)
player.died.connect(my_lambda)
func _exit_tree() -> void:
if player and player.died.is_connected(my_lambda):
player.died.disconnect(my_lambda)
接続先を変更する場合は、名前付きメソッドまたは disconnect_ghost_signals.gd を使用してください。
CONNECT_REFERENCE_COUNTED — 正しい動作
CONNECT_REFERENCE_COUNTED は、同一の接続を複数回行うと、参照カウント付きの1つの接続を共有することを意味します(N 回接続/N 回切断)。「エミッターの解放時に自動クリーンアップする」という意味ではなく、キャプチャするラムダによるリークを解決するものでもありません。
- 解放時の自動クリーンアップ:通常の Object メソッドへの接続(キャプチャしないもの)は、どちらか一方が解放されると解除されます。
- キャプチャするラムダ:必ず手動で
disconnectしてください(上記を参照)。 - 発火後のワンショット自動削除:
CONNECT_ONE_SHOT。
詳細なレシピ(必要に応じて)
LLM の知識不足に関するルール:一般的なエージェントが読む前に知らないような内容は、ここか
scripts/に置きます。削除はせず、移動のみ行ってください。
| トピック | リファレンス |
|---|---|
| パターン 1~7 と注意点 | implementation-patterns.md |
リファレンス
段階的な情報開示:特定の API を調査する場合にのみ公式ドキュメントへのリンクを開き、関連するスキルは隣接ドメインへの振り分け時に読み込んでください。全体をあらかじめ読み込まないでください。
公式ドキュメント
- シグナルの使用 — 基本的な発信/接続の仕組みと、シグナルがノード間の強い参照を避けて疎結合にする理由を説明します。
- シーンの構成 — 親から子へ呼び出し、子から親へシグナルを送るという基本的な所有ルールにより、親→子のコマンドの流れを明示します。
- シグナルを使ったインスタンス化 — 生成したシーンからシグナルを発信し、固定のノードパスを使わずに、親やマネージャーが弾、戦利品などの生成物を受け取る方法を説明します。
- Autoload と通常のノード — グローバルな EventBus が適切な場合と、シーン内でシグナルを接続するほうが安全な場合を説明します。
- シングルトン(Autoload) — シーン変更後も維持される、型付きシグナルバスの登録方法を説明します。
- Signal — このスキル全体で使用する型付き
SignalAPI:emit、connect、is_connected、切断用ヘルパー。 - Callable — ラッパーラムダを使わずにコールバックのコンテキストを注入または破棄するための
bind()/unbind()。 - Object —
CONNECT_ONE_SHOT、CONNECT_DEFERRED、CONNECT_REFERENCE_COUNTED、CONNECT_APPEND_SOURCE_OBJECTフラグ。 - GDScript の基本 — 型付き
signal宣言と、直線的な非同期シーケンスのためのシグナルに対するawaitを説明します。 - SceneTree の使用 — ツリーへの出入りをまたぐ接続の有効期間と、接続先を変更するときに動的リスナーを切断する必要がある理由を説明します。
- Godot の通知 —
_ready、親のキャッシュ、ユーザーシグナルに関連する安全な接続タイミングを説明します。 - アイドル処理と物理処理 — コールバックが物理ステップ中に物理ボディを変更する場合に、シグナルハンドラーの遅延実行が重要となる理由を説明します。
関連スキル
前提条件
- godot-project-foundations — シグナルを組み込むプロジェクト構成、Autoload の登録、シーンの所有規則について説明します。
- godot-gdscript-mastery — 高度な接続フラグやシーケンサーを使用する前に必要な、型付き Callable、
await、シグナル構文について説明します。 - godot-autoload-architecture — グローバルな EventBus ルーター(ローカルなシーンイベント用ではありません)のシングルトンの起動順序と所有規則について説明します。
補完
- godot-composition — コンポーネントノードは過去形のイベントを発行し、親ノードはそれらのシグナルを接続して下位を呼び出すことで構成します。
- godot-scene-management — シーンの切り替えやローダーでは、ゴーストリスナーが残らないよう、バスを通じて再接続または再発行する必要があります。
- godot-state-machine-advanced — ステートの開始/終了がシグナルのファンアウトを引き起こすことがよくあります。FSM の遷移が循環するシグナルグラフにならないようにします。
- godot-resource-data-patterns — 共有設定には Resources を優先してください。シグナルは変更イベントを伝え、複製された可変状態の塊を運ぶものではありません。
- godot-testing-patterns —
watch_signals/スパイをこのスキルの発行コントラクトと組み合わせると、ユニットテストや統合テストに役立ちます。 - godot-ui-containers — ボタンやメニューは意図を上位へシグナルで伝え、コントローラーは下位を呼び出して Control ツリーを更新します。
下流/コンシューマー
- godot-dialogue-system — セリフ/選択肢の完了イベントは、シグナルを上位へ伝えるオーケストレーションに従い、UI やクエストのリスナーに届ける必要があります。
- godot-ability-system — クールダウン、発動、命中のペイロードには型付きシグナルが必要です。これにより、HUD/VFX とアビリティノードの依存を切り離せます。
- godot-combat-system — ダメージ/死亡/スコアの連鎖は、UI、オーディオ、進行システムへシグナルを上位に伝える典型的なファンアウトです。
- godot-performance-optimization — 高頻度のシグナル発行の嵐が見られる場合は、対策を強化してください。ティックごとのシグナルをバッファーや直接読み取りに置き換えます。
マスター
- godot-master — ライブラリのルーターであり、ミラーされたモジュールのエントリーポイントです。横断的なアーキテクチャ上の関心事をどのドメインスキルが担当するかを確認するときに開きます。