Verse Wiki — an interactive Verse handbook for the Unreal Engine & UEFN ecosystem
Chapter 1 · Lesson 2

Your First Device, creative_device: Build a Logic Brick of Your Own

Last lesson you met the Verse language. This lesson turns code into a physical thing: define a creative_device with your own hands, decode the fixed OnBegin incantation token by token, then walk the full Build → drag-and-drop → launch-session pipeline until your first logic brick is genuinely running in a level.

Last lesson you met the Verse language. This lesson turns code into a physical thing: define a creative_device with your own hands, take the fixed OnBegin line apart piece by piece (like opening up a Blueprint node and inspecting every one of its pins), then walk the full Build → drag-and-drop → launch-session pipeline until your first logic brick is genuinely running in a level.

1. creative_device: a “Logic Brick” You Can Drag Into a Level

If you have played Fortnite Creative, you have fiddled with all kinds of devices: buttons, barriers, scoreboards, launch pads… They are like LEGO bricks — drag them into a level, tweak a few settings, and a mechanic takes shape. But sooner or later the stock bricks run out — and that is when creative_device steps in.

creative_device is the base class for custom Verse devices. It lives in the /Fortnite.com/Devices module and is the founding ancestor of every “custom device”. As soon as your class inherits from it, compiling turns your code into a brand-new brick: it shows up in the Content Browser and can be dragged into a level and set down on the ground just like an official device. In other words:

creative_device is the parent Blueprint of custom Verse devices. It lives in the /Fortnite.com/Devices drawer (module) and is the founding ancestor of every “custom device”. Have your new device claim it as its parent (just like creating a Child Blueprint Class from a parent class in Blueprint), and after Compile your code becomes a brand-new brick: it shows up in the Content Browser and can be dragged into a level and set down on the ground just like an official device. In other words:

Two iron rules to memorize right now. One: every Verse class you want to drag into a level must inherit from creative_device — without that inheritance, even the prettiest code is just a schematic that never leaves the drawing board. Two: only device instances actually placed in the level ever execute — and every copy you drag in runs its own logic, so the same brick can be doing a different job in every corner of your island.

Two iron rules to memorize right now. One: every Verse device you want to drag into a level must claim creative_device as its parent Blueprint — without that parent, even the prettiest code is just a schematic that never leaves the drawing board. Two: only device instances actually placed in the level ever execute — and every copy you drag in runs its own logic, so the same brick can be doing a different job in every corner of your island.

2. One Declaration, Four Parts: my_device := class(creative_device):

Defining a device takes a single line of declaration. Start with a minimal working example:

my_device.verse
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }

# A minimal working custom device
my_device := class(creative_device):

    OnBegin<override>()<suspends>:void =
        Print("Device is online!")

Reading the graph: this code is one Blueprint. The two using lines at the top are like pulling open the Devices and Diagnostics drawers so the parts inside are within reach; my_device := class(creative_device) creates a new Blueprint with creative_device as its parent; the OnBegin line is this graph’s Event BeginPlay node; and the indented Print below it is a Print String node wired in after it, printing “Device is online!” in the top-left of the screen.

Take the declaration line apart and you get four parts:

One-line summary: name := class(ancestor):, then indent and write its skills. That is genuinely all there is to it.

3. Token-by-Token Breakdown: OnBegin<override>()<suspends>:void =

3. Part-by-Part Breakdown: OnBegin<override>()<suspends>:void =

That line in the class body — OnBegin<override>()<suspends>:void = — is where many newcomers take one look and consider quitting: six parts crammed into a single line. Don’t panic. We will strip it down like weapon attachments, one token at a time:

That line in the device Blueprint — OnBegin<override>()<suspends>:void = — is where many newcomers take one look and consider quitting: six parts crammed into a single line. Don’t panic. We will strip it down like weapon attachments, one part at a time:

token Read as What it does
OnBegin “when the show starts” The function name. It is a lifecycle function handed down from creative_device, called automatically by the engine when the game experience starts — you never call it yourself. Function names use PascalCase (capitalized words), the exact opposite of the lower snake_case used for class names This is the device’s Event BeginPlay — the moment the game experience starts, the engine fires it for you; you never trigger it by hand. The name uses PascalCase (capitalized, like OnBegin), the exact opposite of the all-lowercase-with-underscores style used for device names (my_device)
<override> “the override badge” A specifier: OnBegin is already defined in the base class, and to overwrite that inherited family technique you must flash this badge. Omit it = compile error This badge declares “I am rewriting the OnBegin that already exists in the parent Blueprint” — like picking a parent function from a Blueprint’s Override dropdown to rewrite it. Forget the badge and Compile lights up red with an error
() “takes no parameters” The parameter list. OnBegin accepts no parameters at all, but the empty parentheses can never be skipped
<suspends> “the meditation badge” A specifier declaring this a suspendable async function — it can pause mid-run (waiting on Sleep, say) and wake up later. The base class’s OnBegin signature carries it, so your override must carry it too; drop even one and the signatures no longer match This badge declares the function can wait partway through — inside it you can place little-clock nodes like Delay (a Sleep for a few seconds, say) before continuing. The parent Blueprint’s OnBegin wears it, so your override must wear it too; lose one badge and yours no longer matches the parent’s
:void “nothing to hand in” The return type. void means the function returns no meaningful value — it just does the work, with no result to hand back This states what gets handed back. void means the function passes nothing out — its Return node has no output pins; it just does the work, with no result to hand back
= “is defined as” The signature ends here; the function body starts on the next line, indented 4 spaces The definition part of this line ends here; the actual chain of nodes to run gets wired in starting on the next line, indented 4 spaces

For now the memorization strategy is blunt: this entire line is a fixed incantation — learn it verbatim. Its official meaning is “override this function to add custom logic when the game experience begins”. And precisely because it carries <suspends>, the function body can directly call async APIs like Sleep(seconds) — the star of the next section.And precisely because it carries <suspends> (the waiting badge), the body can directly hold waiting, little-clock nodes like Sleep(seconds) (Blueprint’s Delay) — the star of the next section. Incidentally, OnBegin has a twin, OnEnd<override>():void =, which runs when the game experience ends — note that it carries no suspends. Its story is told in this lesson’s advanced extra.

4. Full Example: welcome_device — It Greets, It Meditates

Snap this lesson’s parts together and build a “welcome device”: the moment the game starts it calls out a greeting, meditates in place for 3 seconds, then follows up with a tip. Sleep comes from the /Verse.org/Simulation module, hence the extra using line at the top of the file.Sleep lives in the /Verse.org/Simulation drawer, hence one more drawer pulled open at the top of the file (that extra using line). Hit “Run Next Step” and watch the code execute line by line — pay special attention to the Sleep(3.0) step, where the output log freezes completely. That is what “waiting” looks like.

welcome_device.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

# A welcome device that greets players
welcome_device := class(creative_device):

    OnBegin<override>()<suspends>:void =
        Print("Welcome to my island, adventurer!")
        Sleep(3.0)
        Print("Tip: there is a supply chest next to the spawn point - grab it before you head out.")
Output Log

Hit “Run Next Step” to watch the code execute line by line.

Mini experiment: reset and run it once more, and imagine the version without Sleep — both lines would pop out in the same instant, and players might not catch either one. Pacing is part of design, too.

5. From Code to Level: Compile and Report for Duty in Four Steps

Enough theory-crafting — here is the full pipeline for putting welcome_device into an actual game. Four steps, and you will own the first custom brick of your life:

Step 1: Create the Verse File

Open the Verse Explorer panel, right-click your project name, choose “Add new Verse file to project”, and pick the Verse Device template. Double-click the generated .verse file and it opens in Visual Studio Code — type the code above in by hand; muscle memory is precious.

Step 2: Compile (Build Verse Code)

Back in UEFN, click “Build Verse Code” in the toolbar’s Verse menu, or just press Ctrl+Shift+B — every .verse file in the project compiles together. On success, a green check mark appears on the Verse button; on failure it is a red stop icon, and clicking “See Errors” in the error popup opens the Message Log listing every error — until they are all fixed, your code cannot enter playtesting.

Step 3: Drag It Into the Level

Once the build succeeds, you will find welcome_device in the Content Browser under your project’s content folder — congratulations, your brick just rolled off the line! Drag it anywhere on the island; it is a logic brick and does not care about feng shui. Remember: a device never dragged into the level executes exactly zero lines of code.

Step 4: Launch a Session and Watch the Log

Click “Launch Session” to start a game session. Print messages show up in three places at once: as debug text on the game screen, in the in-game log, and in UEFN’s Output Log panel. You will see the greeting pop up first and the tip follow 3 seconds later — exactly as the stepper rehearsed it.

If the log in Step 4 matches what you expected, stop and celebrate for ten seconds: you have just closed the full write code → compile → deploy → verify loop — the exact spot where plenty of people stay stuck for days.

Common Pitfalls: A Field Guide to Beginner Mistakes

6. Level Challenge ★

This lesson’s BOSS fight is one fill-in-the-blanks plus three multiple-choice questions. Correct answers earn stars; wrong answers retry freely — no punishment mechanics.

my_first_device.verse
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }

my_first_device := ____(____):

    OnBegin<____>()<____>:void =
        Print("My first device is online!")

Your code compiles (the green check mark is lit), yet after launching a session nothing happens. The most likely cause?

You write OnBegin as OnBegin<override>():void = (dropping the suspends badge). What happens?

What does pressing Ctrl+Shift+B in UEFN do?

Extra Reading

Tip · EXTRA

Sleep One Frame First: The Sleep(0.0) Community Trick

Why do veterans put Sleep(0.0) on the first line of OnBegin? One line of code that dodges the silent failures of frame one.

Open the extra →

Extension · EXTRA

Hot Reload Without Restarting: Push Verse Changes and the Iteration Workflow

Swap in new logic without restarting the session — Verse hot reload and incremental cooking rescue you from “one edit, one restart”.

Open the extra →

Advanced · EXTRA

Device Lifecycle: OnBegin, OnEnd, and the Swallowed Coroutine

A device’s full life from wake-up to curtain call, and why the official docs warn “don’t spawn in OnEnd”.A device’s full life from wake-up to curtain call, and why the official docs warn “don’t spawn in OnEnd” (spawn = branching off a fresh exec wire on the fly).

Open the extra →