From dt-brigid
C# signal patterns in Godot 4.6 — custom signals, typed delegates, signal bus, cross-scene communication, Rx integration
npx claudepluginhub dreamteam-hq/brigid --plugin dt-brigidThis skill uses the workspace's default tool permissions.
Connect in the editor or in code. Disconnect on cleanup to avoid leaks.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Connect in the editor or in code. Disconnect on cleanup to avoid leaks.
button.Pressed += OnButtonPressed; // connect
button.Pressed -= OnButtonPressed; // disconnect
[Signal]
public delegate void HealthChangedEventHandler(int newHealth);
Godot 4.6 generates EmitSignalHealthChanged() from the delegate name. Connect from another node with player.HealthChanged += OnHealthChanged;.
CrystalMagica uses direct calls within the coordinator pattern and Rx for cross-system events.
An AutoLoad node that centralizes game-wide events. Avoids deep signal chains through the scene tree.
public partial class SignalBus : Node
{
[Signal]
public delegate void GamePausedEventHandler(bool paused);
public static SignalBus Instance { get; private set; }
public override void _Ready() => Instance = this;
}
Use sparingly. Too many signals on one bus becomes spaghetti.
await ToSignal(animPlayer, AnimationPlayer.SignalName.AnimationFinished);
Useful for cutscenes, animation sequences, and one-shot waits.
CrystalMagica uses System.Reactive Subject<T> instead of Godot signals for ViewModel-to-View communication.
// In RemoteCharacterVM
public Subject<CharacterAction> Updates { get; } = new();
Updates.OnNext(new CharacterAction.Move(position));
// In View — subscribe
_vm.Updates
.OfType<CharacterAction.Move>()
.Subscribe(action => MoveSprite(action.Position));
Why Rx over signals:
Select, OfType, CombineLatest, ThrottleSignals fire on the thread that emits them. If OnNext is called from the main thread (_Process drain loop), subscribers run on main thread. Never emit signals or call OnNext from a background thread if subscribers touch nodes — Godot scene tree access is main-thread-only.