Specify a webhook-driven task for OpenClaw
Describe event inputs, validation, deduplication, and intended actions before integration work.
1,072,278 AI resources indexedWorking toward the world’s largest AI resource index.
Use when Godot code has tight coupling via get_node(), get_parent(), or direct references creating brittle dependencies. Detects coupling patterns and transforms to signal-based communication. Components become independent, testable, and reusable. Preserves exact behavior while improving architec...
---
name: godot-add-signals-66e543363c41
version: 3.0.0
displayName: Replace Coupling with Signals
description: >
Use when Godot code has tight coupling via get_node(), get_parent(), or direct
references creating brittle dependencies. Detects coupling patterns and transforms
to signal-based communication. Components become independent, testable, and reusable.
Preserves exact behavior while improving architecture.
author: Asreonn
license: MIT
category: game-development
type: tool
difficulty: intermediate
audience: [developers]
keywords:
- godot
- signals
- decoupling
- get-node
- get-parent
- architecture
- gdscript
- loose-coupling
platforms: [macos, linux, windows]
repository: https://github.com/asreonn/godot-superpowers
homepage: https://github.com/asreonn/godot-superpowers#readme
permissions:
filesystem:
read: [".gd", ".tscn"]
write: [".gd", ".tscn"]
git: true
behavior:
auto_rollback: true
validation: true
git_commits: true
outputs: "Signal definitions, signal connections, decoupled components, git commits"
requirements: "Git repository, Godot 4.x"
execution: "Fully automatic with behavior preservation"
integration: "Part of godot-refactor orchestrator, works with godot-split-scripts"
---
# Replace Coupling with Signals
## Core Principle
**Components communicate via signals, not direct references.** Coupling makes code brittle and hard to test.
## What This Skill Does
Finds patterns like:
```gdscript
# player.gd
func take_damage(amount):
health -= amount
get_node("../UI/HealthBar").update(health) # TIGHT COUPLING
get_parent().get_node("ScoreManager").reduce_score() # FRAGILE PATH
```
Transforms to:
```gdscript
# player.gd
signal health_changed(new_health)
func take_damage(amount):
health -= amount
health_changed.emit(health) # SIGNAL - NO COUPLING
```
```gdscript
# main.gd (or scene setup)
func _ready():
player.health_changed.connect(ui.health_bar.update)
player.health_changed.connect(score_manager.on_player_damaged)
```
## Detection Patterns
Identifies:
- `get_node("../path")` - Upward path navigation
- `get_parent().something` - Parent dependencies
- `find_child("name")` - Runtime searches
- `has_method()` - Tight interface coupling
- Direct owner references creating circular dependencies
## When to Use
### You're Refactoring Legacy Code
Old code has spaghetti dependencies via get_node chains.
### You're Building Testable Systems
Want to test components in isolation without full scene tree.
### You're Creating Reusable Components
Components should work in different contexts without modification.
### You're Experiencing Brittle Code
Changes to scene structure break unrelated functionality.
## Process
1. **Scan** - Find all get_node(), get_parent(), find_child() usage
2. **Analyze** - Identify what information flows between nodes
3. **Define Signals** - Create signal definitions for communication
4. **Replace** - Convert direct calls to signal emissions
5. **Connect** - Wire signals in appropriate orchestration points
6. **Validate** - Ensure behavior preserved exactly
7. **Commit** - Git commit per coupling removal
## Example Transformation
**Before (Tight Coupling):**
```gdscript
# enemy.gd
extends CharacterBody2D
func die():
var player = get_node("../Player") # FRAGILE PATH
player.add_score(100)
var audio = get_parent().get_node("AudioManager") # TIGHT COUPLING
audio.play_sound("enemy_death")
queue_free()
```
**After (Signal-Based):**
```gdscript
# enemy.gd
extends CharacterBody2D
signal died(score_value: int)
signal death_sound_requested(sound_name: String)
func die():
died.emit(100)
death_sound_requested.emit("enemy_death")
queue_free()
```
```gdscript
# main.gd (orchestrator)
func _ready():
for enemy in enemies:
enemy.died.connect(player.add_score)
enemy.death_sound_requested.connect(audio_manager.play_sound)
```
## Signal Patterns
### One-to-Many
One emitter, multiple listeners (health changed → update UI + save game + achievement check).
### Event Broadcasting
Announce something happened without knowing who cares.
### Request-Response
Request service without knowing provider (request_ammo → whoever handles ammo).
### State Change Notification
Notify when state changes (entered_water, jumped, landed).
## What Gets Created
- Signal definitions with typed parameters
- Signal emission at appropriate points
- Signal connections in orchestrator scripts
- Documentation of signal purpose and parameters
- Git commits documenting each decoupling
## Smart Analysis
**Identifies coupling types:**
- **Structural coupling** - Depends on scene tree structure
- **Interface coupling** - Calls specific methods on other nodes
- **Data coupling** - Accesses data from other nodes
**Chooses appropriate solution:**
- Signals for events and notifications
- Dependency injection for services
- Scene composition for reusable components
## Integration
Works with:
- **godot-split-scripts** - Split first, then decouple
- **godot-extract-to-scenes** - Extract scenes, then add signals
- **godot-refactor** (orchestrator) - Runs as part of full refactoring
## Safety
- Behavior preserved exactly
- Signal connections tested automatically
- Rollback on validation failure
- Original coupling preserved in git history
## When NOT to Use
Don't add signals if:
- Parent-child relationship is intentional design
- Component genuinely needs specific parent type
- Coupling is within same responsibility boundary
- Adding signals makes code more complex, not simpler
Examples of valid coupling:
- UI button calling parent dialog's close method
- Child node accessing parent's exported properties
- Component accessing owner's public API
## Signal Naming Conventions
**Events (past tense):**
- `health_changed`
- `item_collected`
- `enemy_died`
**Requests (imperative):**
- `damage_requested`
- `play_sound`
- `spawn_particle`
**State Changes:**
- `entered_state`
- `exited_state`
- `state_changed`
## Benefits
- **Testability** - Test components without full scene tree
- **Reusability** - Components work in different contexts
- **Flexibility** - Add/remove listeners without changing emitter
- **Maintainability** - Changes don't break distant code
- **Clarity** - Signal connections show system architecture
## Common Transformations
| Before (Coupled) | After (Signal-Based) |
|------------------|---------------------|
| `get_node("../Player").damage()` | `damage_dealt.emit()` → player listens |
| `get_parent().update_ui()` | `ui_update_requested.emit()` → UI listens |
| `owner.score += 10` | `score_changed.emit(10)` → owner listens |
| `find_child("Camera").shake()` | `screen_shake_requested.emit()` → camera listens |
---
name: godot-add-signals-66e543363c41
version: 3.0.0
displayName: Replace Coupling with Signals
description: >
Use when Godot code has tight coupling via get_node(), get_parent(), or direct
references creating brittle dependencies. Detects coupling patterns and transforms
to signal-based communication. Components become independent, testable, and reusable.
Preserves exact behavior while improving architecture.
author: Asreonn
license: MIT
category: game-development
type: tool
difficulty: intermediate
audience: [developers]
keywords:
- godot
- signals
- decoupling
- get-node
- get-parent
- architecture
- gdscript
- loose-coupling
platforms: [macos, linux, windows]
repository: https://github.com/asreonn/godot-superpowers
homepage: https://github.com/asreonn/godot-superpowers#readme
permissions:
filesystem:
read: [".gd", ".tscn"]
write: [".gd", ".tscn"]
git: true
behavior:
auto_rollback: true
validation: true
git_commits: true
outputs: "Signal definitions, signal connections, decoupled components, git commits"
requirements: "Git repository, Godot 4.x"
execution: "Fully automatic with behavior preservation"
integration: "Part of godot-refactor orchestrator, works with godot-split-scripts"
---
# Replace Coupling with Signals
## Core Principle
**Components communicate via signals, not direct references.** Coupling makes code brittle and hard to test.
## What This Skill Does
Finds patterns like:
```gdscript
# player.gd
func take_damage(amount):
health -= amount
get_node("../UI/HealthBar").update(health) # TIGHT COUPLING
get_parent().get_node("ScoreManager").reduce_score() # FRAGILE PATH
```
Transforms to:
```gdscript
# player.gd
signal health_changed(new_health)
func take_damage(amount):
health -= amount
health_changed.emit(health) # SIGNAL - NO COUPLING
```
```gdscript
# main.gd (or scene setup)
func _ready():
player.health_changed.connect(ui.health_bar.update)
player.health_changed.connect(score_manager.on_player_damaged)
```
## Detection Patterns
Identifies:
- `get_node("../path")` - Upward path navigation
- `get_parent().something` - Parent dependencies
- `find_child("name")` - Runtime searches
- `has_method()` - Tight interface coupling
- Direct owner references creating circular dependencies
## When to Use
### You're Refactoring Legacy Code
Old code has spaghetti dependencies via get_node chains.
### You're Building Testable Systems
Want to test components in isolation without full scene tree.
### You're Creating Reusable Components
Components should work in different contexts without modification.
### You're Experiencing Brittle Code
Changes to scene structure break unrelated functionality.
## Process
1. **Scan** - Find all get_node(), get_parent(), find_child() usage
2. **Analyze** - Identify what information flows between nodes
3. **Define Signals** - Create signal definitions for communication
4. **Replace** - Convert direct calls to signal emissions
5. **Connect** - Wire signals in appropriate orchestration points
6. **Validate** - Ensure behavior preserved exactly
7. **Commit** - Git commit per coupling removal
## Example Transformation
**Before (Tight Coupling):**
```gdscript
# enemy.gd
extends CharacterBody2D
func die():
var player = get_node("../Player") # FRAGILE PATH
player.add_score(100)
var audio = get_parent().get_node("AudioManager") # TIGHT COUPLING
audio.play_sound("enemy_death")
queue_free()
```
**After (Signal-Based):**
```gdscript
# enemy.gd
extends CharacterBody2D
signal died(score_value: int)
signal death_sound_requested(sound_name: String)
func die():
died.emit(100)
death_sound_requested.emit("enemy_death")
queue_free()
```
```gdscript
# main.gd (orchestrator)
func _ready():
for enemy in enemies:
enemy.died.connect(player.add_score)
enemy.death_sound_requested.connect(audio_manager.play_sound)
```
## Signal Patterns
### One-to-Many
One emitter, multiple listeners (health changed → update UI + save game + achievement check).
### Event Broadcasting
Announce something happened without knowing who cares.
### Request-Response
Request service without knowing provider (request_ammo → whoever handles ammo).
### State Change Notification
Notify when state changes (entered_water, jumped, landed).
## What Gets Created
- Signal definitions with typed parameters
- Signal emission at appropriate points
- Signal connections in orchestrator scripts
- Documentation of signal purpose and parameters
- Git commits documenting each decoupling
## Smart Analysis
**Identifies coupling types:**
- **Structural coupling** - Depends on scene tree structure
- **Interface coupling** - Calls specific methods on other nodes
- **Data coupling** - Accesses data from other nodes
**Chooses appropriate solution:**
- Signals for events and notifications
- Dependency injection for services
- Scene composition for reusable components
## Integration
Works with:
- **godot-split-scripts** - Split first, then decouple
- **godot-extract-to-scenes** - Extract scenes, then add signals
- **godot-refactor** (orchestrator) - Runs as part of full refactoring
## Safety
- Behavior preserved exactly
- Signal connections tested automatically
- Rollback on validation failure
- Original coupling preserved in git history
## When NOT to Use
Don't add signals if:
- Parent-child relationship is intentional design
- Component genuinely needs specific parent type
- Coupling is within same responsibility boundary
- Adding signals makes code more complex, not simpler
Examples of valid coupling:
- UI button calling parent dialog's close method
- Child node accessing parent's exported properties
- Component accessing owner's public API
## Signal Naming Conventions
**Events (past tense):**
- `health_changed`
- `item_collected`
- `enemy_died`
**Requests (imperative):**
- `damage_requested`
- `play_sound`
- `spawn_particle`
**State Changes:**
- `entered_state`
- `exited_state`
- `state_changed`
## Benefits
- **Testability** - Test components without full scene tree
- **Reusability** - Components work in different contexts
- **Flexibility** - Add/remove listeners without changing emitter
- **Maintainability** - Changes don't break distant code
- **Clarity** - Signal connections show system architecture
## Common Transformations
| Before (Coupled) | After (Signal-Based) |
|------------------|---------------------|
| `get_node("../Player").damage()` | `damage_dealt.emit()` → player listens |
| `get_parent().update_ui()` | `ui_update_requested.emit()` → UI listens |
| `owner.score += 10` | `score_changed.emit(10)` → owner listens |
| `find_child("Camera").shake()` | `screen_shake_requested.emit()` → camera listens |
Imported from the listed AgentSkill.sh category. Complete supplied package files and notices are retained. Required external tools and credentials are not installed. No bundled code was executed during import. Individual agent task behavior has not been tested.