gamedev-skills/awesome-gamedev-agent-skillsチェック済み
SKILL DETAIL
godot-gdscript
gamedev-skills/awesome-gamedev-agent-skills/godot-gdscript
Write idiomatic GDScript for Godot 4.7: static typing, the node lifecycle (_ready/_process/_physics_process), @export/@onready/@tool annotations, signals, and await for asynchronous flow. Use when editing .gd scripts in a Godot project (project.godot), writing or debugging GDScript, or porting 3.x GDScript to 4.x (function signatures, yield to await, export to @export).
インストール · 298出典を見る
Installation
npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-gdscript
スキルファイル
SKILL.md
最終同期 · 2026/10/22
references/annotations-and-typing.md›
# GDScript annotations & typing reference (Godot 4.7)
Depth companion to `godot-gdscript`. All annotations start with `@` in GDScript 2.0.
## Common export annotations
```gdscript
@export var title: String = "Level 1"
@export var enabled := true
@export_range(0, 100, 1) var percent: int = 50 # min, max, step
@export_range(0.0, 1.0, 0.01, "or_greater") var gain := 1.0
@export_enum("Idle", "Walk", "Run") var state: int # int-backed dropdown
@export_enum("Sword", "Bow") var weapon: String # string-backed dropdown
@export_flags("Fire", "Water", "Earth") var resist: int # bitmask
@export_file("*.json") var data_path: String # file picker
@export_dir var folder: String
@export_multiline var description: String # multi-line text box
@export_color_no_alpha var tint: Color
@export_node_path("Camera2D") var cam_path: NodePath
@export_group("Movement") # groups Inspector fields
@export var speed := 200.0
@export_subgroup("Air")
@export var air_control := 0.4
```
Export a typed array of resources (great for data-driven design):
```gdscript
@export var waves: Array[PackedScene] = []
@export var loot: Array[ItemResource] = []
```
## Other annotations
- `@onready var x = $Child` — assign when the node enters the tree.
- `@tool` — run the script in the editor (top of file). Guard editor-only code with
`if Engine.is_editor_hint():`.
- `@icon("res://icon.svg")` — custom Inspector icon for a `class_name` type.
- `@rpc("any_peer", "call_local", "reliable")` — mark a networked method (see
`godot-multiplayer`).
- `@warning_ignore("unused_variable")` — silence a specific parser warning.
- `@static_unload` — allow a script's static variables to unload.
## Static typing details
```gdscript
var a: int = 3 # explicit type
var b := 3 # inferred int via :=
var c: float # typed, defaults to 0.0
var nodes: Array[Node2D] = [] # typed array (element type enforced)
var scores: Dictionary = {} # Dictionary is untyped in 4.3; typed dicts arrived in 4.4
func clamp_hp(hp: int) -> int:
return clampi(hp, 0, 100) # clampi/clampf are typed variants
```
Typed code is faster because the VM can skip runtime type checks, and the editor can
autocomplete and flag mismatches before you run.
## Lifecycle callbacks (order)
1. `_init()` — object constructed (no tree, no children resolved).
2. `_enter_tree()` — node added to the tree (children may not be ready).
3. `_ready()` — node and all children are in the tree (runs once). `@onready` vars are
assigned just before this.
4. `_process(delta)` — every rendered frame (skip with `set_process(false)`).
5. `_physics_process(delta)` — every fixed physics tick (default 60 Hz).
6. `_exit_tree()` — node removed from the tree.
7. `_notification(what)` — low-level catch-all (e.g. `NOTIFICATION_WM_CLOSE_REQUEST`).
## Idioms
- Prefer `is_instance_valid(node)` before touching a node that may have been freed.
- Use `queue_free()` (deferred) over `free()` to delete a node safely during a frame.
- `match` is GDScript's switch: supports values, arrays `[1, var x]`, and `_` default.
- String formatting: `"%s scored %d" % [name, score]`.
- Use `assert(cond, "msg")` for debug-only invariants (stripped in release builds).
SKILL.md›
---
name: godot-gdscript
description: >
Write idiomatic GDScript for Godot 4.7: static typing, the node lifecycle
(_ready/_process/_physics_process), @export/@onready/@tool annotations,
signals, and await for asynchronous flow. Use when editing .gd scripts in a
Godot project (project.godot), writing or debugging GDScript, or porting 3.x
GDScript to 4.x (function signatures, yield to await, export to @export).
---
# Godot GDScript (4.x)
Write correct, statically typed GDScript and use the node lifecycle and signal
system the way the engine intends. Targets **Godot 4.7** (GDScript 2.0).
## When to use
- Use when writing or fixing `.gd` files: declaring variables, functions, classes,
using `@export`/`@onready`, connecting signals, or awaiting coroutines/signals.
- Use when porting Godot 3.x scripts to 4.x and the script no longer parses.
**When *not* to use:** scene/node structure and instancing questions →
`godot-nodes-scenes`; signal *architecture*/decoupling patterns →
`godot-signals-groups`; using C# instead of GDScript → `godot-csharp`.
## Core workflow
1. **Type everything you can.** GDScript 2.0 supports static types
(`var hp: int = 10`, `func add(a: int, b: int) -> int:`). Types catch errors at
parse time and speed up the VM. Use `:=` for inferred types.
2. **Use the lifecycle callbacks for their purpose:** `_ready()` once when the node
and its children enter the tree; `_process(delta)` every rendered frame;
`_physics_process(delta)` on the fixed physics tick (use it for movement/physics).
3. **Grab node references with `@onready`**, not in `_init()` — children do not exist
until the node enters the tree.
4. **Expose tunables with `@export`** so designers edit them in the Inspector.
5. **React to events with signals + `await`**, not polling, where it reads cleanly.
6. **Run and read errors.** The Debugger panel prints typed errors with line numbers;
fix the first error first (later ones are often cascades).
## Patterns
### 1. A typed script with lifecycle, @export, and @onready
```gdscript
extends Node2D
class_name Spinner # registers a global type usable in other scripts
@export var speed: float = 90.0 # editable in the Inspector (degrees/sec)
@export_range(0, 10, 0.5) var wobble := 2.0
@onready var sprite: Sprite2D = $Sprite2D # resolved when the node enters the tree
func _ready() -> void:
# Runs once, after children are ready. Safe to touch $Sprite2D here.
sprite.modulate = Color.AQUA
func _process(delta: float) -> void:
# delta is seconds since last frame; multiply rates by it for FPS independence.
rotation_degrees += speed * delta
```
### 2. Signals: declare, emit, connect (4.x Callable syntax)
```gdscript
extends Node
signal health_changed(current: int, maximum: int) # typed signal params
var health := 100
func take_damage(amount: int) -> void:
health = max(health - amount, 0)
health_changed.emit(health, 100) # 4.x: emit as a method on the signal
func _ready() -> void:
# 4.x: connect with a Callable, not a string method name.
health_changed.connect(_on_health_changed)
func _on_health_changed(current: int, maximum: int) -> void:
print("HP: %d/%d" % [current, maximum])
```
### 3. await — pause until a timer or signal fires (replaces 3.x yield)
```gdscript
func flash_then_continue() -> void:
modulate = Color.RED
await get_tree().create_timer(0.2).timeout # resume after 0.2s
modulate = Color.WHITE
# await any signal: var result = await some_node.some_signal
```
### 4. Lambdas, typed arrays, and safe access
```gdscript
var enemies: Array[Node] = [] # typed array
func cull_dead() -> void:
enemies = enemies.filter(func(e): return e.is_inside_tree())
func get_first_name(d: Dictionary) -> String:
return d.get("name", "unknown") # default avoids missing-key errors
```
## Pitfalls
- **3.x → 4.x signal API changed.** `emit_signal("x")` still works but prefer
`x.emit(...)`; `connect("x", self, "_on_x")` is gone — use `x.connect(_on_x)` with a
Callable. `yield(obj, "sig")` is now `await obj.sig`.
- **`export var` is now `@export var`** (annotation). Likewise `onready`→`@onready`,
`tool`→`@tool`, `remote`/`master` RPC keywords → the `@rpc(...)` annotation.
- **`@onready` and `$NodePath` in `_init()` fail** — the node isn't in the tree yet.
Initialize node references in `_ready()` or with `@onready`.
- **Integer division truncates.** `5 / 2 == 2`. Use `5.0 / 2` or cast to `float`.
- **`_process` vs `_physics_process`.** Put `move_and_slide()` and physics in
`_physics_process(delta)`; using `_process` makes motion frame-rate dependent.
- **`class_name` must be unique** project-wide and is required to use the type name in
other scripts or as an Inspector type.
## References
- For the full annotation list, advanced typing, and style conventions, read
`references/annotations-and-typing.md`.
## Related skills
- `godot-nodes-scenes` — the scene tree, instancing, and autoloads.
- `godot-signals-groups` — event-driven architecture with signals and groups.
- `godot-resources` — data-driven design with custom `Resource` types.
- `godot-csharp` — the same engine concepts using C#/.NET.