Skill v1.0.1
currentAutomated scan100/1001 files
version: "1.0.1" name: godot-project-templates description: "Expert blueprint for genre-specific project boilerplates (2D platformer, top-down RPG, 3D FPS) including directory structures, AutoLoad patterns, and core systems. Use when bootstrapping new projects or migrating architecture. Keywords project templates, boilerplate, 2D platformer, RPG, FPS, AutoLoad, scene structure."
Project Templates
Genre-specific scaffolding, AutoLoad patterns, and modular architecture define rapid prototyping.
Available Scripts
base_game_manager.gd
Expert AutoLoad template for game state management.
base_level.gd
Abstract base class for all loaded levels with structured lifecycle hooks.
base_actor.gd
Expert foundation for all gameplay agents (Player, NPC, Enemies).
base_menu.gd
UI foundation for focus persistence, animations, and input blocking.
subsystem_locator.gd
Decoupled alternative to monolithic managers for modular registration.
multi_platform_input.gd
Template-driven Input Mapping for hardware-aware profile overrides.
platform_feature_config.gd
Conditional platform logic using Godot Feature Tags.
scene_state_machine.gd
Node-based State Machine boilerplate for visual state logic.
state_machine_node.gd
Abstract state node foundation for specialized state components.
accessibility_tts_manager.gd
Accessibility & Localization foundation using native TTS API.
level_steamer_manager.gd
Background level-loading template using load_threaded_request.
NEVER Do (Expert Anti-Patterns)
Directory & Scaffolding
- NEVER hardcode scene paths —
get_tree().change_scene_to_file("res://levels/level_1.tscn")in 20 places? Nightmare refactoring. Use AutoLoad + constants OR scene registry. - NEVER skip .gdignore for asset folders — Designer internal project files should never be imported into res:// directly.
Architecture & Lifecycle
- NEVER use `get_tree().paused` without groups — Pausing entire tree = pause menu freezes. Use process mode
PROCESS_MODE_ALWAYSon UI. - NEVER skip virtual lifecycle hooks — In base classes, always provide
_initialize_X()hooks instead of just_ready()to allow child overrides without breaking parents. - NEVER rely on monolithic "God" singletons — Decouple systems using a Signal Bus or Subsystem Locator.
Platform & UI
- NEVER skip Input.MOUSE_MODE_CAPTURED in FPS — Set in player
_ready()to ensure focus. - NEVER use floating point constants for UI layout — Leads to drift. Use anchors and containers.
- NEVER ignore i18n Translation Context — "Lead" (Metal) vs "Lead" (Action). Strictly use contexts in
translate().
Performance
- NEVER load massive levels synchronously — Causes frame freezes. Strictly use
ResourceLoader.load_threaded_request(). - NEVER copy-paste templates as-is — Using platformer template for RPG? Leads to debt. UNDERSTAND the structure, then adapt.
Directory Structure
my_platformer/├── project.godot├── autoloads/│ ├── game_manager.gd│ ├── audio_manager.gd│ └── scene_transitioner.gd├── scenes/│ ├── main_menu.tscn│ ├── game.tscn│ └── pause_menu.tscn├── entities/│ ├── player/│ │ ├── player.tscn│ │ ├── player.gd│ │ └── player_states/│ └── enemies/│ ├── base_enemy.gd│ └── goblin/├── levels/│ ├── level_1.tscn│ └── tilesets/├── ui/│ ├── hud.tscn│ └── themes/├── audio/│ ├── music/│ └── sfx/└── resources/└── data/
Core Scripts
game_manager.gd:
extends Nodesignal game_startedsignal game_paused(paused: bool)signal level_completedvar current_level: int = 1var score: int = 0var is_paused: bool = falsefunc start_game() -> void:score = 0current_level = 1SceneTransitioner.change_scene("res://levels/level_1.tscn")game_started.emit()func pause_game(paused: bool) -> void:is_paused = pausedget_tree().paused = pausedgame_paused.emit(paused)func complete_level() -> void:current_level += 1level_completed.emit()
Top-Down RPG Template
Directory Structure
my_rpg/├── autoloads/│ ├── game_data.gd│ ├── dialogue_manager.gd│ └── inventory_manager.gd├── entities/│ ├── player/│ ├── npcs/│ └── interactables/├── maps/│ ├── overworld/│ ├── dungeons/│ └── interiors/├── systems/│ ├── combat/│ ├── dialogue/│ ├── quests/│ └── inventory/├── ui/│ ├── inventory_ui.tscn│ ├── dialogue_box.tscn│ └── quest_log.tscn└── resources/├── items/├── quests/└── dialogues/
Core Systems
inventory_manager.gd:
extends Nodesignal item_added(item: Resource)signal item_removed(item: Resource)var inventory: Array[Resource] = []func add_item(item: Resource) -> void:inventory.append(item)item_added.emit(item)func remove_item(item: Resource) -> bool:if item in inventory:inventory.erase(item)item_removed.emit(item)return truereturn falsefunc has_item(item_id: String) -> bool:for item in inventory:if item.id == item_id:return truereturn false
3D FPS Template
Directory Structure
my_fps/├── autoloads/│ ├── game_manager.gd│ └── weapon_manager.gd├── player/│ ├── player.tscn│ ├── player.gd│ ├── camera_controller.gd│ └── weapons/│ ├── weapon_base.gd│ ├── pistol/│ └── rifle/├── enemies/│ ├── ai_controller.gd│ └── soldier/├── levels/│ ├── level_1/│ └── level_2/├── ui/│ ├── hud.tscn│ └── crosshair.tscn└── resources/├── weapons/└── pickups/
Player Controller
player.gd:
extends CharacterBody3D@export var speed := 5.0@export var jump_velocity := 4.5var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")@onready var camera: Camera3D = $Camera3D@onready var weapon_holder: Node3D = $Camera3D/WeaponHolderfunc _ready() -> void:Input.mouse_mode = Input.MOUSE_MODE_CAPTUREDfunc _physics_process(delta: float) -> void:if not is_on_floor():velocity.y -= gravity * deltaif Input.is_action_just_pressed("jump") and is_on_floor():velocity.y = jump_velocityvar input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_backward")var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()if direction:velocity.x = direction.x * speedvelocity.z = direction.z * speedelse:velocity.x = move_toward(velocity.x, 0, speed)velocity.z = move_toward(velocity.z, 0, speed)move_and_slide()
Input Map Template
# All templates should include these actions:[input]move_left=Keys: A, Left, Gamepad Leftmove_right=Keys: D, Right, Gamepad Rightmove_up=Keys: W, Up, Gamepad Upmove_down=Keys: S, Down, Gamepad Downjump=Keys: Space, Gamepad Ainteract=Keys: E, Gamepad Xpause=Keys: Escape, Gamepad Startui_accept=Keys: Enter, Gamepad Aui_cancel=Keys: Escape, Gamepad B
Usage
- Copy template structure
- Rename project in
project.godot - Register AutoLoads
- Configure Input Map
- Begin development
Expert Template Patterns
1. Folder-by-Feature (Entity-Centric)
The professional standard for scalable Godot project organization.
- The Rule: Keep all resources related to a game entity (scripts, scenes, textures, local resources) in the same directory (e.g.,
res://entities/player/). - Benefit: Simplifies refactoring, enables easier asset migration between projects, and prevents the "monolithic scripts folder" bottleneck.
2. Standard-Export-Presets (Platform Stability)
Optimized configurations for high-fidelity exports.
- VRAM Compression: Ensure
textures/vram_compression/import_etc2_astcis enabled for Android/mobile compatibility. - Architecture: Target
x86_64for Windows/Linux desktop andarm64-v8afor modern Android devices. - Feature Tags: Use custom feature tags (e.g.,
mobile,low_end) to conditionally load lower-resolution assets or simplified shaders at runtime.
- Versioning: Add
.importfiles to version control; they contain the vital metadata that tells Godot how to process your raw assets.
4. CI/CD-Ready Pipeline (GitHub Actions)
Automate builds headlessly using CLI flags. This ensures consistent binaries and early detection of export errors [3, 16, 17].
# .github/workflows/export.ymljobs:export:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Export Windowsrun: godot --headless --export-release "Windows Desktop" build/game.exe
5. Modular-DLC Structure (PCK Mounting)
Deliver content updates or patches without exposing source code. Use ProjectSettings.load_resource_pack() to mount external assets into res:// [4, 6].
func load_dlc(path: String):if ProjectSettings.load_resource_pack(path):# Assets in PCK override existing res:// pathsvar new_scene = load("res://dlc_level.tscn")
6. System-Bootstrap-Priority
Control AutoLoad initialization order using a central BootstrapManager. This replaces the linear Project Settings list with a prioritized script [19, 20].
# BootstrapManager.gd (The only Autoload)func _ready():# 1. Start Critical Systems (Network, Config)_add_system(NetworkManager.new())# 2. Start Secondary Systems (Audio, UI)_add_system(AudioManager.new())
Reference
Related
- Master Skill: godot-master