Typed GDScript — the house contract
These rules apply to every line of GDScript in the projects on this site — the curricula link here rather than restating them — and they are worth adopting in yours.
The six rules#
- Every variable is typed —
var speed: float = 90.0— or type-inferred only when the right side makes the type obvious:var direction := Vector2.ZERO. - Every function is fully typed, including
-> void:func till(cell: Vector2i) -> bool: - Typed containers:
Array[int],Array[Texture2D],Dictionary[Vector2i, PlotState](typed dictionaries need Godot 4.4+). An untypedArrayis a bug you haven't met yet. - Enums over strings for any closed set of values:
enum State { IDLE, WALK, USE_TOOL }. A typo'd string fails silently at runtime; a typo'd enum fails at parse time. - Warnings turned up: Project Settings →
debug/gdscript/warnings/untyped_declaration→ Warn. The editor becomes the enforcement; a stage/feature isn't done while the panel shows warnings. @exportwith types so the Inspector constrains what can be assigned:@export var data: CropData.
Why (the one-paragraph version)#
Typed GDScript catches whole bug classes at parse time, unlocks precise autocomplete, and runs faster (typed opcodes) — but the speed is a bonus, not the reason. The reason is that types are statements of intent the editor can check while you're learning: every warning is a misconception surfacing early, at the cheapest possible moment.
The traps the contract prevents#
| Trap | Untyped symptom | Typed behavior |
|---|---|---|
| Stringly-typed channels | judged.emit("prefect") scores nothing, silently | enum member typo won't parse |
| Variant drift | an Array of mixed junk works until it doesn't | Array[NoteData] rejects at assignment |
| Wrong-space vectors | Vector2 where Vector2i cell math expected — off-by-subpixel bugs | signature mismatch flagged in-editor |
Silent null flow | crash three calls away from the cause | typed returns force the null question at the boundary |