# Dependency Injection

Use when managing dependencies between systems, autoloads, service locators, @export...

- Repository: https://github.com/jame581/GodotPrompter (914 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add jame581/GodotPrompter --skill dependency-injection -g -a claude-code -y`
Codex: `npx skills add jame581/GodotPrompter --skill dependency-injection -g -a codex -y`
Cursor: `npx skills add jame581/GodotPrompter --skill dependency-injection -g -a cursor -y`
Gemini CLI: `npx skills add jame581/GodotPrompter --skill dependency-injection -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add jame581/GodotPrompter`

## Description

Use when managing dependencies between systems, autoloads, service locators, @export injection, and scene injection patterns

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Dependency Injection in Godot 4.3+

Patterns for wiring dependencies between systems so nodes stay loosely coupled, swappable, and testable. All examples target Godot 4.3+ with no deprecated APIs.

> **Related skills:** **godot-testing** for test-friendly architecture, **event-bus** for signal-based decoupling, **godot-project-setup** for autoload registration.

---

## 1. The Problem

Tight coupling makes code hard to test, extend, and swap. The most common form in Godot is reaching directly into a global autoload from everywhere in the codebase.

```gdscript
# BAD, tight coupling via direct autoload access scattered everywhere

# player.gd
func take_damage(amount: int) -> void:
    health -= amount
    AudioManager.play_sfx("hurt")          # hard dependency on AudioManager
    UIManager.update_health_bar(health)    # hard dependency on UIManager
    if health <= 0:
        GameState.record_death()           # hard dependency on GameState

# enemy.gd
func attack() -> void:
    AudioManager.play_sfx("attack")        # same AudioManager dependency again
```

```csharp
// BAD, tight coupling via direct autoload / global access scattered everywhere

// Player.cs
public partial class Player : CharacterBody3D
{
    private int _health = 100;

    public void TakeDamage(int amount)
    {
        _health -= amount;
        GetNode<AudioManager>("/root/AudioManager").PlaySfx("hurt");        // hard dependency
        GetNode<UIManager>("/root/UIManager").UpdateHealthBar(_health);     // hard dependency
        if (_health <= 0)
            GetNode<GameState>("/root/GameState").RecordDeath();            // hard dependency
    }
}

// Enemy.cs
public partial class Enemy : CharacterBody3D
{
    public void Attack()
    {
        GetNode<AudioManager>("/root/AudioManager").PlaySfx("attack");      // same dependency again
    }
}
```

**Problems with this approach:**

The rest: https://github.com/jame581/GodotPrompter/blob/HEAD/skills/dependency-injection/SKILL.md
