godot-autoload-architecture

安装量: 68
排名: #11306

安装

npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-autoload-architecture
AutoLoad Architecture
AutoLoads are Godot's singleton pattern, allowing scripts to be globally accessible throughout the project lifecycle. This skill guides implementing robust, maintainable singleton architectures.
NEVER Do
NEVER access AutoLoads in
_init()
— AutoLoads aren't guaranteed to exist yet during _init(). Use
_ready()
or
_enter_tree()
instead.
NEVER create circular dependencies
— If GameManager depends on SaveManager and SaveManager depends on GameManager, initialization deadlocks. Use signals or dependency injection.
NEVER store scene-specific state in AutoLoads
— AutoLoads persist across scene changes. Storing temporary state (current enemy count, UI state) causes leaks. Reset in
_ready()
.
NEVER use AutoLoads for everything
— Over-reliance creates "God objects" and tight coupling. Limit to 5-10 AutoLoads max. Use scene trees for local logic.
NEVER assume AutoLoad initialization order
— AutoLoads initialize top-to-bottom in Project Settings. If order matters, add explicit
initialize()
calls or use
@onready
carefully.
Available Scripts
MANDATORY
Read the appropriate script before implementing the corresponding pattern.
service_locator.gd
Service locator pattern for decoupled system access. Allows swapping implementations (e.g., MockAudioManager) without changing game code.
stateless_bus.gd
Stateless signal bus pattern. Domain-specific signals (player_health_changed, level_completed) without storing state. The bus is a post office, not a warehouse.
autoload_initializer.gd
Manages explicit initialization order and dependency injection to avoid circular dependencies.
Do NOT Load
service_locator.gd unless implementing dependency injection patterns.
When to Use AutoLoads
Good Use Cases:
Game Managers
PlayerManager, GameManager, LevelManager
Global State
Score, inventory, player stats
Scene Transitions
SceneTransitioner for loading/unloading scenes
Audio Management
Global music/SFX controllers
Save/Load Systems
Persistent data management Avoid AutoLoads For: Scene-specific logic (use scene trees instead) Temporary state (use signals or direct references) Over-architecting simple projects Implementation Pattern Step 1: Create the Singleton Script 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 Step 2: Register as AutoLoad Project → Project Settings → AutoLoad Click the folder icon, select game_manager.gd Set Node Name: GameManager (PascalCase convention) Enable if needed globally Click "Add" Verify in project.godot : [ autoload ] GameManager = " *res://autoloads/game_manager.gd " The * prefix makes it active immediately on startup. Step 3: Access from Any Script 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 ) Best Practices 1. Use Static Typing

✅ Good

var score : int = 0

❌ Bad

var score = 0 2. Emit Signals for State Changes

✅ 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

  1. Organize AutoLoads by Feature res://autoloads/ game_manager.gd audio_manager.gd scene_transitioner.gd save_manager.gd
  2. Scene Transitioning Pattern

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 ) Common Patterns Game State Machine 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 Resource Preloading

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 Testing AutoLoads 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

Reference Godot Docs: Singletons (AutoLoad) Best Practices: Scene Organization Related Master Skill: godot-master

返回排行榜