Patches
A patch is behaviour you draw. It sits neatly between events, which are simple but cannot hold a value or do arithmetic, and scripts, which can do anything but ask you to write code.
Reach for a patch the first time you catch yourself wanting "…but only if the score is above ten" or "…move it a bit further each time".
Patches are compiled, not interpreted, so they run exactly as fast as hand-written code. You can read the generated script at any time in the code panel — which is also the quickest way to check that a graph does what you meant.
Every node, with its ports: patch node reference — 203 nodes across 24 categories.
Four kinds of node
| Kind | How you spot it | What it is |
|---|---|---|
| Event | only outputs, one of them a pulse | where the graph starts — on launch, on tap, every frame |
| Effect | a pulse in and a pulse out | does something, in order |
| Control | splits or repeats the pulse | branch, gate, repeat, for-each, once, delay |
| Data | no pulses at all | a value — a number, a sum, a component's field |
The pulse wire is the order things happen in. Follow it from an event node and you are reading the sequence. Data wires just carry values; they have no order.
Ports and wires
Ports are typed (number, boolean, string, vector, colour, object) and mismatched types will not connect, which catches a lot of mistakes before you run anything.
A vector port unfolds into x, y and z, so you can wire one and type the other two.
An input you leave unconnected uses whatever value you typed into the node. That is usually what you want: wire only the parts that change.
Telling a node which object to use
Component nodes ("get transform", "set material") need to know which object.
Leave the binding empty and it means this object, the one the patch is attached to. Set it and the node works on that object instead.
Two conveniences worth knowing:
- Get nodes are forgiving. Reading a component an object does not have gives you nothing, rather than breaking the graph.
- Set nodes only write what you filled in. Everything you left alone stays as it was.
Which matches everything else you can see. Just remember it if you are passing values between a patch and a script, where rotation is in radians.
What is in the catalogue
| Category | What you will find |
|---|---|
| events | 30 starting points — launch, frame, tap, keys, collisions, tracking |
| components | read and write any component |
| math · vector · logic · string | arithmetic, comparisons, vectors, text |
| flow | branch, gate, repeat, for-each, once, delay, sequence |
| state | counter, toggle, timer, smooth |
| entities · lifecycle | find objects, create, spawn, destroy |
| physics | impulses, forces, velocity, raycast |
| net | multiplayer — send, receive, shared state, spawn |
| globals · variables · messaging | values shared with other patches and scripts |
| ui | read and write an interface card's variables |
| functions | call another patch, or a script |
Reusing a patch
Save a graph as a resource and you can drop it onto other canvases. How it behaves depends on how you built it:
| You built | You get |
|---|---|
| no input or output nodes | a behaviour — drop it in and it runs, no wires needed |
| inputs, outputs and a pulse input | a step — it runs when the pulse arrives, outputs ready afterwards |
| inputs and outputs, no pulse | a function — its outputs are worked out wherever they are read |
Its sockets come from the input and output nodes you put inside it: add one and it appears on every caller. Edit the patch and everything calling it updates live.
Inside a pure function there is no "this object", so object and component nodes do not belong there. Keep functions to data, maths and logic, and do the scene work in the caller.
Patches can call scripts too, which is the usual way to reach something the catalogue does not cover.
Values that outlive the graph
Three ways to keep something, differing in how far it reaches:
| Store | Shared with |
|---|---|
| variables | the nodes of this one patch |
| globals | every patch, script and event in the project |
| messages | anyone listening, as a one-off notification by name |
Globals come in two scopes: project-wide (they survive moving between spaces) and space-only (they start fresh). Names are typed in rather than wired, which keeps the routing predictable.
The escape hatch
Two nodes take JavaScript directly: expression returns a value, action runs statements. Everything a script can reach is available inside them.
They are there for the one small thing the catalogue lacks — not as a way of life. If you find yourself writing a lot in them, write a script and call it from the graph instead.
When something is not right
Open the code panel. A graph that cannot compile — a loop in the data wires, broken JavaScript in an action node — tells you there.
And a broken patch never takes the scene down with it: the others carry on running.
Next: Game controls — let people walk around.