GDScript Mastery
Expert guidance for writing performant, maintainable GDScript following official Godot standards.
NEVER Do
- NEVER use dynamic typing for performance-critical code —
var x = 5is 20-40% slower thanvar x: int = 5. Type everything. - NEVER call parent methods from children ("Call Up") — Use "Signal Up, Call Down". Children emit signals, parents call child methods.
- NEVER use
get_node()in_process()or_physics_process()— Caches with@onready var sprite = $Sprite. get_node() is slow in loops. - NEVER access dictionaries without
.get()default —dict["key"]crashes if missing. Usedict.get("key", default)for safety. - NEVER skip
class_namefor reusable scripts — Withoutclass_name, you can't use as type hints (var item: Item). Makes code harder to maintain.
Available Scripts
MANDATORY: Read the appropriate script before implementing the corresponding pattern.
advanced_lambdas.gd
Higher-order functions in GDScript: filter/map with lambdas, factory functions returning Callables, typed array godot-composition, and static utility methods.
type_checker.gd
Scans codebase for missing type hints. Run before releases to enforce static typing standards.
performance_analyzer.gd
Detects performance anti-patterns: get_node() in loops, string concat, unsafe dict access.
signal_architecture_validator.gd
Enforces "Signal Up, Call Down" pattern. Detects get_parent() calls and untyped signals.
Do NOT Load performance_analyzer.gd unless profiling hot paths or optimizing frame rates.
Core Directives
1. Strong Typing
Always use static typing. It improves performance and catches bugs early.
Rule: Prefer var x: int = 5 over var x = 5.
Rule: Always specify return types for functions: func _ready() -> void:.
2. Signal Architecture
- Connect in
_ready(): Preferably connect signals in code to maintain visibility, rather than just in the editor. - Typed Signals: Define signals with types:
signal item_collected(item: ItemResource). - Pattern: "Signal Up, Call Down". Children should never call methods on parents; they should emit signals instead.
3. Node Access
- Unique Names: Use
%UniqueNamesfor nodes that are critical to the script's logic. - Onready Overrides: Prefer
@onready var sprite = %Sprite2Dover callingget_node()in every function.
4. Code Structure
Follow the standard Godot script layout:
extendsclass_namesignals/enums/constants@export/@onready/properties_init()/_ready()/_process()- Public methods
- Private methods (prefixed with
_)
Common "Architect" Patterns
The "Safe" Dictionary Lookup
Avoid dict["key"] if you aren't 100% sure it exists. Use dict.get("key", default).
Scene Unique Nodes
When building complex UI, always toggle "Access as Scene Unique Name" on critical nodes (Labels, Buttons) and access them via %Name.
Reference
- Official Docs:
tutorials/scripting/gdscript/gdscript_styleguide.rst - Official Docs:
tutorials/best_practices/logic_preferences.rst
Related
- Master Skill: godot-master