authoring-godot-prompt…
Use when writing or editing a SKILL.md, a skill's references/*.md, or an agent definition in this repo — required frontmatter,…
Use when setting up decoupled node communication — a global EventBus autoload with typed signals. Not for adding signals to an existing bus
Claude Code
$ npx -y skills add jame581/GodotPrompter --skill event-bus --agent claude-code
Codex
$ npx skills add jame581/GodotPrompter --skill event-bus -a codex -y
Cursor
$ npx skills add jame581/GodotPrompter --skill event-bus -a cursor -y
Gemini CLI
$ npx skills add jame581/GodotPrompter --skill event-bus -a gemini-cli -y
GitHub Copilot
$ npx skills add jame581/GodotPrompter --skill event-bus -a github-copilot -y
OpenCode
$ npx skills add jame581/GodotPrompter --skill event-bus -a opencode -y
Windsurf
$ npx skills add jame581/GodotPrompter --skill event-bus -a windsurf -y
name: event-bus description: Use when setting up decoupled node communication — a global EventBus autoload with typed signals. Not for adding signals to an existing bus
A global signal hub that lets unrelated nodes communicate without holding references to each other. All examples target Godot 4.3+ with no deprecated APIs.
> **Related skills:** **component-system** for direct signal communication between components, **csharp-signals** for C#-specific signal patterns, **dependency-injection** for alternative decoupling approaches, **ability-system** for an EventBus usage example with ability events.
---
An EventBus is a singleton autoload that acts as a central registry for signals. Instead of nodes connecting directly to each other, every node connects to (or emits on) the shared EventBus. This removes the need for one node to hold a reference to another.
Without EventBus With EventBus
────────────── ──────────────────────────
NodeA ──signal──► NodeB NodeA ──emit──► EventBus ──signal──► NodeB
──signal──► NodeC
──signal──► NodeD**Flow diagram**
┌─────────┐ emit(player_died) ┌───────────┐ player_died ┌──────────┐
│ NodeA │ ────────────────────► │ EventBus │ ───────────────► │ NodeB │
│(Player) │ │(Autoload) │ │ (UI) │
└─────────┘ └───────────┘ ───────────────► └──────────┘
player_died ┌──────────┐
│ NodeC │
│(AudioMgr)│
└──────────┘NodeA emits the signal. NodeB and NodeC each connected to EventBus independently. Neither knows the other exists.
---
| Scenario | Recommended approach | |--------------------------------------------|-------------------------------| | Parent notifying its own child | Direct signal or method call | | Child notifying its parent | Direct signal (bubble up) | | Two nodes with the same parent | Direct signal via parent | | Completely unrelated nodes in the tree | Event bus | | UI reacting to gameplay state changes | Event bus | | Audio manager reacting to game events | Event bus | | Data manager / save system reacting | Event bus | | Tight, performance-sensitive inner loop | Direct method call |
**Rule of thumb:** if you would otherwise need `get_node("../../SomeDistantNode")` or a hard-coded NodePath, the event bus is a better fit.
---
Create `res://autoloads/event_bus.gd` (or `EventBus.cs`), then register it in **Project → Project Settings → Globals → Autoload** with the name `EventBus`.
extends Node ## Emitted when the player character has died. signal player_died ## Emitted whenever the score changes. signal score_changed(new_score: int) ## Emitted when a level finishes successfully. signal level_completed(level_id: int) ## Emitted when the player picks up a collectible. signal item_collected(item_name: String) ## Emitted when the player's health changes. signal health_changed(current: int, maximum: int)
using Godot;
/// <summary>
/// Global signal hub. Register as an autoload named "EventBus".
/// </summary>
public partial class EventBus : Node
{
/// <summary>Emitted when the player character has died.</summary>
[Signal] public delegate void PlayerDiedEventHandler();
/// <summary>Emitted whenever the score changes.</summary>
[Signal] public delegate void ScoreChangedEventHandler(int newScore);
/// <summary>Emitted when a level finishes successfully.</summary>
[Signal] public delegate void LevelCompletedEventHandler(int levelId);
/// <summary>Emitted when the player picks up a collectible.</summary>
[Signal] public delegate void ItemCollectedEventHandler(string itemName);
/// <summary>Emitted when the player's health changes.</summary>
[Signal] public delegate void HealthChangedEventHandler(int current, int maximum);
}---
Consumers connect in `_ready()`. In C#, always disconnect in `_ExitTree()`: the bus outlives its consumers and its signals are custom, a case Godot does not disconnect when the consumer is freed, so the next emit would throw `ObjectDisposedException`.
extends CanvasLayer
# A connection to this node's method is removed automatically when the
# node is freed, but explicit disconnection is still good practice
# for long-lived nodes that reconnect frequently.
func _ready() -> void:
EventBus.player_died.connect(_on_player_died)
EventBus.score_changed.connect(_on_score_changed)
EventBus.health_changed.connect(_on_health_changed)
func _exit_tree() -> void:
EventBus.player_died.disconnect(_on_player_died)
EventBus.score_changed.disconnect(_on_score_changed)
EventBus.health_changed.disconnect(_on_health_changed)
func _on_player_died() -> void:
$DeathScreen.show()
func _on_score_changed(new_score: int) -> void:
$ScoreLabel.text = "Score: %d" % new_score
func _on_health_changed(current: int, maximum: int) -> void:
$HealthBar.value = float(current) / float(maximum) * 100.0using Godot;
public partial class HudLayer : CanvasLayer
{
private EventBus _eventBus;
public override void _Ready()
{
_eventBus = GetNode<EventBus>("/root/EventBus");
// Connect using strongly-typed delegate handlers
_eventBus.PlayerDied += OnPlayerDied;
_eventBus.ScoreChanged += OnScoreChanged;
_eventBus.HealthChanged += OnHealthChaAgentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.
Use when writing or editing a SKILL.md, a skill's references/*.md, or an agent definition in this repo — required frontmatter,…
Use when cutting a GodotPrompter release or bumping its version — the version-bump sequence, tag-triggered workflow, and the…
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D,…
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion…
Use when building or replacing an ability system — abilities with cost/cooldown, buffs/debuffs, stat modifiers, and gameplay…
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.