Event node (e.g. "On Actor Overlap")
Verse: Device.SomeEvent.Subscribe(Handler)
You wire behavior by subscribing a function to the event, and you must keep the returned cancelable if you ever want to unsubscribe.
Every Blueprint node and concept, mapped to its Verse equivalent for UEFN.
You already know this from Blueprints. Below is every Blueprint node and concept the Verse Nodegraph Editor understands, next to its real Verse equivalent and the one-sentence gotcha that actually trips people up — not “Verse is just Blueprints in text,” but exactly where the two genuinely differ. Common gameplay concepts (events, branches, casts, loops, variables) come first; the rest follows below.
Each entry links into the live editor, where you can wire up the Blueprint-style node graph yourself and watch it write real, plain-text Verse — no install, free, in your browser.
Open the live editor →Verse: Device.SomeEvent.Subscribe(Handler)
You wire behavior by subscribing a function to the event, and you must keep the returned cancelable if you ever want to unsubscribe.
Verse: if (Cond) { ... } else { ... }
Cond doesn't have to be a plain true/false — it can be any operation that can fail, and failure steers the flow just like "false" would.
Verse: if (C := Agent.GetFortCharacter[]) { ... }
The "Cast Failed" pin becomes the else branch; the [ ] means "this call can fail" — a Branch node whose condition looks like this shows "worked"/"didn't-work" on its own exec-outs instead of true/false, so the graph gives you that Cast Failed shape automatically.
Verse: set X = value
Only works on a var — Verse data is immutable unless you declared it mutable up front. Forgetting this is the #1 beginner mistake.
Verse: X (just reference the name — no extra syntax to read a value)
Reading a value has no ceremony in the text; the graph still shows a Get node because you need something to drag a wire from.
Verse: for (X := Collection) { ... }
Runs the body once per item, binding it to X each time — no manual index counting.
Verse: for (I := IndexRange) { ... } (iterate a number range: for (I := 0..Count-1))
The same for node covers both this and ForEach — iterate a range for an indexed loop, or a collection directly for ForEach. Verse doesn't need two different nodes.
Verse: loop { if (not Cond) { break } ... }
Verse has no condition-checking loop head — Loop repeats forever, so a While is a Loop with a Branch + Break checking the condition yourself.
Verse: Print(Message)
Writes text to the on-screen debug log — same purpose, same "just for testing" feel.
Verse: return Value (or simply the function's last expression)
Sends a value back to the caller — but Verse won't let you write an explicit return from inside a failure context (an if-condition, etc.), a rule Blueprint has no equivalent of.
Verse: case (Subject): pattern => ...
Picks one branch by matching Subject against each listed pattern, checked top to bottom.
Verse: X := if (Cond) { A } else { B } (an if-expression, not a statement)
Select picks between two values without touching exec flow; Verse's if-expression does the same — it evaluates to a value instead of running exec pins.
Verse: Sequential statements, one after another (the exec wire itself)
Sequence just runs its outputs in listed order — that's already what consecutive lines/nodes do, so there's no dedicated node for it.
Verse: Sleep(Seconds) inside a <suspends> function
Delay "infects" the whole function — every function that (directly or indirectly) waits gets marked <suspends>. The graph adds this for you.
Verse: break
Stops the loop immediately and continues with whatever comes right after it.
Verse: Methods on a class(creative_device); OnBegin<override>()<suspends> is the entry point
There is no single canvas — logic lives on typed methods spread across the class, and OnBegin is the one Verse calls automatically when the device starts.
Verse: Indentation-scoped sequential statements (Python-like)
Order comes from where a line sits, not from a wire you dragged — the node graph re-adds that wire visually so nothing here changes for you.
Verse: let / X := value (immutable) vs. var X : type = value (mutable)
Blueprint never makes you choose — Verse forces the mutable/immutable decision the moment you create the variable.
Verse: Static types, checked at compile time
Type mistakes are caught before you ever run anything, instead of failing (or silently misbehaving) at runtime.
Verse: A loop + Sleep(0.0) inside a <suspends> function
There is no visual curve editor — a timeline becomes a hand-written per-frame loop.
Verse: sync / race / rush / branch (structured), spawn (unstructured)
Blueprint runs things in parallel implicitly; Verse makes you pick exactly how the parallel branches relate to each other.
Verse: Fn()<computes>: int = ... (and other effect specifiers)
Verse makes you declare what a function is allowed to do (compute only, fail, wait, …) — Blueprint has nothing like it. The editor infers these for you.
Verse: interface + <override>
Same idea as a Blueprint Interface, just declared as text rather than in a separate asset.
Verse: @editable
A typed attribute, per-instance in the UEFN Details panel — and it fails silently if the class isn't concrete, which the eye icon never warned you about.
Verse: option / ?type — unwrapped with a failable ?
There is no null — "no result" is a typed value you must explicitly unwrap in a failure context, instead of an IsValid check you can skip.
Verse: Arr[i] (failable)
Blueprint quietly returns a default/None on a bad index; Verse won't compile unless the failure is handled somewhere.
Verse: map — lookup is failable, returning an option
A missed key is a failure to handle, not a None value you can ignore.
Verse: struct and tuple (int, string)
Tuples add positional (unnamed) grouping on top of what Blueprint's Make Struct gives you.
Verse: using { /Fortnite.com/Devices }
Nothing is in scope by default — this tool derives the using list for you automatically from the types you actually reference.
Verse: Type the value directly into any input's inline field (0, "text", true, …)
There are no separate literal-constructor nodes — every data input already has an editable inline default; there's nothing extra to place or wire.
Verse: var Open : logic = true ... if (Open) { ... }
No dedicated node — model an open/closed flag as a var bool you flip with Change a value, guarded by a Branch (if).
Verse: var HasRun : logic = false ... if (not HasRun) { set HasRun = true; ... }
No dedicated node — a var bool "has it run yet" flag checked by a Branch gives the same "only the first time" behavior.
Verse: var Toggle : logic = false ... if (Toggle) { ... } else { ... }; set Toggle = not Toggle
No dedicated node — a var bool flag flipped after each run, checked by a Branch, alternates between the two paths the same way.