godot-signal-architecture
Installation
SKILL.md
NEVER Do in Signal Architecture
- NEVER use the legacy string-based
Object.connect()— Typos result in silent failures. Always usesignal.connect(_callback)for compile-time validation. - NEVER use signals to dictate behavior top-down — Signals are past-tense events (e.g., "died"). Use direct method calls for commands (e.g., "kill").
- NEVER connect a signal twice to the same Callable — This throws an
ERR_INVALID_PARAMETERat runtime unless using theObject.CONNECT_REFERENCE_COUNTEDflag to stack connections. - NEVER use a Global Signal Bus for local data — Pollutes global state and makes debugging harder. Use local connections for scene-specific logic.
- NEVER assume callbacks must accept all signal arguments — Use
unbind()to drop unwanted parameters and keep your API clean. - NEVER create circular signal dependencies — A signals B, B signals back to A? Use a mediator (parent or AutoLoad) to break the loop.
- NEVER skip signal typing —
signal movedwithout types lacks editor support. Always usesignal moved(dir: Vector2). - NEVER forget to disconnect dynamic signals — Ghost connections cause "call on null instance" errors. Disconnect in
_exit_tree()or when retargeting (disconnect_ghost_signals.gd). - NEVER emit signals with immediate side effects on the emitter — If
died.emit()callsqueue_free(), listeners might fail to respond. Emit first. - NEVER use signals for high-frequency data streams — Sending 1000+ signals/second (like per-particle updates) is inefficient. Use shared arrays or direct buffers.