GDScript Notes

Language quirks we hit coming from C# / Python / Java.

stablegdscriptgodot
On this page

Concise. Only what showed up in this codebase.

Variables and types

var speed := 120                 # inferred int
var lines: Array[Dictionary] = []
const STAND_SPACING := 60.0
@export var guest_data: GuestData
@export_range(0, 1000) var speed := 120

Dynamic by default; annotations help the analyzer. Typed arrays are stricter than Python lists.

Functions and control flow

func _ready() -> void:
	pass

if vector == Vector2.ZERO:
	_play_idle()
elif absf(direction.x) >= absf(direction.y):
	_facing = "side"

match event.physical_keycode:
	KEY_1: set_time_speed(1.0)
	_: return

for turn in convo.turns:
	lines.append(...)

No traditional switch — use match.

Signals

signal dialog_closed
dialog_closed.emit()
dialog_box.dialog_closed.connect(_on_closed, CONNECT_ONE_SHOT)

Closer to C# events than Java listeners; connect with Callable.

Await

await get_tree().create_timer(2.0).timeout
await get_tree().physics_frame
await RenderingServer.frame_post_draw

Coroutines are first-class. Always re-check state after await (object may be gone; state may have changed).

Input

Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
event.is_action_pressed("interact")
get_viewport().set_input_as_handled()

StringName

Animation names often compare as StringName:

if $AnimatedSprite2D.animation != StringName(anim):
	$AnimatedSprite2D.play(anim)

class_name

class_name Guest
extends CharacterBody2D

Registers a global type (like a short import). Autoloads are separate (singleton instances).

Dictionaries as lightweight DTOs

Dialog lines are dicts, not a mandatory custom class:

{"speaker": "You", "text": "Hi", "is_player": true}

Fine for jam UI; use Resources when data is authored in bulk (conversations).

Unlike Python

  • Indentation matters, but static typing is optional/encouraged.
  • No list comprehensions like Python’s; build arrays imperatively.
  • load("res://...") is filesystem-in-project, not Python import.

Unlike C#

  • No async/await keywords pair — just await on signals/properties that expose completed states.
  • Node refs go null if freed — check is_instance_valid.