← Back to list
✍️

godot-gdscript Checked

Write idiomatic GDScript for Godot 4.7: static typing, the node lifecycle (_ready/_process/_physi…
✍️ Writing skills By gamedev-skills Version v1.0.0 Added 2026-10-21 Updated 2026-10-21 Source ↗
7.7Overall rating
0Views
0Downloads
2.0kStars

Installation

🤖 Install via AI

Copy the prompt below and send it to your AI assistant (e.g. Claude Code) — it will follow the instructions and install automatically.

Install the "godot-gdscript" skill by following the instructions at https://skill123.me/install/godot-gdscript.
⌨️ Command line install

Run in your terminal — downloads and installs to ~/.claude/skills/.

curl -fsSL https://skill123.me/install/godot-gdscript.sh | bash
📦 Download ZIP

Download the zip and extract it into your skills directory (e.g. ~/.claude/skills/), then restart your session.

⬇ Download v1.0.0 · 5 KB
📊 Static rating
7.7/10
Trigger
8.0
Structure
0.0
Workflow
8.0
Content
0.0
Engineering
0.0
Security
7.0

Six-dimension rubric with reviewer rationale.

View scorecard ↓
🛡 Dynamic test
—

Not live-tested yet — this skill is rated on static analysis only.

About this skill

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).

Documentation

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


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)


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
View full documentation

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)

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

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.

Score breakdown

Trigger
8.0
Structure
0.0
Workflow
8.0
Content
0.0
Engineering
0.0
Security
7.0