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 →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.
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:
creative_device = a brick cast from your own mold, with whatever logic you care to write.creative_device as its parent Blueprint = a brick cast from your own mold, with whatever logic you care to write.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.
Defining a device takes a single line of declaration. Start with a minimal working example:
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:
my_device — the name you give your device. Class names use lower_snake_case (all lowercase + underscores), the naming etiquette laid down by the official Verse Code Style Guide — creative_device itself is a textbook example;:= — read it as “is defined as”. The name goes on the left; what that name actually is goes on the right. Note it is not the same as a bare = — in Verse, = compares things; to define something new, reach for :=;class(creative_device) — announces “I am a class, and I inherit creative_device’s entire estate”: I can be dragged into a level, and I wake up automatically when the game experience starts;class(creative_device) — announces “I am a Blueprint, creative_device is my parent, and I inherit its entire estate” (just like creating a Child Blueprint Class from a parent class): I can be dragged into a level, and I wake up automatically when the game experience starts;: + a 4-space indent on the next line — Verse has no curly braces; indentation is the code block. The colon says “the contents live below”, and the 4 spaces say “I am those contents”.: + a 4-space indent on the next line — Verse has no curly braces; indentation is the grouping. In Blueprint, which exec wire a node hangs on and which event owns it is expressed by wiring; Verse has no wires, so indentation stands in — the colon says “the contents live below”, and every line indented 4 spaces deeper counts as “the chain of nodes wired in after this line”.One-line summary: name := class(ancestor):, then indent and write its skills. That is genuinely all there is to it.
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.
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.
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.")
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.
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:
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.
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.
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.
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.
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.
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?
Tip · EXTRA
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
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
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 →