skills/godot-autoload-architecture/SKILL.md
Expert patterns for Godot AutoLoad (singleton) architecture including global state management, scene transitions, signal-based communication, dependency injection, autoload initialization order, and anti-patterns to avoid. Use for game managers, save systems, audio controllers, or cross-scene resources. Trigger keywords: AutoLoad, singleton, GameManager, SceneTransitioner, SaveManager, global_state, autoload_order, signal_bus, dependency_injection.
npx skillsauth add thedivergentai/gd-agentic-skills godot-autoload-architectureInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
AutoLoads are Godot's singleton pattern, allowing scripts to be globally accessible throughout the project lifecycle. This skill guides implementing robust, maintainable singleton architectures.
Using static var for high-performance global state that doesn't need SceneTree presence.
Robust scene transitioning logic that handles deferred freeing and root-level management.
Diagnostic utility for verifying and debugging the initialization sequence of Singletons.
Centralized signal router for decoupling disparate systems (Achievements, Stats, Game Events).
Pattern for data that must survive change_scene_to_file() (Inventory, Settings).
Memory-efficient singleton pattern that instantiates on-demand rather than at boot.
CanvasLayer-based debug overlay accessible from any game context.
Expert rules and safety checks for communication between multiple Singletons.
Using Mutex and call_deferred to safely access global data from background threads.
Validation utility to ensure Autoloads are correctly registered before attempting access.
_init() — AutoLoads are initialized sequentially. Accessing one in _init() may find a null reference [12]._ready() — If multiple Singletons refer to each other's trees during boot, it can cause layout/sorting errors.Parent.method() calls from an Autoload — Autoloads sit at the root. They are the ultimate "top". Use signals to talk to the active scene._process() or signals, use a static var in a class_name script instead [7].get_tree().current_scene is accurate in _ready() — In Autoloads, the active scene might still be initializing. Access it via get_tree().root.get_child(-1) [6].process_mode configuration — If your global console or music manager needs to work while the game is paused, set process_mode = PROCESS_MODE_ALWAYS.Good Use Cases:
Avoid AutoLoads For:
Example: GameManager.gd
extends Node
# Signals for global events
signal game_started
signal game_paused(is_paused: bool)
signal player_died
# Global state
var score: int = 0
var current_level: int = 1
var is_paused: bool = false
func _ready() -> void:
# Initialize autoload state
print("GameManager initialized")
func start_game() -> void:
score = 0
current_level = 1
game_started.emit()
func pause_game(paused: bool) -> void:
is_paused = paused
get_tree().paused = paused
game_paused.emit(paused)
func add_score(points: int) -> void:
score += points
Project → Project Settings → AutoLoad
game_manager.gdGameManager (PascalCase convention)Verify in project.godot:
[autoload]
GameManager="*res://autoloads/game_manager.gd"
The * prefix makes it active immediately on startup.
extends Node2D
func _ready() -> void:
# Access the singleton
GameManager.connect("game_paused", _on_game_paused)
GameManager.start_game()
func _on_button_pressed() -> void:
GameManager.add_score(100)
func _on_game_paused(is_paused: bool) -> void:
print("Game paused: ", is_paused)
# ✅ Good
var score: int = 0
# ❌ Bad
var score = 0
# ✅ Good - allows decoupled listeners
signal score_changed(new_score: int)
func add_score(points: int) -> void:
score += points
score_changed.emit(score)
# ❌ Bad - tight coupling
func add_score(points: int) -> void:
score += points
ui.update_score(score) # Don't directly call UI
res://autoloads/
game_manager.gd
audio_manager.gd
scene_transitioner.gd
save_manager.gd
# scene_transitioner.gd
extends Node
signal scene_changed(scene_path: String)
func change_scene(scene_path: String) -> void:
# Fade out effect (optional)
await get_tree().create_timer(0.3).timeout
get_tree().change_scene_to_file(scene_path)
scene_changed.emit(scene_path)
enum GameState { MENU, PLAYING, PAUSED, GAME_OVER }
var current_state: GameState = GameState.MENU
func change_state(new_state: GameState) -> void:
current_state = new_state
match current_state:
GameState.MENU:
# Load menu
pass
GameState.PLAYING:
get_tree().paused = false
GameState.PAUSED:
get_tree().paused = true
GameState.GAME_OVER:
# Show game over screen
pass
# Preload heavy resources once
const PLAYER_SCENE := preload("res://scenes/player.tscn")
const EXPLOSION_EFFECT := preload("res://effects/explosion.tscn")
func spawn_player(position: Vector2) -> Node2D:
var player := PLAYER_SCENE.instantiate()
player.global_position = position
return player
Since AutoLoads are always loaded, avoid heavy initialization in _ready(). Use lazy initialization or explicit init functions:
var _initialized: bool = false
func initialize() -> void:
if _initialized:
return
_initialized = true
# Heavy setup here
development
Godot Expert Auditor: Aurelius. Exhaustive never-list enforcement and architectural slap-down for Godot 4.6 projects.
development
--- name:# Godot Expert Analyst: Anara ## Visionary Architect of Godot 4.6+ Excellence > "Scale is not a feature; it is a philosophy. I don't look at what your game is today; I look at whether it can survive tomorrow." — Anara You are **Anara**, the visionary architect of Godot 4.6+ excellence. You evaluate projects not for "if they work", but for "how well they scale". Your purpose is to certify professional-grade projects and provide the blueprint for architectural transcendence. Your voice
development
Expert blueprint for AI pathfinding (tower defense, RTS, stealth) using NavigationAgent2D/3D, NavigationServer, avoidance, and dynamic navigation mesh generation. Use when implementing enemy AI, NPC movement, or obstacle avoidance. Keywords NavigationAgent2D, NavigationRegion2D, pathfinding, NavigationServer, avoidance, baking, NavigationObstacle.
development
Expert patterns for Godot audio including AudioStreamPlayer variants (2D positional, 3D spatial), AudioBus mixing architecture, dynamic effects (reverb, EQ,compression), audio pooling for performance, music transitions (crossfade, bpm-sync), and procedural audio generation. Use for music systems, sound effects, spatial audio, or audio-reactive gameplay. Trigger keywords: AudioStreamPlayer, AudioStreamPlayer2D, AudioStreamPlayer3D, AudioBus, AudioServer, AudioEffect, music_crossfade, audio_pool, positional_audio, reverb, bus_volume.