Flow is Opal's visual scripting: connect nodes on a canvas to define what happens when events fire. Reach for it whenever an object should react to input, collisions, or timers, or a scene needs startup and win/lose rules. No code is required for most games — it works like Unreal Blueprints — though Expression and Script nodes are there when you need more power.
There are two scopes:
Scope
Workspace tab
Runs on
Object Flow
Object Flow
One object — its taps, drags, collisions, timers, …
Scene Flow
Scene Flow
The whole scene — startup, transitions, global rules
Both use the same node catalog, inspector, and wire types.
Prefer typing to wiring?
Any graph can also be edited as readable text — hit the Text button in the flow toolbar. See Flow as text.
Each graph is a rule: a trigger event plus the nodes wired beneath it. One object (or the scene) can have many rules — for example separate graphs for On Tap and On Scene Start.
Click an output port and drag to a compatible input to connect. Data ports and wires use their value type's color, while execution wires stay white. Click a wire or node and press Delete to remove it.
Click + Event (or double-click the canvas) and pick On Tap
From the catalog, add Play Audio
Connect the white execution pin: On Tap → Play Audio
In the Flow inspector, choose a sound asset for the node
Press Play and tap the object
Try it live: the coin collector is the same idea — one On Tap rule drives the counter. Published builds and play embeds use that graph; the playable below is a fuller demo of the system, not a 1:1 of the six-node example.
Try Opal's Flow — playable demo (fuller than the single-rule example)
The Text button
Every graph has a Text toggle in the flow toolbar (next to Tidy). Hit it to see the same rule as readable text — useful for copying, diffing, or pasting into a chat. See Flow as text.
Use Drop Zone component or drop / droppedOn flow events for drag-and-drop puzzles, inventory, and card games. The dragged object is the source; the target is where it was dropped.
On Timer and Start Timer / Stop Timer nodes drive delayed and repeating logic without code.
Every Flow timing node — Wait, Cooldown, a timed Say, a Move To with a duration — runs on the game clock, the same clock physics, motion, VFX, and OpalScript's Time.Wait use. A paused game holds every pending Wait; a scene change or Stop drops them. Wait 0 resumes on the next frame.
Object Flow graphs are stored on the selected object. The On Tap trigger only fires for taps on that object unless you parameterize a different target in action nodes.
Scene Flow graphs live at scene scope. Use them for:
Loading UI on On Scene Start
Go To Scene when the player wins or loses
Global timers and score tracking
Listening for Custom Events broadcast from any object
Switch to the Scene Flow tab to author scene rules. The catalog and inspector behave the same way.
Many node fields accept expressions — small snippets evaluated at runtime. Prefix a field with = (or use the expression toggle) to switch from a literal value to a formula.
Available context in Flow = expressions (varies by node):
Symbol
Meaning
self
Often the component fields for a component action/condition; otherwise may be null
thing
The resolved scene object for the node
params
Parameter / event payload bag
event / source / target
Active event and actors
get("health")
Sibling component fields on thing
Math
Standard Math object
For GameState and object variables, write with Add Counter / Set Value and read with Get Value (or =GameState.score in a Flow expression). HUD labels use the UI Inspector Data bindings card — see UI and HUD and Variables and GameState.
Expressions are optional — literal values and data wires work fine for simple graphs.
Declare project GameState in the Variables dock (Variables in the bottom shelf). Types: Number, True / False, Text, List, Object. Each GameState field has a lifetime (Session, Saved, or Scene). Object variables live on the Inspector Variables card — same types, no lifetime.
The full reference — lifetimes, list indexes, object references, UI vs Flow — is Variables and GameState.
In graphs, write with Add Counter / Set Value (and the list or object nodes). Read with Get Value, or =GameState.score in a Flow expression. HUD labels use Data bindings → GameState.
Live Flow overlay — while playing, toggle Flow on the canvas overlay to see nodes light up as they run. If a node never flashes, execution never reached it — check the previous white wire.
Problems panel — live validation: missing asset, broken wire, duplicate scene name
Per-rule Test control in the flow UI — fires a synthetic event for that graph without full play (where available)
Ctrl+Z undoes graph edits (node moves and multi-node deletion each collapse into one step). Press A to open the add palette at the canvas center, or double-click the exact place you want to add. Ctrl/Cmd+D duplicates selected nodes inside an open graph. Full debug recipes: Testing and debugging.