Functions & Macros
Both are reusable, and picking between them is one question: does it finish inside the call, or does it take time?
- A function is a list of steps. Its entry node has a single Run cell, no lifecycle, and it is over by the time the caller’s next step runs.
- A macro is a piece of state machine. It has states of its own, each with all four cells, so it keeps running across frames. A spin that lasts a second needs somewhere to live while that second passes, and only a state can do that.
The guided path builds one of each: Functions and Macros.
What a function is made of
Section titled “What a function is made of”Inputs it borrows from the caller, outputs it hands back, and branches, the named ways it can end. Inside the body, its own inputs sit at the top of every bind list, above the script’s variables, so an argument feeds a field exactly like a variable does.
A function ends on a Finish action, which only appears in the search inside one. It has a field per output plus a Result picker listing the branches.
The four shapes a function takes
Section titled “The four shapes a function takes”| Outputs | Branches | What you get |
|---|---|---|
| none | none | A named block of steps, for the four things you keep repeating |
| one | none | A value, which can be dropped straight into a field as an inline action |
| any | some | A step that decides, carrying branch cells like any question |
| some | some | Both: it decides and hands values back |
The second row is the one worth remembering. No branches and exactly one output stops the
function being a step in a chain and makes it a value producer, sitting in the field picker next to
Random Float and Mouse Position. Any bit of maths you keep rewriting can become one.
A function cannot change its own script’s state
Section titled “A function cannot change its own script’s state”Open a branch editor inside a function and no state of the script is offered. A function does not know who called it, so it is in no position to decide where that caller goes next: it reports which way it left, and the caller decides what that means.
It can drive another script’s machine, which is not the machine it is running inside.
What a macro is made of
Section titled “What a macro is made of”Inputs, read inside like variables. Branches, the named ways out, which each use points at a state of its own. And entries, the holes it leaves on purpose.
A branch is the way out; an entry is the way in. You mark one by adding a Run <name>
action inside the macro, at the exact cell where those steps belong, and each use fills it with its
own steps. A Move To macro with an entry called on step walks the same way for everybody, while
one use turns to face the target and another draws a line to it. Entries are the answer when two
macros differ by a single action.
A macro names branches instead of states for the same reason a function does not transition: naming a state directly would tie it to one place in one script.
Using one
Section titled “Using one”Use macro, on a state’s settings popup, adds the macro as a sub-state whose contents are the macro’s machine. Its entry node reads top to bottom as the deal being struck:
- a pin per input, holding the value this use hands over
- a cell per entry, where this use puts its own steps
- the four normal cells, which belong to the use itself
- a cell per branch, picking the state this use goes to when the macro takes it
What they compile to
Section titled “What they compile to”- A function becomes a method:
Pick Target→fn_pick_target(max_distance: float = 300.0). - A function with branches returns which way out it took, and the call site becomes a
matchon it, with the branch steps under each case. - Its outputs then ride script variables, since the return value is already carrying the way out. The wires read them for you.
- Two functions whose names collapse to the same method name (
take damageandTake Damage) do not overwrite each other, the second is numbered. - Each use of a macro becomes its own nested class with its own copy of the machine, so two uses
never step on each other. The values a use hands in become script variables of their own, one set
per use (
_mc_17_speed,_mc_20_speed), because a nested class in GDScript cannot read the class holding it.