thedivergentai/godot-signal-architecture
Expert blueprint for signal-driven architecture using \"Signal Up, Call Down\" pattern for loose coupling. Covers typed signals, signal chains, one-shot connections, and AutoLoad event buses. Use when implementing event systems OR decoupling nodes. Keywords signal, emit, connect, CONNECT_ONE_SHOT, CONNECT_REFERENCE_COUNTED, event bus, AutoLoad, decoupling.
npx skills add https://github.com/thedivergentai/GD-Agentic-Skills --skill godot-signal-architecture
Signal Up/Call Down, typed signals, and scoped buses — not connect/emit tutorials.
Object.connect() — Typos result in silent failures. Always use signal.connect(_callback) for compile-time validation.ERR_INVALID_PARAMETER at runtime unless using the Object.CONNECT_REFERENCE_COUNTED flag to stack connections.unbind() to drop unwanted parameters and keep your API clean.signal moved without types lacks editor support. Always use signal moved(dir: Vector2)._exit_tree() or when retargeting (disconnect_ghost_signals.gd).died.emit() calls queue_free(), listeners might fail to respond. Emit first.health_changed, died).apply_damage, play_anim).Use signals for: UI presses, death → game over, loot → inventory, cross-scene bus events.
Use direct calls for: parent commanding child, local property access.
| Scope | Pattern | MANDATORY script |
|-------|---------|------------------|
| Child notifies parent / UI | Local signal.connect in parent _ready | signal_up_call_down_pattern.gd |
| Parent orchestrates children | Method calls down (not signals) | same |
| Cross-scene / systems (achievements, save) | Autoload bus | global_signal_bus_router.gd / global_event_bus.gd |
| Linear async steps (load → fade → spawn) | await signal sequence | await_signal_sequencing.gd / complex_signal_sequencer.gd |
| Retarget tracking (new enemy) | Disconnect old first | disconnect_ghost_signals.gd |
| One-shot / physics-safe | CONNECT_ONE_SHOT / CONNECT_DEFERRED | one_shot_deferred_connections.gd |
| Extra context / drop args | Callable.bind / unbind | callable_bind_context.gd / unbind_unwanted_args.gd |
is_connected guards.CONNECT_APPEND_SOURCE_OBJECT.Godot auto-disconnects most connections when a node frees. Exception: lambdas that capture locals — you must disconnect manually.
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)
Prefer named methods or disconnect_ghost_signals.gd when retargeting.
CONNECT_REFERENCE_COUNTED means multiple identical connects share one connection with a refcount (connect N times / disconnect N times). It is not "auto-cleanup when the emitter frees" and does not fix capturing-lambda leaks.
disconnect (see above).CONNECT_ONE_SHOT.> LLM-ignorance rule: if a general agent would not know it before reading, it lives here or in scripts/ — never delete, only move.
| Topic | Reference |
|-------|-----------|
| Patterns 1–7 + gotchas | implementation-patterns.md |
> Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.
Signal API: emit, connect, is_connected, and disconnect helpers used throughout this skill.bind() / unbind() for injecting or discarding callback context without wrapper lambdas.CONNECT_ONE_SHOT, CONNECT_DEFERRED, CONNECT_REFERENCE_COUNTED, and CONNECT_APPEND_SOURCE_OBJECT flags.signal declarations and await on signals for linear async sequences._ready, parent caches, and user signals.await, and signal syntax required before advanced connect flags and sequencers.watch_signals / spies pair with this skill’s emit contracts for unit and integration tests.Take thedivergentai/godot-signal-architecture from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.