Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
thedivergentai avatar

Godot Project Foundations

  • 243 installs
  • 454 repo stars
  • Updated July 28, 2026
  • thedivergentai/gd-agentic-skills

Use godot-project-foundations for development tasks

About

godot-project-foundations: A skill for development. This provides functionality for development workflows.

  • godot-project-foundations

Godot Project Foundations by the numbers

  • 243 all-time installs (skills.sh)
  • +29 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #1,601 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-project-foundations

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs243
repo stars454
Last updatedJuly 28, 2026
Repositorythedivergentai/gd-agentic-skills

What it does

Use godot-project-foundations for development tasks

Files

SKILL.mdMarkdownGitHub ↗

Project Foundations

Feature-based organization, consistent naming, and version control hygiene define professional Godot projects.

Available Scripts

🏛️ Core Scaffolding (Stateful / Persistent)

Stateful managers and controllers that persist in the SceneTree or handle global lifecycle events.

  • [project_bootstrapper.gd](scripts/project_bootstrapper.gd): Auto-generates feature folders and .gitignore.
  • [runtime_configurator.gd](scripts/runtime_configurator.gd): Applies high-performance profiles and saves override.cfg.
  • [managed_autoload.gd](scripts/managed_autoload.gd): Advanced Singleton pattern with RefCounted delegation.
  • [global_event_bus.gd](scripts/global_event_bus.gd): Strongly-typed global Signal Bus for system decoupling.
  • [node_pooling_system.gd](scripts/node_pooling_system.gd): Thread-safe Object Pool for high-frequency scene instantiation.
  • [async_resource_loader.gd](scripts/async_resource_loader.gd): Threaded non-blocking scene loading with progress status.

🛠️ Runtime Utilities (Stateless / Lightweight)

Stateless helper scripts, static libraries, and custom data containers (Resource/RefCounted).

  • [base_data_resource.gd](scripts/base_data_resource.gd): Reactive Resource foundation using emit_changed().
  • [advanced_telemetry_logger.gd](scripts/advanced_telemetry_logger.gd): Custom OS-level Logger for crash reporting.
  • [threaded_task_worker.gd](scripts/threaded_task_worker.gd): Robust WorkerThreadPool implementation.
  • [action_buffer_input.gd](scripts/action_buffer_input.gd): Foundational _unhandled_input buffer.
  • [build_metadata_provider.gd](scripts/build_metadata_provider.gd): Native extraction of version and build metadata.
Do NOT Load dependency_auditor.gd unless troubleshooting loading errors.

NEVER Do (Expert Anti-Patterns)

Global Architecture

  • NEVER group by file type/scripts, /sprites folders. Nightmare maintainability. Use feature-based: /player, /ui.
  • NEVER mix snake_case and PascalCase in files — Standard: snake_case for files, PascalCase for nodes.
  • NEVER use hardcoded get_node() paths — Brittle on reparenting. Use %SceneUniqueNames for stable references.
  • NEVER use monolithic Autoloads — Avoid managers that hold visual node references; keep singletons focused on pure data or RefCounted delegation.

Resource Management

  • NEVER forget .gitignore — Committing .godot/ folder = 100MB+ bloat + conflicts.
  • NEVER skip .gdignore for raw assets — Design source files (.psd, .blend) in root will be imported unless ignored.
  • NEVER modify globally shared Resources directly — Strictly call duplicate(true) for unique instances with independent state.

Performance & Threading

  • NEVER block the main thread with `load()` — Strictly use ResourceLoader.load_threaded_request() for async scene transitions.
  • NEVER modify the SceneTree from a background thread — Strictly use call_deferred() for thread-to-main-thread synchronization.
  • NEVER skip Mutex locking during pooled access — Strictly ensure thread-safety when using a shared WorkerThreadPool or Object Pool.
  • NEVER use `_process()` for precise input — Tied to visual framerate. Strictly use _unhandled_input() to capture exact, frame-independent events.

---

1. Naming Conventions

  • Files & Folders: Always use snake_case. (e.g., player_controller.gd, main_menu.tscn).
  • Exception: C# scripts use PascalCase for class-match.
  • Node Names: Always use PascalCase (e.g., PlayerSprite, CollisionShape2D).
  • Exported Variables: Use snake_case. (e.g., @export var max_health: int). The Inspector automatically converts this to Title Case ("Max Health").
  • Internal / Private Members: Prepend a single underscore _ to variables and methods that are internal to the class. (e.g., var _current_health, func _calculate_damage()). This also applies to virtual engine callbacks (e.g., _ready, _process).
  • Signals: Use past-tense snake_case to represent events that have already occurred. (e.g., signal health_changed, signal door_opened).
  • Unique Names: Use %SceneUniqueNames for frequently accessed nodes to avoid brittle get_node() paths.

2. Feature-Based Organization

Instead of grouping by type (e.g., /scripts, /sprites), group by feature (the "What", not the "How").

Correct Structure:

/project.godot
/common/           # Global resources, themes, shared scripts
/entities/
    /player/       # Everything related to player
        player.tscn
        player.gd
        player_sprite.png
    /enemy/
/ui/
    /main_menu/
/levels/
/addons/           # Third-party plugins

3. Version Control

  • Always include a .gitignore tailored for Godot (ignoring .godot/ folder and import artifacts).
  • Use .gdignore in folders that Godot should not scan/import (e.g., raw design source files).

Workflow: Scaffolding a New Project

When asked to "Setup a project" or "Start a new game":

1. Initialize Root: Ensure project.godot exists. 2. Create Core Folders:

  • entities/
  • ui/
  • levels/
  • common/

3. Setup Git: Create a comprehensive .gitignore. 4. Documentation: Create a README.md explaining the feature-based structure.

🔄 Migration Guide: Typed GDScript 2.0

Transitioning from untyped GDScript or C# to strictly-typed GDScript 2.0.

1. The Inference Operator (:=)

Use := when the type is obvious from the right-hand side.

  • Good: var pos := Vector2(10, 10)
  • Redundant: var pos: Vector2 = Vector2(10, 10)

2. Typed Collections

Godot 4 introduces statically typed arrays and dictionaries.

  • Array: var enemies: Array[Enemy] = []
  • Dictionary: var spawn_rates: Dictionary[StringName, float] = {}

3. Explicit Return Types

Always specify the return type, even if it is void.

  • func take_damage(amount: int) -> void:

4. Safe Casting (as)

Use the as keyword to guarantee a type and get "safe lines" (green line numbers in the editor).

  • var timer := $Timer as Timer

5. Enforce Strictness

In Project Settings > Debug > GDScript, set Untyped Declaration to Warn or Error.

Expert Foundation Architectures

1. Scene Transition Manager (Threaded)

Avoid blocking the main thread during scene changes by using ResourceLoader.load_threaded_request(). This allows you to show an animated loading screen while the background thread parses the next level.

class_name SceneManager extends Node
## Autoload: Manages threaded scene transitions.

signal progress_updated(percent: float)
var _target_path: String = ""

func load_scene(path: String) -> void:
    _target_path = path
    if ResourceLoader.load_threaded_request(path) == OK:
        set_process(true)

func _process(_delta: float) -> void:
    var progress := []
    var status := ResourceLoader.load_threaded_get_status(_target_path, progress)
    
    match status:
        ResourceLoader.THREAD_LOAD_IN_PROGRESS:
            progress_updated.emit(progress[0] * 100)
        ResourceLoader.THREAD_LOAD_LOADED:
            var scene := ResourceLoader.load_threaded_get(_target_path) as PackedScene
            get_tree().change_scene_to_packed(scene)
            set_process(false)

2. Global Event Bus (Decoupled)

Maintain strict decoupling by using a global "Event Bus" Autoload. This allows distant systems (e.g., UI and Boss AI) to communicate without knowing each other's existence.

class_name EventBus extends Node
## Autoload: Central hub for global signals.

signal player_died
signal quest_completed(quest_id: String)
signal boss_phase_changed(new_phase: int)

# Usage (Publisher):
# EventBus.player_died.emit()

# Usage (Subscriber):
# EventBus.player_died.connect(_on_player_death)

3. Project Metadata (Resource-Based)

Centralize project info like versioning, build dates, and feature flags in a dedicated Resource. This is type-safe and more performant than parsing raw JSON/TXT files.

class_name ProjectMetadata extends Resource
## Data container for project-wide configuration.

@export var version: String = "1.0.0"
@export var build_date: String = "2026-04-30"
@export var debug_mode: bool = false

func save_metadata(path: String = "user://metadata.res") -> void:
    ResourceSaver.save(self, path)

static func load_metadata(path: String = "user://metadata.res") -> ProjectMetadata:
    if ResourceLoader.exists(path):
        return ResourceLoader.load(path) as ProjectMetadata
    return ProjectMetadata.new()

Reference

  • Official Docs: tutorials/best_practices/project_organization.rst
  • Official Docs: tutorials/best_practices/scene_organization.rst

Related

  • Master Skill: godot-master

Related skills

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.