Skip to content

Flow as text

Every Opal flow graph can be edited two ways: as nodes on the canvas, or as readable text. It's the same graph either way — text is a view over it, not a separate file. If you'd rather type behavior than wire nodes, this is for you.

Look for the Text button in the flow board toolbar, next to Tidy and Fit. Click it to see the open graph as text; click it again to return to nodes.

on tap actor self:
  if variable equals key "isOpen" value true:
    bounce self
  else:
    say self key "Locked" value 2000

That block is the node graph above — one On Tap rule with a condition that branches to a bounce or a "Locked" message.

One graph, two views

Editing as text and editing as nodes both change the same graph and share the same undo history (Ctrl+Z). Switching views never converts or duplicates anything.


Reading a graph

A graph reads top to bottom, indented like an outline. Each line is one step; indentation groups the branches and blocks beneath it.

The event line

The first line is the trigger — the on <event> that starts the graph:

on tap actor self:
on collision actor #enemies:
on timer key "wave" value 1000:
on sceneStart:

Actors and targets name who the event is about:

In textMeans
selfThe object that owns the graph
targetThe other object in the event (collision partner, drop target, …)
hit / sourceContext objects for specific events
#groupNameAny object in that group
"objectId"One specific object, by id

Actions

Actions are verbs. The verb is the action's name; a subject and any settings follow:

bounce self
shake self value 2 duration 500
spawn object key "enemy" target self offset (10, 0)
go to scene key "level2"
set variable key "score" value 10

The subject (self, target, …) comes first when the action acts on an object. Settings are name value pairs — key "…" for names and text, plain numbers for amounts, (x, y) for offsets.

Conditions

if splits the flow; else is optional:

on tap actor self:
  if variable at least key "coins" value 3:
    go to scene key "shop"
  else:
    say self key "Not enough coins" value 1500

Variables

Graph-local variables are declared once, under the event line:

on sceneStart:
  var timer: number = 0
  var armed: boolean = false

Expressions

Any setting can be a computed expression instead of a fixed value. Write setting = <expression>:

on sceneStart:
  var multiplier: number = 3
  set variable key "score" value = var("score") + 10 * var("multiplier")

Expressions support:

KindExamples
Numbers, text, true/false10, "win", true
Graph variablesvar("multiplier")
Arithmetic+ - * / %
Comparisons> < >= <= == !=
Logic&& || not(x)
Functionsmin(a, b), max, abs, round, clamp(v, lo, hi), lerp(a, b, t)

Parentheses group as you'd expect: set variable key "n" value = (var("a") + 1) * 2.


It's safe to edit

The text view is built so you can't lose work:

  • A typo never breaks your graph. If the text doesn't parse, nothing is applied — your node graph and undo history are untouched — and the error is shown so you can fix it in place.
  • Every apply is one undo step. Commit a text edit, press Ctrl+Z, and it reverts as a single change, exactly like a node edit.
  • Committing happens when you leave the field (click away) or toggle back to nodes. Nothing is applied while you're mid-type.

When a graph opens read-only

Some graphs use parts the text grammar can't fully express yet. Rather than risk dropping them, those graphs open read-only with a banner naming what's involved — you can read the text, but you edit that graph in the node view.

A graph is read-only when it contains:

  • Component actions or Script nodes — their configuration lives outside the text grammar
  • Component or Expression conditions
  • Value wires the grammar can't render yet (e.g. reading a component field or scene value into a setting)
  • Comments or disconnected nodes that the text outline wouldn't include

Everything else — events, if/else, action verbs, variables, and variable-based expressions — is fully editable. The editable set grows as the grammar expands; read-only is always the safe fallback, never a data risk.


What text doesn't show

Text captures the logic of a graph — the trigger, the steps, the connections, the variables. It does not capture visual layout: node positions and pan/zoom are the node view's concern and are regenerated automatically when you switch back. Two graphs that behave identically read as identical text.


Tips

  1. Reach for text on dense logic — a long if/else chain is often faster to read and edit as an outline than as a fan of wires.
  2. Stay in nodes for wiring-heavy graphs — data-flow webs and component calls are clearer on the canvas (and may be read-only in text for now).
  3. The two views round-trip — flip to text to skim what a graph does, flip back to nodes to fine-tune connections.
  4. Undo works across both — edit in text, undo, and continue in nodes seamlessly.

  • Visual scripting — the node view: events, wires, the catalog, and the inspector
  • Scripts — write reusable behavior in code, including behavior scripts on objects
  • Testing and debugging — the live Flow overlay and Graph Explorer

Opal Engine — MIT licensed