godot-gdscript
gamedev-skills/awesome-gamedev-agent-skills
Write idiomatic GDScript 2.0 for Godot 4.7 with static typing, lifecycle callbacks, and signals.
What is godot-gdscript?
Master GDScript for Godot 4.7, including static typing, node lifecycle (_ready/_process/_physics_process), @export/@onready annotations, signals, and await for async flow. Use when writing or debugging .gd scripts, or porting Godot 3.x scripts to 4.x.
- Write statically typed GDScript with type inference and compile-time error checking
- Use node lifecycle callbacks (_ready, _process, _physics_process) correctly for their intended purpose
- Declare and connect signals with typed parameters using 4.x Callable syntax
- Pause execution with await for timers and signals instead of 3.x yield
- Expose inspector-editable variables with @export and resolve node references with @onready
- Port Godot 3.x GDScript to 4.x (yield→await, export→@export, signal API changes)
How to install godot-gdscript
npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-gdscript- Godot 4.7 installed with a project.godot file
- Basic familiarity with GDScript syntax or similar dynamically-typed languages
How to use godot-gdscript
- 1.Open or create a .gd script in your Godot project
- 2.Declare variables with explicit types (e.g., var hp: int = 10) and use @export for Inspector exposure
- 3.Implement _ready() for one-time initialization and _process(delta) or _physics_process(delta) for per-frame updates
- 4.Use @onready to resolve node references ($NodePath) after the node enters the tree
- 5.Define signals with typed parameters and emit them as methods (signal_name.emit(...))
- 6.Connect signals using Callables (signal_name.connect(callback_function)) and use await to pause for timers or signals
Use cases
- Writing movement and physics code in _physics_process for frame-rate independent gameplay
- Declaring health/damage systems with typed signals that emit and connect with Callables
- Creating inspector-tunable game parameters with @export and @export_range annotations
- Implementing async sequences like timed effects or waiting for player input with await
- Debugging parse errors and type mismatches in the Godot Debugger panel
- Game developers writing Godot 4.x gameplay scripts
- Developers porting Godot 3.x projects to Godot 4.x
- Game designers using @export to tune game balance in the Inspector
- Anyone debugging GDScript parse or runtime errors in Godot 4.7
godot-gdscript FAQ
Use _process(delta) for rendering and input-driven logic; use _physics_process(delta) for movement, move_and_slide(), and physics interactions. Physics runs on a fixed tick independent of frame rate.
Replace yield(obj, "signal") with await obj.signal and yield(get_tree(), "timeout") with await get_tree().create_timer(seconds).timeout.
Child nodes do not exist in the scene tree during _init(). Use @onready or initialize node references in _ready() instead.
Use the Callable syntax: signal_name.connect(callback_function). The old string-based connect("signal", self, "_method") is deprecated.
class_name registers a script as a global type usable in other scripts and the Inspector. It must be unique project-wide and is required to reference the type by name.
Full instructions (SKILL.md)
Source of truth, from gamedev-skills/awesome-gamedev-agent-skills.
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
.gdfiles: 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
- 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. - 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). - Grab node references with
@onready, not in_init()— children do not exist until the node enters the tree. - Expose tunables with
@exportso designers edit them in the Inspector. - React to events with signals +
await, not polling, where it reads cleanly. - 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
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 preferx.emit(...);connect("x", self, "_on_x")is gone — usex.connect(_on_x)with a Callable.yield(obj, "sig")is nowawait obj.sig. export varis now@export var(annotation). Likewiseonready→@onready,tool→@tool,remote/masterRPC keywords → the@rpc(...)annotation.@onreadyand$NodePathin_init()fail — the node isn't in the tree yet. Initialize node references in_ready()or with@onready.- Integer division truncates.
5 / 2 == 2. Use5.0 / 2or cast tofloat. _processvs_physics_process. Putmove_and_slide()and physics in_physics_process(delta); using_processmakes motion frame-rate dependent.class_namemust 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 customResourcetypes.godot-csharp— the same engine concepts using C#/.NET.
Related skills
More from gamedev-skills/awesome-gamedev-agent-skills and the wider catalog.

godot-multiplayer
Build networked Godot 4.7 games with ENet, RPCs, and state replication.

godot-nodes-scenes
Structure Godot 4.x games with scenes, nodes, and runtime instancing.

godot-physics
Configure Godot 4.x physics bodies, collision layers/masks, overlap detection, and raycasts in 2D and 3D.

godot-resources
Design data-driven Godot 4.7 games with custom Resource classes and .tres/.res files.

godot-shaders
Write Godot 4.7 shaders (2D canvas_item and 3D spatial) with uniforms, TIME animation, and screen-reading.

godot-signals-groups
Decouple Godot 4.x gameplay with signals and node groups instead of hard-coded references.