Skills に戻る
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.