4.8 KiB
4.8 KiB
| name | description | license | compatibility | metadata | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| godot-gdscript-patterns | GDScript best practices for Godot 4.x: node composition, typed signals, scene instantiation, resource management, singletons, event buses, and common design patterns. Use when writing or reviewing GDScript code in Godot. | MIT |
|
|
GDScript Patterns for Godot 4.x
Best practices and patterns for writing clean, maintainable GDScript code.
Node Hierarchy Best Practices
Composition Over Inheritance
# Good: Small, focused scenes composed together
# Player.tscn contains:
# - CharacterBody2D (root)
# - Sprite2D (visual)
# - CollisionShape2D (physics)
# - AnimatedSprite2D (animation)
# - HealthComponent (Node — logic)
# - InventoryComponent (Node — logic)
# Avoid: Deep inheritance chains
# Player extends CharacterBody2D extends Node2D...
Scene Instantiation Patterns
# preload() — Compile-time, for always-needed resources
@onready var bullet_scene = preload("res://scenes/entities/bullet.tscn")
# load() — Runtime, for conditional loading
var dialog_scene = load("res://scenes/ui/dialog.tscn")
# instantiate() — Create instance from scene
func spawn_bullet():
var bullet = bullet_scene.instantiate()
add_child(bullet)
Typed Signals (Godot 4.x)
Declaring Typed Signals
# Godot 4.x typed signal syntax
signal health_changed(new_health: int, max_health: int)
signal player_died(position: Vector2)
signal item_collected(item_data: Resource)
Connecting Signals
# Auto-connect in editor (rename method to on_NodeName_signal)
func _on_health_changed(new_health: int, _max_health: int):
update_health_bar(new_health)
# Manual connection
func _ready():
enemy.health_depleted.connect(_on_enemy_defeated)
# Callable syntax (Godot 4.x)
button.pressed.connect(func: do_something())
Scene Loading Patterns
Resource Loading
# Preload for compile-time constants
const PlayerScene = preload("res://scenes/entities/player.tscn")
# Load for runtime/conditional loading
func load_level(level_name: String):
var path = "res://levels/%s.tscn" % level_name
var scene = load(path)
if scene:
current_level = scene.instantiate()
add_child(current_level)
Resource Management
# Use Resource for game data
@export_file("*.tres") var player_data: String
var data: PlayerData = load(player_data) as PlayerData
# Scene packs for level data
var level_pack = preload("res://resources/data/level_pack.tscn")
Common Patterns
Singleton (Autoload) Pattern
# Add to Project Settings > Autoload as "GameData"
class_name GameData extends Node
var player_score: int = 0
var high_score: int = 0
func add_score(points: int):
player_score += points
if player_score > high_score:
high_score = player_score
Event Bus Pattern
# Add to Project Settings > Autoload as "EventBus"
class_name EventBus extends Node
signal game_started()
signal level_completed(level_id: int)
signal player_died()
signal game_paused(paused: bool)
# Usage in any script
func _ready():
EventBus.level_completed.connect(on_level_completed)
Node Path Best Practices
# Good: Use @onready for scene tree paths
@onready var health_bar = $UI/HealthBar as ProgressBar
@onready var sprite = $Sprite2D as Sprite2D
# Avoid: Hardcoded paths
var health_bar = get_node("UI/HealthBar") # Fragile to hierarchy changes
Godot 4.7 GDScript Notes
- DrawableTexture2D — Create dynamic textures at runtime for procedural rendering
- tween_await() — Use await with tweens for sequential animations
- Typed signals are now the standard — prefer typed over untyped
MCP Bridge Tools (Optional — Live Editor Integration)
When the MCP bridge is running (Phase 2), these tools can inspect and modify your project live:
script_read— Read any script file from the projectscript_edit— Write updated script contents directly to diskscript_validate— Validate GDScript syntax withsuggestTweenAwait: truefor Godot 4.7 migrationscene_tree— Inspect the current scene hierarchyclass_db_info— Query available methods/properties on any Godot class
Note: MCP tools require the Godot editor to be running with the MCP plugin enabled. Skills work independently without the bridge.