Quick Reference

English | 日本語
Table of contents
Authors: la.panon.
Version: 0.14.1

This document offers concise examples of common patterns in gdext-nim. Each section shows the equivalent code in GDScript and Nim, so you can quickly find how to perform a task. For a complete API specification, see the Full API Reference.


Object Definition

Inherit an object

GDScript:

# my_object.gd
@icon("res://path/to/optional/icon.svg")
class_name MyObject
extends Object

Nim:

# classes/gdmyobject.nim
import gdext
import gdext/classes/gdObject

type MyObject* {.gdsync, icon: "res://path/to/optional/icon.svg".} = ptr object of Object
# bootstrap.nim
import classes/gdmyobject

Initialize objects

GDScript:

func _init():
  pass

Nim:

method onInit(self: MyObject) =
  discard

Finalize objects

GDScript:

func _notification(what):
  if what == NOTIFICATION_PREDELETE:
    pass

Nim:

method notification(self: MyNode; what: int32) =
  case what
  of NotificationPredelete:
    discard
method onDestroy(self: MyObject) =
  discard

Override virtual methods

GDScript:

func _ready():
  pass

Nim:

import gdext/classes/[gdNode]
method ready(self: MyNode) {.gdsync.} =
  discard

Define functions

GDScript:

func my_function(arg1):
  pass
func my_function(arg1: int) -> Dictionary:
  pass

Nim:

proc my_function*(self: MyNode; arg1: Variant) {.gdsync.} =
  discard
proc my_function*(self: MyNode; arg1: Int): Dictionary {.gdsync.} =
  discard

Define static functions

GDScript:

static func my_function(arg1):
  pass
static func my_function(arg1: int) -> Dictionary:
  pass

Nim:

proc my_function*(T: typedesc[MyNode]; arg1: Variant) {.gdsync.} =
  discard
proc my_function*(T: typedesc[MyNode]; arg1: Int): Dictionary {.gdsync.} =
  discard

Then you can call the function in Nim like this:

MyNode.my_function(10)

Note:

This syntax can also be used to define factory methods (custom constructors).

Define signals

GDScript:

signal my_signal
signal my_signal(arg1, arg2)

Nim:

proc my_signal*(self: MyNode): Error {.gdsync, signal.}
proc my_signal*(self: MyNode; arg1: Int; arg2: Variant): Error {.gdsync, signal.}

Define constants

GDScript:

const A = 5

Nim:

Not available

Define enums

GDScript:

enum MyEnum {A, B = 5, C}

Nim:

type MyEnum = enum
  A, B = 5, C

MyNode.bind MyEnum

Define bitfields

GDScript:

#N/A

Nim:

type MyFlags = enum
  A, B = 5, C

MyNode.bind set[MyFlags]

Define new virtual functions

GDScript:

#N/A

Nim:

method my_virtual*(self: MyNode) {.gdsync, base.} =
  discard

Export properties

GDScript:

@export var integer := 10

Nim:

type MyNode* {.gdsync.} = ptr object of Node
  integer* {.gdexport.}: Int = 10
type MyNode* {.gdsync.} = ptr object of Node
  integer*: Int = 10
gdexport MyNode.integer
type MyNode* {.gdsync.} = ptr object of Node
  integer* : Int

proc set_integer(self: MyNode; value: Int) {.gdsync.} =
  self.integer = value

gdexport "integer",
  getter= proc(self: MyNode): int = self.integer,
  setter= set_integer

Customize property appearances in the editor

GDScript:

@export_range(0, 20) var integer := 10

Nim:

type MyNode* {.gdsync.} = ptr object of Node
  integer* {.gdexport: Appearance.range(0, 20).}: Int = 10
type MyNode* {.gdsync.} = ptr object of Node
  integer*: Int = 10
gdexport MyNode.integer, Appearance.range(0, 20)
type MyNode* {.gdsync.} = ptr object of Node
  integer* : Int

proc set_integer(self: MyNode; value: Int) {.gdsync.} =
  self.integer = value

gdexport "integer",
  getter= proc(self: MyNode): int = self.integer,
  setter= set_integer,
  Appearance.range(0, 20)

Object Operation

Instantiate Object

GDScript:

var obj := Object.new()

Nim:

var obj: Object = instantiate Object

Call user-defined signals

GDScript:

signal my_signal

func _ready():
  my_signal.emit()
  emit_signal("my_signal")

Nim:

proc my_signal*(self: MyNode): Error {.gdsync, signal}

method ready(self: MyNode) {.gdsync.} =
  assert self.my_signal() == ok
  assert self.signal("my_signal").emit() == ok
  assert self.emitSignal("my_signal") == ok

Connect signals and callables

GDScript:

signal my_signal
func my_function():
  pass

func _ready():
  my_signal.connect(my_function)
proc my_signal*(self: MyNode): Error {.gdsync, signal}
proc my_function*(self: MyNode) {.gdsync} =
  discard

method ready(self: MyNode) {.gdsync.} =
  discard self.connect("my_signal", self.callable("my_function"))
  discard self.signal("my_signal").connect(self.callable("my_function"))

Cast objects

Object kinds

GDScript:

var node: Node = object as Node

Nim:

var node: Node = object as Node
var node: Node = object.castTo(Node)

RefCounted kinds

GDScript:

var refcounted: RefCounted = object as RefCounted

Nim:

var refcounted: gdref RefCounted = object as gdref RefCounted
var refcounted: gdref RefCounted = object.castTo(gdref RefCounted)

Note:

castTo and as are the same.
In gdext-nim, these type casts are valid (A and B are subtypes of Object):

  • A as B
  • gdref A as B
  • A as gdref B
  • gdref A as gdref B

You can also obtain a gdref A from an A.

proc f(x: RefCounted): gdref RefCounted = x as gdref RefCounted

RefCounted Operation

Instantiate RefCounted

GDScript:

var refc := RefCounted.new()

Nim:

var refc: gdref RefCounted = instantiate RefCounted

Call functions of RefCounted

GDScript:

refc.getReferenceCount()

Nim:

refc[].getReferenceCount()

Load resources

GDScript:

var texture = preload("res://icon.png")
var texture = load("res://icon.png")

Nim:

preload is not available.

var resource: gdref Resource = ResourceLoader.load("res://icon.png")
var texture = resource as gdref Texture

Node Operation

Get nodes

GDScript:

var subnode: SubNode = $path/to/SubNode as SubNode
var subnode: SubNode = getNode("path/to/SubNode") as SubNode

Nim:

var subnode: SubNode = self/"path/to/SubNode" as SubNode
var subnode: SubNode = self.getNode("path/to/SubNode").castTo(SubNode)

Variant Operation

Primitives ⇔ Variant

Using as

GDScript:

var v: Variant = 10
var i: int = v as int
var v: Variant = Object.new()
var o: Object = v as Object
var v: Variant = RefCounted.new()
var r: RefCounted = v as RefCounted

Nim:

var v: Variant = variant 10
var i: int = v as int
var v: Variant = variant instantiate Node
var n: Node = v as Node
var v: Variant = variant instantiate Refcounted
var r: gdref RefCounted = v as gdref RefCounted

Using get:

Nim:

var v: Variant = variant 10
var i: int = v.get(int)
var v: Variant = variant instantiate Node
var n: Node = v.get(Node)
var v: Variant = variant instantiate Refcounted
var r: gdref RefCounted = v.get(gdref RefCounted)

Allocate primitives

GDScript:

var array: Array[Variant] = [1, 2, 3]
var typed_array: Array[int] = [1, 2, 3]
var dict: Dictionary[Variant, Variant] = {"A": 1, "B": 2, "C": 3}
var dict: Dictionary[string, int] = {"A": 1, "B": 2, "C": 3}
var string = "Hello"
var string_name = &"Node"
var node_path = ^"A/B"
var packed_array = PackedByteArray([1, 2, 3])
var nil = null

Nim:

var array: Array = newArray [1, 2, 3]
var typed_array: TypedArray[Int] = newTypedArray[int]([1, 2, 3])
var dict: Dictionary = newDictionary()
dict[variant "A"] = variant 1
dict[variant "B"] = variant 2
dict[variant "C"] = variant 3

Note: typed-dictionary is not available

var string = newString "Hello"
var string: String = "Hello"
var string_name = newStringName "Node"
var string_name: StringName = "Node"
var node_path = newNodePath "A/B"
var node_path: NodePath = "A/B"
var packed_array = newPackedByteArray [1.byte, 2, 3]
var packed_array = newPackedArray [1.byte, 2, 3]
var nil = variant()

Init primitives

GDScript:

var vector3: Vector3 = Vector3(1, 2, 3)

Nim:

Constructor is camelCase.

var vector3: Vector3 = vector3(1, 2, 3)

Get member constants

GDScript:

var vector3: Vector3 = Vector3.ZERO

Nim:

Nim Manual says:

That means only the first letters are compared in a case-sensitive manner.

var vector3: Vector3 = Vector3.Zero
var vector3: Vector3 = Vector3.ZERO

Advanced Recipes

Compare types

Using typeof

GDScript:

var foo = 2
match typeof(foo):
  TYPE_NIL:
    print("foo is null")
  TYPE_INT:
    print("foo is an integer")
  TYPE_OBJECT:
    print("foo is a(n) %s" % foo.get_class())

Nim:

var foo = variant 2
case cast[VariantType](gdext.typeof(foo))
of VariantTypeNil:
  print("foo is null")
of VariantTypeInt:
  print("foo is an integer")
of VariantTypeObject:
  print("foo is a(n) %s" % foo.getClass())

Remote procedure call (RPC)

Define RPC func

GDScript:

@rpc
func rpc_func():
  print("RPC!")
@rpc("any_peer", "call_remote", "reliable", 0)
func rpc_func():
  print("RPC!")

Nim:

proc rpc_func(self: MyNode) {.rpc.} =
  print("RPC!")
proc rpc_func(self: MyNode) {.rpc(
    mode = rpcModeAnyPeer,
    callLocal = false,
    transferMode = transferModeReliable,
    transferChannel = 0).}
  print("RPC!")

Call RPC func

GDScript:

rpc_func.rpc()

Nim:

var error: Error = self.rpc("rpc_func")