Skip to content

03 Scripting

zhoeshin edited this page Jul 23, 2026 · 13 revisions

Basics

The plugin uses a domain-specific language for its core functionality. The basic building blocks are

# this sets the current dialog box. `someBoxScene` needs to be an initialized scene
[someBoxScene]

# this displays the output to the player
# `somesprite` is used for the portrait and `sometext` is the message, both can be expressions
# the dictionary after it is passed as `options`. if omitted, an empty dictionary is passed
somesprite: sometext {
    someparam = somevalue
}

# this creates an input for the player to respond to in accordance to the `someInputType` descriptor
# after that, `somevar` is assigned to the player's output
# the dictionary literal is passed as `options` to the dialog box
# `somevar` is optional and if omitted the result is not assigned
# the dictionary containing `options` is optional. an empty dictionary is passed if none present
somevar <- someInputType {
    someparam = somevalue
}
# matching by value after input is also optional
- somebranch1 # branch executed if player's output is same as `somebranch1`
    do1
- somebranch2 ? condition # this branch is only created if `condition` is true
    do2
--
    dodefault

# matching uses the same syntax
somevalue:
- somematch1 # branch executed if `somevalue == somematch1`
    do1
# in this case, because `?` is an operator, the branch equals `somematch2` if `condition` is true and `null` otherwise
# if `somevalue` is `null`, it might still match this branch
- somematch2 ? conditon
    do2
--
    dodefault

# if statements are
? somecond1
    do1
# multiple conditional statements in a row get joined into if-else chains
? elsecond2
    doelse2
?! # the else branch terminates the chain of conditionals
    doelse

? cond1
    do1
. # the dot terminates the chain of conditionals
? cond2 # checked independantly of `cond1` branch
    do2
.

# any other line is treated as an expression
somevar = someval1 + someval2

Values

Literals

Numbers

Numbers can only be digits 0-9, with optional period. For example 12345, 12.34. .5 or 1. are not valid numerals. Different bases, such as hex 0xae, binary 0b1001 or octal 0x765 are not currently supported

Strings

Strings are quoted with either " or '. String interpolation is supported: a part of a string can be delimitered by {}. In which case, the contents are executed as an expression, for example

somevar = "a"
somevar2 = "b"
edwin: "Vars {a} {b} {a + b} {2 ** 4 + 3}" # outputs "Vars a b ab 19"
edwin: "No vars \{a} \{2 ** 4 + 3}" # backslash escapes interpolation, so output is "No vars {a} {2 ** 4 + 3}"

Interpolation is performed on all strings in the context they are used in, not just on string literals

Resources

Resources can be loaded using ^"res://path/to/resource" syntax. For example ^"res://sprites/portraits.edwin.png", ^"res://scripts/cutscene.gd", ^"res://dialogBoxes/default.tscn". If the loaded resource is a script or a scene, it is instantiated automatically.

This means, a script can be imported by binding = ^"res://path/to/script.gd" and setting a dialog box is possible via [^"res://path/to/dialogBox.tscn"].

Variables

For most scenarios, no special naming conventions or prefixes are required. Valid names are somevar, somevar123, _othervar. However, a local variable might shadow a global one. To force accessing a global variable, its name can be prefixed with %, for example, %Inventory will not look for a local variable named Inventory.

Built-ins

Most of Godot's built-in functions, objects and types are accessible by the same identifier with the DSL

Operators

Any expression written in the DSL can both access Godot's internal operators and use overloads. First, overloads are checked, and if any are present, that method is executed. Otherwise, execution falls back to Godot's built-in operators.

All operators in the DSL are:

Operator Overload Note
a in b _in
a () b _call
a [] b none Accessing a member
a . b none Accessing a member
a ** b _pow
a */ b _root Falls back to a ** (1.0 / b)
a * b _mul
a / b _div True division(not rounded) if both a and b are integer
a % b _mod
a // b _floor_div
a + b _add
a - b _sub
a > b _gt
a < b _lt
a >= b _ge
a <= b _le
a == b _eq
a != b _ne
a && b _land Can convert a and b to bool if they implement _to_bool method
a b
a ^^ b _lxor Can convert a and b to bool if they implement _to_bool method. Falls back to bool(a) != bool(b)
a & b _and
a b _xor
a ^ b _xor
a = b none
a ? b none if b is falsey, returns a. b can reference a as _ *note
a ?! b none if a is null, returns b

Any overloadable operator can have a secondary method prefixed with _r for when self is the right hand side. For example, for 5 + someCustomClass, int does not implement _add. If CustomClass impelemnts _add_r, that method is called with 5 as the argument. Otherwise, the interpreter falls back to using Godot's native addition

*note: For example, "Red" ? prevColor != _ will return null if prevColor == "Red". This is primarily used for branches in input statements(any branch matching a null is ignored). If the right hand size of the ? has a _, _ is substituted with the left hand side value. If no _ is present, left hand side is not evaluated unless right hand side is true.

Clone this wiki locally