Top Level Namespace
Included Modules
Extended Modules
Defined in:
Method Summary
- after(delay : Time::Span | Number, node : Godot::Node | Nil = nil, &block : Godot::TimerHandle -> Void) : Godot::TimerHandle
-
crystal_godot_init(api : Pointer(Godot::LibBridge::BridgeAPI)) : Void
C ABI Entry point called by crystal_bridge when game library is loaded
-
every(interval : Time::Span | Number, node : Godot::Node | Nil = nil, &block : Godot::TimerHandle -> Void) : Godot::TimerHandle
Top-level gameplay convenience methods
-
group(name : String | Symbol) : Godot::GroupQuery
Global fluent group query helper
-
load(path : String, type_hint : String = "", cache_mode : Int64 = 0_i64) : Godot::Resource
Global convenience helper to load resources from Godot VFS
-
nodes(regex : Regex) : Array(Godot::Node)
Global query helper returning all nodes matching the regex under the active node context.
-
on_main_thread(&block : -> Void) : Void
Dispatches block to execute safely on the Godot Main Thread.
-
preload(path : String) : Godot::Resource
Global convenience helper to preload resources from Godot VFS
-
vec2(x : Number, y : Number) : Godot::Vector2
Top-level math constructors
- vec3(x : Number, y : Number, z : Number) : Godot::Vector3
- vec4(x : Number, y : Number, z : Number, w : Number) : Godot::Vector4
Macro Summary
-
__define_node_ref_property(name_or_decl, type = nil, path = nil, is_unique = false, is_nilable = false)
Declares a lazy-cached node property matching Godot's
@onreadypattern. -
abstract_class
Convenience macro to designate a class as abstract in Godot.
-
await(target, signal_name = nil, timeout_sec = nil)
Cooperatively awaits a signal, timer, or duration without blocking the engine main thread.
-
await!(target, signal_name = nil, timeout_sec = nil)
Cooperatively awaits a signal, timer, or duration, raising
Godot::DisposedObjectErrorif the target is freed orGodot::TimeoutErrorif timeout expires. -
await?(target, signal_name = nil, timeout_sec = nil)
Cooperatively awaits a signal, timer, or duration, returning nil if the target is freed, or nil (or false) if timeout expires.
-
await_until(condition, timeout_sec, &block)
Cooperatively yields the calling fiber until
conditionevaluates to truthy. -
await_while(condition, timeout_sec, &block)
Cooperatively yields the calling fiber while
conditionevaluates to truthy. -
build(type, **kwargs, &block)
Idiomatic alias for
create -
cold_boot_test(category, name, &block)
Dedicated declarative cold boot test macro
-
create(type, **kwargs, &block)
Instantiates a Godot object or custom node and configures its properties and methods in a block or kwargs.
-
create_child(type, under = nil, **kwargs, &block)
Declarative alias for
spawn_node - define_log_filter(name, **opts)
- define_log_filters(&block)
-
define_string_enum_export(macro_name, hint_string, default_fallback = "")
Defines a custom export macro
macro_namethat declares an exportedStringproperty withPROPERTY_HINT_ENUM(2_u32) andhint_stringin the Godot Inspector. -
delegate_property_to_instance(*prop_names)
Forwards class-level properties to the class singleton instance
-
delegate_to_instance(*method_names)
Forwards class-level methods to the class singleton instance (e.g.
-
emit(signal_expr, *args)
Type-safe signal emitter macro.
-
ensure_lapis
The primary
nodemacro: Usage: node MyNode node MyNode do # defaults to Godot::Node end -
export_category(name, &block)
Categorizes top-level inspector sections in Godot.
-
export_group(name, prefix = "", &block)
Groups exported properties under a common folding group in the Godot inspector.
-
export_subgroup(name, prefix = "", &block)
Subgroups exported properties under the current inspector group.
-
gdclass(decl, &block)
Declares a custom RefCounted or generic Godot engine class registered with ClassDB.
-
gmodule(decl, &block)
Declares a reusable Godot module or mixin registered with ClassDB metadata.
-
godot_bind(var_name, class_name, method_name, hash)
Lazily retrieves and caches a GDExtension method bind handle from ClassDB
-
godot_call_str(method_name, *args)
Dynamically calls an instance method and returns the result as a Crystal String
-
godot_collider_query(cls_name, indexed = false)
Synthesizes null-safe #get_collider? query on raycasts and shapecasts
-
godot_marshal_enum(name, idx)
Marshals an enum or integer argument into a typed 64-bit pointer for ptrcall
-
godot_marshal_nodepath(name, idx)
Marshals a NodePath or String argument into an unmanaged Godot NodePath pointer
-
godot_marshal_obj(name, idx)
Marshals a Godot Object wrapper into an unmanaged pointer-to-pointer for ptrcall
-
godot_marshal_str(name, idx)
Marshals a String argument into an unmanaged Godot String pointer
-
godot_marshal_string_name(name, idx)
Marshals a String or StringName argument into an interned StringName pointer
-
godot_marshal_val(name, idx)
Marshals a primitive scalar (Float, Int, Bool, Vector2/3, Color) for ptrcall
- godot_module(decl)
-
godot_prop(prop_name, getter_name, setter_name = nil)
Synthesizes an ergonomic getter and setter pair
-
godot_ptrcall(mb, target_ptr, args_slice, ret_ptr)
Executes a low-overhead GDExtension ptrcall
-
godot_ptrcall_bool(mb, target_ptr, args_slice)
Executes a ptrcall returning a boolean
-
godot_ptrcall_enum(mb, target_ptr, args_slice, enum_type)
Executes a ptrcall returning a strongly-typed enum
-
godot_ptrcall_float(mb, target_ptr, args_slice)
Executes a ptrcall returning a float (Float64 / Float32)
- godot_ptrcall_float32(mb, target_ptr, args_slice)
- godot_ptrcall_float64(mb, target_ptr, args_slice)
-
godot_ptrcall_int(mb, target_ptr, args_slice)
Executes a ptrcall returning an integer (Int64)
-
godot_ptrcall_obj(mb, target_ptr, args_slice, class_type)
Executes a ptrcall returning a typed object wrapper, reusing alive instance if present
-
godot_ptrcall_obj_or_nil(mb, target_ptr, args_slice, class_type)
Executes a ptrcall returning a typed object wrapper, or nil if Godot returned nullptr
-
godot_ptrcall_val(mb, target_ptr, args_slice, type_name)
Executes a ptrcall returning a value type with default constructor (e.g.
-
godot_ptrcall_void(mb, target_ptr, args_slice)
Executes a void ptrcall with no return buffer
-
godot_return_enum(enum_type, ret_var)
Instantiates a strongly-typed enum from a 64-bit ptrcall return buffer
-
godot_return_obj(class_type, ret_ptr)
Wraps a returned native object pointer into its typed Crystal wrapper
-
godot_signal(name, *types)
Synthesizes a first-class typed signal accessor, StaticSignalSlot view, and direct emission helper
-
godot_singleton(cls_name, godot_name, parent_type = Godot::Object)
Defines a Godot singleton accessor and pointer caching
-
godot_singleton_accessor(method_name, cls_name)
Emits top-level Godot module singleton helper
-
godot_static_call_str(method_name, *args)
Dynamically calls a static engine method and returns the result as a Crystal String
-
group(*group_names)
Declaratively assigns the node to one or more scene tree groups upon
_ready. -
icon(path)
Convenience macro to set a custom icon path in the editor.
-
instantiate(path, as type = Godot::Node, **kwargs, &block)
Loads a PackedScene (.tscn) and instantiates it as wrapper type T with configuration
-
instantiate_child(path, under = nil, as type = Godot::Node, **kwargs, &block)
Loads a PackedScene (.tscn), instantiates it as wrapper type T, and attaches it as a child to the parent
-
load(path)
Loads a resource dynamically from the Godot virtual filesystem with compile-time type inference.
-
load?(path)
Safe, nil-returning variant of
load(path). -
log_filter(name, **opts)
Re-export at top-level for maximum ergonomics
-
match(target, &block)
Expression-oriented pattern matching macro designed for concise, expressive gameplay scripting.
-
multiplayer_test(name, clients = 2, &block)
Dedicated declarative multiplayer simulation test macro
-
n!(path, type = nil)
Ultra-short alias for
node!(path, type). -
n?(path, type = nil)
Ultra-short alias for
node?(path, type). - node(decl, &block)
-
node!(path, type = nil)
Immediately retrieves a child node from the current node's scene hierarchy.
-
node2d(decl, &block)
Expressive convenience macro for 2D scene nodes defaulting to Godot::Node2D
-
node3d(decl, &block)
Expressive convenience macro for 3D spatial nodes defaulting to Godot::Node3D
-
node?(path, type = nil)
Safely retrieves a child node from the current node's scene hierarchy, returning
nilif not found. -
node_path!(path)
Creates a compile-time verified Godot::NodePath
-
node_ref(name_or_decl, type = nil, path = nil)
Declares a dead-pointer safe, lazy-cached node property matching Godot's
@onreadypattern. -
node_ref?(name_or_decl, type = nil, path = nil)
Declares a safe, lazy-cached node property that returns nil if missing or type mismatch.
-
on(sig_or_target, *args, once = false, &block)
Expressive signal connection macro
-
on_signal(sig_or_target, *args, once = false, &block)
Zero-allocation static signal connection macro binding compile-time typed procs or blocks directly to
StaticSignalTableslots. - onready(name_or_decl, type = nil, path = nil)
-
onready?(name_or_decl, type = nil, path = nil)
Declares a safe, lazy-cached node property that returns nil if missing or type mismatch.
-
play_sound(stream, at = nil, under = nil, **kwargs, &block)
Context-aware one-shot audio playback macro: - Inspects
@typeat compile-time: *@type <= Godot::Node2D-> emits AudioStreamPlayer2D with global_position *@type <= Godot::Node3D-> emits AudioStreamPlayer3D with global_position * Otherwise -> emits non-spatial AudioStreamPlayer - If explicitat:coordinate is passed (Vector2 or Vector3), spatializes appropriately - Automatically preloads or loads the AudioStream - Sets kwargs properties (e.g. -
preload(path)
Preloads and caches a resource from the Godot virtual filesystem with compile-time type inference.
-
preload?(path)
Safe, nil-returning variant of
preload(path). -
resource(decl, &block)
Declares a custom Godot Resource class registered with ClassDB and EditorHelp.
-
resource_card(decl, &block)
Declares a custom Resource strategy card.
-
signal(name_or_decl, *extra_types)
Declares a custom Godot signal with first-class typed signal accessors.
-
spawn_child(type, under = nil, **kwargs, &block)
Contextual alias for
spawn_node -
spawn_node(type, under = nil, **kwargs, &block)
Instantiates a node, configures it, and attaches it as a child to the specified parent (defaults to
selfif inside a Node method, or current scene / root). -
static_unload
Convenience macro to mark extension library unloading behavior.
-
test_case(category, name, cold_boot = false, &block)
Base test_case macro
-
test_suite(category, &block)
Declarative suite macro allowing grouped tests, parameterized tests, and suite/case lifecycle hooks
-
tween(target, &block)
Block-based tween DSL targeting specified node with compile-time type verification (e.g.
-
tween(&block)
Block-based tween DSL targeting self (e.g.
-
tween(property_expr, to value, in in_duration = 0.2.seconds, from from_val = nil, trans = Godot::Tween::TransitionType::TransLinear, ease = Godot::Tween::EaseType::EaseInOut)
Compile-time type-safe tween macro supporting dot-navigation (e.g.
-
u!(name, type = nil)
Ultra-short alias for
unique!(name, type). -
u?(name, type = nil)
Ultra-short alias for
unique?(name, type). -
unique!(name, type = nil)
Immediately retrieves a Scene Unique Node (Godot 4
%Nodesyntax). -
unique?(name, type = nil)
Safely retrieves a Scene Unique Node (Godot 4
%Nodesyntax), returningnilif not found. -
unique_node(name_or_decl, type = nil, unique_name = nil)
Declares a lazy-cached Scene Unique Node property (Godot 4
%Nodesyntax). -
unique_node?(name_or_decl, type = nil, unique_name = nil)
Declares a safe, lazy-cached Scene Unique Node property that returns nil if missing.
-
unique_node_ref(name_or_decl, type = nil, unique_name = nil)
Declares a dead-pointer safe, lazy-cached Scene Unique Node property (Godot 4
%Nodesyntax). -
unique_node_ref?(name_or_decl, type = nil, unique_name = nil)
Declares a safe, lazy-cached Scene Unique Node property that returns nil if missing.
-
warning_ignore(name)
Convenience macro to suppress compiler warnings.
- warning_ignore_restore(name)
- warning_ignore_start(name)
Instance methods inherited from module Lapis::Test
add_child_autofree(parent : Godot::Node, child : T) : T forall Tadd_child_autofree(child : T) : T forall T add_child_autofree, assert_alive(object : Godot::Object, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_alive, assert_approx_eq(actual : Float32 | Float64, expected : Float32 | Float64, epsilon : Float64 = 0.001, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_approx_eq, assert_between(actual : Number, min : Number, max : Number, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_between, assert_bytes_per_iteration(max_rate : Float64 | Number, name : String = "Operation", iterations : Int32 = 1000, warmup : Int32 = 10, file : String = __FILE__, line : Int32 = __LINE__, &) : Lapis::Profiler::AllocationReport assert_bytes_per_iteration, assert_child_count(node : Godot::Node, expected : Int32, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) : Void assert_child_count, assert_connected(emitter : Godot::Object, signal_name : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_connected, assert_disposed(object : Godot::Object, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_disposed, assert_emits(emitter : Godot::Object, signal_name : String, timeout_sec : Float64 = 2.0, file : String = __FILE__, line : Int32 = __LINE__, &) : Array(Variant) assert_emits, assert_empty(collection, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_empty, assert_eq(actual, expected, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_eq, assert_false(cond : Bool | Nil, msg : String = "Expected false, got true", file : String = __FILE__, line : Int32 = __LINE__) assert_false, assert_file_does_not_exist(path : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_file_does_not_exist, assert_file_empty(path : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_file_empty, assert_file_exists(path : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_file_exists, assert_file_not_empty(path : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_file_not_empty, assert_freed(object : Godot::Object, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_freed, assert_gt(actual : Comparable, expected : Comparable, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_gt, assert_gte(actual : Comparable, expected : Comparable, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_gte, assert_has_child(node : Godot::Node, name : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) : Void assert_has_child, assert_has_method(obj : Godot::Object, method_name : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_has_method, assert_has_node(parent : Godot::Node, path : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_has_node, assert_has_signal(emitter : Godot::Object, signal_name : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_has_signal, assert_in_delta(actual : Number, expected : Number, delta : Number, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_in_delta, assert_includes(collection, item, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_includes, assert_invalid_id(instance_id : UInt64 | Int64, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_invalid_id, assert_is_a(obj, klass : T.class, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) forall T assert_is_a, assert_lt(actual : Comparable, expected : Comparable, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_lt, assert_lte(actual : Comparable, expected : Comparable, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_lte, assert_max_allocations(max_bytes : Int64 | Int32, name : String = "Operation", iterations : Int32 = 1000, warmup : Int32 = 10, file : String = __FILE__, line : Int32 = __LINE__, &) : Lapis::Profiler::AllocationReport assert_max_allocations, assert_memory_stable(cycles : Int32 = 1, max_delta : Int32 = 2, name : String = "Memory Stability", file : String = __FILE__, line : Int32 = __LINE__, &block) assert_memory_stable, assert_ne(actual, expected, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_ne, assert_nil(val, msg : String = "Expected nil value", file : String = __FILE__, line : Int32 = __LINE__) assert_nil, assert_no_emit(emitter : Godot::Object, signal_name : String, duration_sec : Float64 = 0.5, file : String = __FILE__, line : Int32 = __LINE__, &) : Void assert_no_emit, assert_no_leak(max_delta_objects : Int32 = 0, name : String = "Operation", file : String = __FILE__, line : Int32 = __LINE__, &) assert_no_leak, assert_no_new_orphans(msg : String = "", file : String = __FILE__, line : Int32 = __LINE__, &) assert_no_new_orphans, assert_no_signal(target : Godot::Object, signal_name : String, during_frames : Int32 = 10, file : String = __FILE__, line : Int32 = __LINE__) : Void
assert_no_signal(target : Godot::Object, signal_name : String, file : String = __FILE__, line : Int32 = __LINE__, &block : -> Void) : Void assert_no_signal, assert_node_path_exists(root : Godot::Node, path : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) : Void assert_node_path_exists, assert_not_between(actual : Number, min : Number, max : Number, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_not_between, assert_not_connected(emitter : Godot::Object, signal_name : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_not_connected, assert_not_empty(collection, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_not_empty, assert_not_freed(object : Godot::Object, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_not_freed, assert_not_nil(val, msg : String = "Expected non-nil value", file : String = __FILE__, line : Int32 = __LINE__) assert_not_nil, assert_not_same(actual : Reference, expected : Reference, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_not_same, assert_raises(klass : T.class, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__, &) forall T assert_raises, assert_refcount(refcounted : Godot::RefCounted, expected : Int32, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_refcount, assert_same(actual : Reference, expected : Reference, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_same, assert_settled(body : Godot::Object, max_frames : Int32 = 60, linear_epsilon : Float64 = 0.05, angular_epsilon : Float64 = 0.05, file : String = __FILE__, line : Int32 = __LINE__) : Void assert_settled, assert_signal_count(spy : SignalSpy, count : Int32, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_signal_count, assert_signal_emit_count(spy : SignalSpy, count : Int32, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_signal_emit_count, assert_signal_emitted(spy : SignalSpy, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_signal_emitted, assert_signal_not_emitted(spy : SignalSpy, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_signal_not_emitted, assert_string_contains(str : String, substr : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_string_contains, assert_string_ends_with(str : String, suffix : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_string_ends_with, assert_string_starts_with(str : String, prefix : String, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_string_starts_with, assert_true(cond : Bool | Nil, msg : String = "Expected true, got false", file : String = __FILE__, line : Int32 = __LINE__) assert_true, assert_valid_id(instance_id : UInt64 | Int64, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_valid_id, assert_vector_approx(actual : Godot::Vector2, expected : Godot::Vector2, epsilon : Float64 = 0.001, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__)
assert_vector_approx(actual : Godot::Vector3, expected : Godot::Vector3, epsilon : Float64 = 0.001, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__)
assert_vector_approx(actual : Godot::Color, expected : Godot::Color, epsilon : Float64 = 0.001, msg : String = "", file : String = __FILE__, line : Int32 = __LINE__) assert_vector_approx, assert_zero_allocation(name : String = "Hot Loop", iterations : Int32 = 1000, warmup : Int32 = 10, file : String = __FILE__, line : Int32 = __LINE__, &) : Lapis::Profiler::AllocationReport assert_zero_allocation, autofree(obj : T) : T forall T autofree, autofree_all : Void autofree_all, autoqfree(node : T) : T forall T autoqfree, await_signal(emitter : Godot::Object, signal_name : String, timeout_sec : Float64 = 2.0, file : String = __FILE__, line : Int32 = __LINE__) : Array(Variant) await_signal, cleanup_autofree : Void cleanup_autofree, cleanup_tracked_nodes : Void cleanup_tracked_nodes, input_sender : InputSender input_sender, pending(reason : String = "Test pending implementation") : Nil pending, profile_allocations(name : String = "Operation", iterations : Int32 = 1000, warmup : Int32 = 10, &) : Lapis::Profiler::AllocationReport profile_allocations, scenario(root : Godot::Node, name : String, &block : ScenarioStepContext -> Void) : Void
scenario(name : String, &block : ScenarioStepContext -> Void) : Void scenario, simulate(node : Godot::Node, frames : Int32 = 1, delta : Float64 = 0.016666666666666666, physics : Bool = false) : Void simulate, skip_frames(count : Int32 = 1) : Void skip_frames, skip_if(condition : Bool, reason : String = "Test skipped") : Nil skip_if, skip_physics_frames(count : Int32 = 1) : Void skip_physics_frames, suppress_errors(&) suppress_errors, track_node(node : Godot::Node) : Godot::Node track_node, with_node(klass : T.class, parent : Godot::Node | Nil = nil, &block : T -> Void) forall T with_node, with_timeout(timeout_sec : Float64 = 5.0, operation_name : String = "Operation", file : String = __FILE__, line : Int32 = __LINE__, &) with_timeout
Class methods inherited from module Lapis::Test
autofree_objects
autofree_objects,
autoqfree_nodes
autoqfree_nodes,
tracked_nodes
tracked_nodes
Method Detail
C ABI Entry point called by crystal_bridge when game library is loaded
Top-level gameplay convenience methods
Global convenience helper to load resources from Godot VFS
Global query helper returning all nodes matching the regex under the active node context.
Example:
nodes(~/coin_\d+/).each(&.queue_free)
Dispatches block to execute safely on the Godot Main Thread. Executes immediately if already on the main thread; queues if on a worker thread.
Global convenience helper to preload resources from Godot VFS
Macro Detail
Declares a lazy-cached node property matching Godot's @onready pattern.
Unlike eager onready var = path properties which initialize strictly during _ready,
this macro defines a lazy getter that resolves the node on first access, caches the pointer,
and verifies #check_alive! on every subsequent access to protect against dead-pointer dereferencing.
Supported Styles:
- Auto-inferred name and type:
onready sprite_2d, Sprite2D(fetches child"Sprite2D") - Scene Unique Node:
onready camera, Camera2D, "%MainCamera" - Explicit path:
onready sprite, Sprite2D, "Visuals/Sprite2D"
Example:
node Enemy < CharacterBody2D do
onready sprite, Sprite2D, "Visuals/Sprite2D"
onready health_bar, ProgressBar, "%HealthBar"
def hit : Void
sprite.modulate = Godot::Color.new(1.0, 0.0, 0.0) # Resolves and caches sprite
end
end
Internal generator synthesizing dead-pointer safe, lazy-cached node property accessors.
Cooperatively awaits a signal, timer, or duration without blocking the engine main thread.
Rationale & Execution Model:
In Godot, asynchronous gameplay events (animations, dialogue timers, death signals)
must not block the engine's main loop (_process / _physics_process). Standard Crystal
sleep suspends the entire OS thread and hangs the engine.
await suspends only the calling Crystal fiber, polling Godot cooperatively across frame steps
while ensuring:
- Zero main thread stalling.
- Immediate dead-pointer protection: if the emitting node is freed (
destroy/free/queue_free) while waiting,awaitunblocks immediately withstatus.freed? == true(whileawait!raisesGodot::DisposedObjectErrorandawait?returnsnil). - Optional timeout support with automated timeout cancellation.
Supported Calling Forms:
# 1. First-class bound signal:
await(enemy.died)
await(enemy.died, timeout_sec: 5.0)
# 2. Dynamic target and string signal name:
await(boss, "phase_transition")
await(boss, "phase_transition", timeout_sec: 10.0)
# 3. SceneTree timer:
await(get_tree.create_timer(1.5).timeout)
# 4. Numeric delay in seconds:
await(1.5)
await(2.seconds)
Cooperatively awaits a signal, timer, or duration, raising Godot::DisposedObjectError if the target is freed or Godot::TimeoutError if timeout expires.
Cooperatively awaits a signal, timer, or duration, returning nil if the target is freed, or nil (or false) if timeout expires.
Cooperatively yields the calling fiber until condition evaluates to truthy.
Uses Fiber.yield between evaluation cycles. Supports an optional timeout_sec
parameter which raises Godot::TimeoutError if exceeded.
Example:
await_until(character.on_floor?, timeout_sec: 5.0)
Cooperatively yields the calling fiber while condition evaluates to truthy.
Uses Fiber.yield between evaluation cycles. Supports an optional timeout_sec
parameter which raises Godot::TimeoutError if exceeded.
Example:
await_while(tween.is_running, timeout_sec: 3.0)
Instantiates a Godot object or custom node and configures its properties and methods in a block or kwargs.
Supports:
- Keyword properties:
create Sprite2D, position: Vector2.new(10, 20), centered: true - Block property setters:
create Sprite2D do position = Vector2.new(10, 20); centered = true end - Method dispatches:
create Sprite2D do add_to_group("sprites"); rotate(0.5) end - Mixed kwargs and block:
create Sprite2D, centered: true do position = Vector2.new(10, 20) end
Defines a custom export macro macro_name that declares an exported String property
with PROPERTY_HINT_ENUM (2_u32) and hint_string in the Godot Inspector.
Forwards class-level properties to the class singleton instance
Forwards class-level methods to the class singleton instance (e.g. Input, AudioServer)
Type-safe signal emitter macro.
Emits signals directly via TypedSignal#emit or emit_signal.
Examples:
emit(player.health_changed, 50, 100) # Expands to player.health_changed.emit(50, 100)
emit(player.renamed) # Expands to player.renamed.emit
emit(health_changed, 50, 100) # Inside Player: expands to health_changed.emit(50, 100)
emit(sig, 50, 100) # Signal variable: expands to sig.emit(50, 100)
The primary node macro:
Usage:
node MyNode
node MyNode do
# defaults to Godot::Node
end
node Player < CharacterBody3D node Player < CharacterBody3D do # inherits Godot::CharacterBody3D end Expressive loader macro to ensure Lapis engine bindings are loaded without duplicate require cycles or missing dependency errors
Categorizes top-level inspector sections in Godot.
May be used standalone or as a block scoping exported properties.
Example:
node Boss < CharacterBody3D do
export_category "Combat Stats" do
@[Export]
property health : Int32 = 1000
@[Export]
property defense : Int32 = 50
end
end
Groups exported properties under a common folding group in the Godot inspector.
May be used standalone or as a block scoping exported properties.
Example:
node Vehicle < CharacterBody3D do
export_group "Engine", prefix: "engine_" do
@[Export]
property engine_power : Float32 = 250.0_f32
@[Export]
property engine_torque : Float32 = 400.0_f32
end
end
Subgroups exported properties under the current inspector group.
May be used standalone or as a block scoping exported properties.
Example:
node Character < CharacterBody3D do
export_group "Movement" do
export_subgroup "Advanced", prefix: "adv_" do
@[Export]
property adv_friction : Float32 = 0.1_f32
end
end
end
Declares a custom RefCounted or generic Godot engine class registered with ClassDB.
Defaults to inheriting RefCounted when no parent is specified.
Can be called with or without a block (e.g. gdclass MyState).
gdclass StateMachine < RefCounted do
@[Export]
property current_state : String = "idle"
end
gdclass SimpleState
Declares a reusable Godot module or mixin registered with ClassDB metadata.
Can declare properties (with @[Export]), signals, lifecycle hooks, and interface methods.
When included into a node, gdclass, or resource via include, its properties
and signals are automatically registered with ClassDB and dispatched via the GDExtension bridge.
Examples:
gmodule Damageable do
signal health_changed(current : Int32, max : Int32)
signal died
@[Export(range: 0..100)]
property health : Int32 = 100
@[Export]
property max_health : Int32 = 100
def take_damage(amount : Int32) : Void
self.health = Math.max(0, self.health - amount)
emit(health_changed, self.health, self.max_health)
emit(died) if self.health == 0
end
end
node Player < CharacterBody2D do
include Damageable
end
Lazily retrieves and caches a GDExtension method bind handle from ClassDB
Dynamically calls an instance method and returns the result as a Crystal String
Synthesizes null-safe #get_collider? query on raycasts and shapecasts
Marshals an enum or integer argument into a typed 64-bit pointer for ptrcall
Marshals a NodePath or String argument into an unmanaged Godot NodePath pointer
Marshals a Godot Object wrapper into an unmanaged pointer-to-pointer for ptrcall
Marshals a String argument into an unmanaged Godot String pointer
Marshals a String or StringName argument into an interned StringName pointer
Marshals a primitive scalar (Float, Int, Bool, Vector2/3, Color) for ptrcall
Synthesizes an ergonomic getter and setter pair
Executes a low-overhead GDExtension ptrcall
Executes a ptrcall returning a strongly-typed enum
Executes a ptrcall returning a float (Float64 / Float32)
Executes a ptrcall returning an integer (Int64)
Executes a ptrcall returning a typed object wrapper, reusing alive instance if present
Executes a ptrcall returning a typed object wrapper, or nil if Godot returned nullptr
Executes a ptrcall returning a value type with default constructor (e.g. Vector2, Vector3, Color, Transform3D)
Executes a void ptrcall with no return buffer
Instantiates a strongly-typed enum from a 64-bit ptrcall return buffer
Wraps a returned native object pointer into its typed Crystal wrapper
Synthesizes a first-class typed signal accessor, StaticSignalSlot view, and direct emission helper
Defines a Godot singleton accessor and pointer caching
Emits top-level Godot module singleton helper
Dynamically calls a static engine method and returns the result as a Crystal String
Declaratively assigns the node to one or more scene tree groups upon _ready.
The node macro extracts all group statements and registers them automatically
in Godot's SceneTree when the node enters the tree.
Example:
node Player < CharacterBody3D do
group "players", "damageable", "interactable"
end
Loads a PackedScene (.tscn) and instantiates it as wrapper type T with configuration
Loads a PackedScene (.tscn), instantiates it as wrapper type T, and attaches it as a child to the parent
Loads a resource dynamically from the Godot virtual filesystem with compile-time type inference.
Supported extensions:
.tscn,.scn->Godot::PackedScene.png,.svg,.webp->Godot::Texture2D.wav,.ogg,.mp3->Godot::AudioStream- Other /
.tres->Godot::Resource
For custom types, chain .as(Type):
config = load("res://data.tres").as(CustomConfig)
Safe, nil-returning variant of load(path).
Returns nil if the resource fails to load or does not exist on disk.
Example:
if scene = load?("res://dlc/bonus_level.tscn")
# ...
end
Expression-oriented pattern matching macro designed for concise, expressive gameplay scripting.
Returns the evaluated result of the first matching branch, or nil if no branch matched.
Rationale & Architectural Design:
While Crystal's native case / when statement is powerful, game development in Godot
requires specialized pattern matching capabilities that native case cannot express:
- Variant Unboxing: Automatically extracting typed values from dynamically typed
Godot::Variant. - Dead-Pointer Safe Node Downcasting: Verifying
#alive?during downcasting so freed nodes never match. - Implicit Variable Binding: Allowing
match i do is Int64 do "Value: #{i * 2}" endwithout repetitive|i|closures. - String & Symbol Equivalence: Matching
:actionagainst"action"seamlessly for input and state machines. - Structural Destructuring: Extracting elements from Tuples, Arrays with rest ranges (
[first, .., last]), and Dictionaries.
Supported Syntax Patterns:
1. Implicit Variable Binding (Variable is narrowed to branch type):
value_text = match i do
is Int64 do "Integer: #{i * 2}" end
is String do "Text: #{i.upcase}" end
is Godot::Vector2 do "Vector: (#{i.x}, #{i.y})" end
default do "Unsupported Variant" end
end
2. Explicit Parameter Binding:
description = match hit.collider do
is Player do |player| "Player with #{player.health} HP" end
is Enemy do |enemy| "Enemy of level #{enemy.level}" end
default do "Non-entity obstacle" end
end
3. Guard Clauses (if: named argument):
label = match score do
is Int64, if: score > 1000 do "High Score: #{score}" end
is Int64 do "Normal Score: #{score}" end
default do "Invalid" end
end
4. Multi-Pattern Splats:
match state do
is :idle, :standing do play_animation("idle") end
is :run, :sprint do play_animation("run") end
end
5. Tuple Destructuring:
match {state, on_floor?} do
is :jumping, false do apply_air_control end
is :jumping, true do land! end
end
6. Array Rest Matching:
match inventory do
is [first, .., last] do |f, l| "First: #{f}, Last: #{l}" end
default do "Empty or small" end
end
7. Dictionary Matching:
match packet do
is dict(type: "chat", body: msg) do |_, text| display_message(text) end
default do handle_unknown_packet end
end
Dedicated declarative multiplayer simulation test macro
Immediately retrieves a child node from the current node's scene hierarchy.
Provides GDScript $ parity with static type casting.
Supported Patterns:
- Type-inferred:
node!(Sprite2D)-> looks up"Sprite2D"and casts toSprite2D - Path with Type:
node!("Visuals/Sprite2D", Sprite2D)-> resolves path and casts toSprite2D - Path string:
node!("Visuals/Sprite2D")-> resolves path as untypedGodot::Node
Raises Godot::NodeNotFoundError if the node is not found or fails type casting.
Example:
def _ready : Void
sprite = node!(Sprite2D)
camera = node!("Pivot/Camera3D", Camera3D)
end
Expressive convenience macro for 2D scene nodes defaulting to Godot::Node2D
Expressive convenience macro for 3D spatial nodes defaulting to Godot::Node3D
Safely retrieves a child node from the current node's scene hierarchy, returning nil if not found.
Supported Patterns:
- Type-inferred:
node?(Sprite2D)-> looks up"Sprite2D", returnsSprite2D? - Path with Type:
node?("Visuals/Sprite2D", Sprite2D)-> returnsSprite2D? - Path string:
node?("Visuals/Sprite2D")-> returnsGodot::Node?
Declares a dead-pointer safe, lazy-cached node property matching Godot's @onready pattern.
Supports:
- Macro signature:
node_ref player, Player, "Player" - Type declaration:
node_ref player : Player = "Player" - Auto-inferred:
node_ref sprite_2d : Sprite2D
Declares a safe, lazy-cached node property that returns nil if missing or type mismatch.
Examples:
node_ref? player, PlayerController, "Player"
node_ref? hud : GameHUD = "HUD"
Expressive signal connection macro
Supports:
- First-class signal:
on button.pressed { do_something } - Positional type filter:
on body_entered, Player { |p| p.collect } - Multi-argument type filters:
on item_equipped, Player, Sword { |p, s| ... } - Any wildcard filter:
on damage_received, Player, Any { |p, info| ... } - One-shot execution:
on boss.died, Player, once: true { |p| ... } - Target and signal string:
on enemy, "died" { |bounty| add_score(bounty) }
Zero-allocation static signal connection macro binding compile-time typed procs
or blocks directly to StaticSignalTable slots.
Can be used both:
- Declaratively at class body scope inside
nodeorgmodule:node Player < CharacterBody3D do signal health_changed(new_health : Int32, max_health : Int32) signal died on_signal health_changed, ->on_health_changed(Int32, Int32) on_signal :died, ->on_died, once: true def on_health_changed(hp : Int32, max : Int32) : Void end def on_died : Void end end - Imperatively inside methods or scripts:
on_signal player.health_changed, ->(hp : Int32, max : Int32) { ... } on_signal player.health_changed_slot, handler_proc on_signal player, :health_changed, handler_proc, once: true on_signal player.health_changed do |hp, max| ... end
Declares a safe, lazy-cached node property that returns nil if missing or type mismatch.
Examples:
onready? player, PlayerController, "Player"
onready? hud, GameHUD, "HUD"
Context-aware one-shot audio playback macro:
- Inspects
@typeat compile-time:@type <= Godot::Node2D-> emits AudioStreamPlayer2D with global_position@type <= Godot::Node3D-> emits AudioStreamPlayer3D with global_position- Otherwise -> emits non-spatial AudioStreamPlayer
- If explicit
at:coordinate is passed (Vector2 or Vector3), spatializes appropriately - Automatically preloads or loads the AudioStream
- Sets kwargs properties (e.g. pitch_scale: 1.2, volume_db: -5.0, bus: "SFX")
- Executes inline configuration block (e.g. do pitch_scale = 1.2 end)
- Attaches to active scene root (
current_scene || root) so audio survives caller deletion! - Connects finished.once { queue_free } for automatic memory cleanup
- Returns the strongly-typed audio player
Preloads and caches a resource from the Godot virtual filesystem with compile-time type inference.
Supported extensions:
.tscn,.scn->Godot::PackedScene.png,.svg,.webp->Godot::Texture2D.wav,.ogg,.mp3->Godot::AudioStream- Other /
.tres->Godot::Resource
For custom types, chain .as(Type):
const CONFIG = preload("res://data.tres").as(CustomConfig)
Safe, nil-returning variant of preload(path).
Returns nil if the resource fails to load or does not exist on disk.
Example:
if icon = preload?("res://custom_icon.png")
# ...
end
Declares a custom Godot Resource class registered with ClassDB and EditorHelp.
Supports @[Export] properties, custom signals, and serialization to .tres.
resource ItemData < Resource do
@[Export]
property item_name : String = "Health Potion"
Declares a custom Resource subclass registered with ClassDB.
Defaults to inheriting `Resource` when no parent is specified.
Can be called with or without a block (e.g. `resource MyItem`).
resource CustomPotion do @[Export] property item_name : String = "Health Potion"
@[Export] property value : Int32 = 50 end
resource ShortItem
Declares a custom Resource strategy card.
Custom Resources inheriting from Godot::Resource act as pluggable strategy objects and data containers (e.g. inventory items, ability cards, weapon stats).
Example:
resource_card WeaponCard < Resource do
@[Export]
property damage : Int32 = 50
@[Export]
property cooldown : Float32 = 1.0_f32
def use(target : CharacterBody2D) : Void
# strategy implementation
end
end
Declares a custom Godot signal with first-class typed signal accessors.
class Player < Godot::CharacterBody3D
signal health_changed(new_health : Int32, max_health : Int32)
signal died
def take_damage(amount : Int32)
health_changed.emit(50, 100)
died.emit if amount >= 100
end
end
Instantiates a node, configures it, and attaches it as a child to the specified parent
(defaults to self if inside a Node method, or current scene / root).
Declarative suite macro allowing grouped tests, parameterized tests, and suite/case lifecycle hooks
Block-based tween DSL targeting specified node with compile-time type verification (e.g. tween(player) do animate(...) end)
Compile-time type-safe tween macro supporting dot-navigation (e.g. tween(boss.position.y, to: 150.0))
Immediately retrieves a Scene Unique Node (Godot 4 %Node syntax).
Automatically prepends % to the identifier if not already present.
Supported Patterns:
- Type-inferred:
unique!(ProgressBar)-> looks up"%ProgressBar"asProgressBar - Name with Type:
unique!("HealthBar", ProgressBar)-> looks up"%HealthBar"asProgressBar - Name string:
unique!("HealthBar")-> looks up"%HealthBar"asGodot::Node
Raises Godot::NodeNotFoundError if the unique node does not exist.
Safely retrieves a Scene Unique Node (Godot 4 %Node syntax), returning nil if not found.
Declares a lazy-cached Scene Unique Node property (Godot 4 %Node syntax).
Examples:
unique_node health_bar, ProgressBar # fetches "%HealthBar"
unique_node main_hud, CanvasLayer, "HUD" # fetches "%HUD"
Declares a safe, lazy-cached Scene Unique Node property that returns nil if missing.
Examples:
unique_node? health_bar, ProgressBar, "HealthBar"
Declares a dead-pointer safe, lazy-cached Scene Unique Node property (Godot 4 %Node syntax).
Supports:
- Macro signature:
unique_node_ref camera, Camera2D, "MainCamera" - Type declaration:
unique_node_ref camera : Camera2D = "MainCamera" - Auto-inferred:
unique_node_ref main_hud : CanvasLayer
Declares a safe, lazy-cached Scene Unique Node property that returns nil if missing.
Examples:
unique_node_ref? camera, Camera2D, "MainCamera"
unique_node_ref? hud : CanvasLayer