Verse Wiki — the Verse handbook for Blueprint authors
Chapter 2 · Lesson 7

Comments, Modules & using: Notes for Humans, Boxes for Tools

The first three lessons of Chapter 2 lined up the vocabulary, the structure and the class. This one closes the chapter with what's left: how the code itself gets sorted into compartments. Comments are notes for humans, modules are a pegboard with dividers, and using hauls a toolbox onto the workbench — the order Blueprint keeps with assets and folders, rebuilt out of plain text.

1. Comments: Notes to Your Teammates (and to You, Three Months from Now)

Lesson 4 handed you a glossary, Lesson 5 unfolded the node graph into indented blocks, and Lesson 6 moved a whole Blueprint class into a .verse file. By now you can write a class that runs — but a real project is never one class. The last lesson of Chapter 2 closes the loop on how the code itself gets sorted into compartments: which words are meant for humans, which definitions belong in the same box, and how code elsewhere finds that box. In Blueprint those three jobs belong to the Comment box, the asset folder, and the asset reference. In Verse they're called comments, modules, and using.

Code has two audiences: one is the compiler, the other is people — your teammates, plus the future you who comes back in three months having forgotten every thought you had while writing it. Comments are notes written specifically for that second audience: the compiler skips right over them, they have zero effect on how the program behaves, and yet they rescue countless late nights of "what on earth was this line trying to do."

Verse offers three ways to write comments, each covering its own scenario:

comment_gallery.verse
# Line comment: everything from # to the end of the line is for humans

MaxPlayers:int = 8  # it can also tag along after code

<# Block comment: write as many lines as you like,
   it only ends at the closing marker #>

Total:int = 1 <# it can even squeeze into the middle of a line #> + 2

<#>
    Indented comment: this block is indented deeper than the marker above,
    so the whole thing is a note — the compiler reads not a single word.

(Blueprint view: in Blueprints you leave notes by dragging out a gray Comment box, or right-clicking a node to add a Node Comment. Verse has no boxes to drag — instead you type the markers #, <# #>, and <#> straight into the code. The form changed, the job didn't: for human eyes only, treated as thin air at Compile time.)

"Comments never execute" is the kind of fact better witnessed than memorized. The device below has a chunk of old code buried inside a block comment — click "Run next step" and see whether it ever gets a scene:

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

# This device does exactly one thing: prove that comments never run
memo_device := class(creative_device):

    OnBegin<override>()<suspends>:void =
        Print("Step 1: boot self-check")  # end-of-line comment, leaves the left side alone
        <# This old line has been retired; the compiler won't even look:
           Print("I am the commented-out code")
        #>
        Sleep(1.0)
        Print("Step 2: comments stayed offstage the whole time")
Output log

Click "Run next step" and watch the code execute line by line.

One side note: the community often says block comments can nest inside each other, but the behavior varies between versions, so this course won't rely on that feature — for the exact nesting rules, defer to the Verse API Reference. If you really need to wrap content containing #>, run a Build first and verify for yourself.

2. Modules: The Code World's Compartmentalized Tool Wall

Picture a wall covered in tools: if the hammers, screws, band-aids, and potato chips all pile into one big crate, finding anything takes forever. Real projects are the same — devices, characters, random numbers, UI: stuff hundreds of Blueprints and assets into a single giant drawer with no naming scheme and you get duplicate names, grabbing the wrong asset, and never finding anything. Verse's answer is the module: pack related definitions into one box — a box with a name, a boundary, and the ability to be picked up and reused as a whole.

The official definition of a module is rather solemn: "A Verse module is an atomic unit of redistributable, dependable code that can evolve over time without breaking its dependents." In plain speech: a module is the smallest unit for shipping an API — Epic can upgrade a module's internals while your code keeps running untouched. Today, in UEFN, every official capability you can call — every device, every function — lives in some module; and every folder under your own project's Verse directory automatically becomes a module of the same name too (that's the key to organizing multi-file projects — the extra pages have the full walkthrough).

So step one of "writing Verse" is always: figure out which box the thing you need lives in, then haul that box over — and hauling the box is exactly what using does.

3. using: Hauling the Toolbox onto the Workbench

using has exactly one syntax, and not a single curly brace is optional:

A typical file opening
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

What it does: it pulls in everything the given module (that tool drawer) exposes to the outside, all in one go, so you can just write the short name creative_device instead of chanting the full-length address every time. It's the same move as ticking a plugin on for your project, or pulling an asset folder into scope. You can survive without using — reciting the entire long path from memory still works — but nobody enjoys doing that on every line. By convention, all the using lines stack up at the very top of the .verse file, like laying every tool you'll need that day out on the bench before you start.

Here's what the common paths cover. Just get acquainted for now — come back and look things up whenever you forget:

Module path What it covers Notable members
/Fortnite.com/Devices The creative_device base class plus every built-in device creative_device, button_device
/Fortnite.com/Characters Game characters fort_character
/Fortnite.com/Game General definitions for the Fortnite gameplay layer
/Verse.org/Simulation Time and simulation Sleep
/Verse.org/Random Random numbers GetRandomInt, GetRandomFloat
/Verse.org/Colors Colors color
/UnrealEngine.com/Temporary/Diagnostics Debug logging tools the log logging class
/UnrealEngine.com/Temporary/SpatialMath Spatial math vector3
/UnrealEngine.com/Temporary/UI User interface

Notice anything? These paths look like URLs: they start with /, and the top level is an internet domain — Fortnite.com, Verse.org, UnrealEngine.com. That's a deliberate design — the domain marks who owns the API and what stability it promises: /Verse.org is language- and general-runtime-level capability, /Fortnite.com belongs to the Fortnite ecosystem, /UnrealEngine.com comes from the engine side. And the Temporary segment in a path is Epic saying out loud that "these APIs are in temporary housing and will move someday" — so don't panic when you see it, and don't be shocked if a using needs updating one day. One more bit of trivia: Print itself lives in the /Verse.org/Verse module, which is available without an explicit using — that's why the earlier lessons never wrote an import for Print; what the Diagnostics line in the template actually provides is debug tooling like the log logging class.

Hands-on time: the opening of the "nap device" below has two words carved out — one is the keyword that hauls toolboxes, the other is the module Sleep lives in. Fill them back in, then hit "Check answers":

(Reading the graph: this device equals an Event BeginPlay wired to a Print String "Napping for 3 seconds..." → a 3-second Delay → another Print String "Awake!"; those using lines at the top simply tick open the drawers where Delay and the string printing live.)

nap_device.verse
____ { /Fortnite.com/Devices }
using { /Verse.org/____ }
using { /UnrealEngine.com/Temporary/Diagnostics }

nap_device := class(creative_device):

    OnBegin<override>()<suspends>:void =
        Print("Napping for 3 seconds...")
        Sleep(3.0)
        Print("Awake!")

4. Building a Module of Your Own: Just a First Hello

You can use other people's modules — now stake out a patch of your own. The most direct way is to hand-write a small module declaration and open a brand-new drawer for yourself:

tools.verse
# Stake out a patch by hand with a module expression
tools<public> := module:
    Greet<public>():void =
        Print("Greetings from the tools module")

(Reading the graph: the snippet above creates a new tool drawer called tools holding one Blueprint function Greet, whose body is a single Print String; the two <public> marks hang a "visible to the outside" sign on the drawer and on the function respectively.)

After that, write using { tools } in another file (pulling the tools drawer open) and you can call Greet() directly; too lazy to open the drawer, the full name tools.Greet() finds it too. The other, more common road is the implicit module: every folder under your project's Verse directory automatically becomes a module of the same name — making a folder is making a module, zero lines of code required.

Those <public> angle brackets on the code do exactly what the Public / Protected / Private access setting does for variables and functions in Blueprint — Verse just writes it as angle brackets hanging off the name. Verse has four levels: public (anyone can use it), internal (the default — current module only), protected (the class and its subclasses), and private (the current class only). Only one iron rule matters right now: for code outside the module to use a member, both the module and the member must be marked <public> — miss either one and the caller slams into an access error. The full craft of organizing modules and nested references lives in this lesson's extra pages; the complete rulebook for visibility specifiers waits for Lesson 22, specifiers and attributes. A passing acquaintance is plenty for today.

5. Classic Pitfalls: The Moment You Forget using

Pitfall 1: forget the using, collect an "Unknown identifier". This is the number-one accident in a fresh blank .verse file: you eagerly type my_device := class(creative_device):, hit Build, and the compiler throws back "Unknown identifier" — it has no idea what creative_device is. The reason is simple: creative_device isn't a keyword, just a class inside the /Fortnite.com/Devices module; if the toolbox never got hauled in, the tools inside it don't exist. From now on, whenever you see Unknown identifier, your first reflex should be: am I missing a using line?

Pitfall 2: using without the curly braces. Writing using /Fortnite.com/Devices is a straight-up syntax error. The braces are part of the using syntax, not decoration.

Pitfall 3: a block comment left unclosed. You wrote the <# and forgot the #>, and a long stretch of perfectly good code gets swallowed as a comment. Even sneakier: the error usually points somewhere far down the file, miles away from the actual crime scene. When you see baffling errors across a wide area, go back and hunt for an unclosed <#.

Pitfall 4: casually renaming a folder. Folders are modules — renaming or moving a folder changes the module path. Best case, a string of using lines breaks; worst case, Verse devices already placed in your level lose their class references. Before renaming, first ask how many places point at it.

One more thing: importing nested modules is order-sensitive — import the outer module first, then the submodule; the reverse errors out. That pitfall, along with the complete playbook for cross-folder references, lives in this lesson's extra page.

Blueprint Cross-Reference

"Organizing your code" is something you already do in Blueprint — it's just hidden inside the editor UI and the asset system. Line the two up item by item; the difference column is the point.

How you do it in Blueprint How you write it in Verse Difference
Leaving a note: drag a gray Comment box around a few nodes, or right-click a node for a Node Comment # line comments, <# … #> block comments, <#> indented comments A Blueprint Comment box is an object with a position, a color and a drag handle; a Verse comment is just characters — it takes up no canvas and nobody can drag it off by accident
Using a node: search the node palette, and if it shows up you can drop it in using { /Fortnite.com/Devices } first, and only then can you write creative_device The Blueprint palette lays everything available in front of you by default; Verse makes you name the module first — anything you didn't name simply "doesn't exist"
Collecting reusable functions: make a Blueprint Function Library asset and put them in it Make a module — write tools<public> := module:, or just make a folder A Function Library only holds functions; a Verse module holds anything: classes, functions, constants, enums, other modules
Checking where a node came from: the tooltip or Details panel tells you which plugin/module it belongs to The module path is the origin: /Verse.org/Simulation, /UnrealEngine.com/Temporary/SpatialMath In Blueprint "where it came from" is metadata you have to open something to see; in Verse it's printed on the first screen of the file — and a segment like Temporary tells you outright that this batch of APIs will move house one day
Organizing a project: asset references plus the Content Browser folder tree, with name clashes settled by asset path Namespaces: module paths keep names apart, so two different door types in two modules never collide An asset reference is a pointer inside a binary — only the editor's Reference Viewer can show it; a module path is plain text you can grep, diff, and read out loud in a code review
Declaring dependencies: there is no such layer. To learn what a Blueprint uses, you run the Reference Viewer backwards Those few using lines at the top of the file are the file's dependency list The price is a few extra lines; the payoff is knowing what a file depends on the second you open it — and also that classic error, forget the using and collect an Unknown identifier

All of these differences grow from one root: Blueprint hands "who can see what" to the editor, Verse hands it to the words you type into the file. The palette pre-filters the nodes you may use, an asset reference is created the instant you drag something in, and even access level hides behind a dropdown in the Details panel — most of Blueprint's organizational structure is a by-product of the UI. Verse has no UI to lean on, so it lifts the same information into the open: using what you use, mark <public> what you want opened, and let folder boundaries be module boundaries.

What you write out ends up wordier than a Blueprint. The payoff is that it becomes searchable, comparable text. "Which modules does this file depend on" means clicking through the Reference Viewer in Blueprint; in Verse it's the first three lines of the file. "Who changed a module's visibility last week" is nearly unanswerable in Blueprint; in Verse it's one line of a diff. That's also why, on the glossary table back in Lesson 4, so many Blueprint concepts map not to a Verse feature but to "a piece of text you write yourself".

6. Level Challenges

Three little challenges to bank this lesson's loot. Wrong answers cost nothing — retry as often as you like.

You create a blank .verse file, write nothing at the top, go straight to my_device := class(creative_device): and hit Build. What happens?

You want to comment out a big chunk of old code in one piece. Which syntax should you use?

Your code calls Sleep(2.0), and Build reports "Unknown identifier". Which using line is most likely missing?

Further Reading

Deep Dive · EXTRA

The digest Files: An API Dictionary Fresher Than the Docs Site

The .digest.verse files generated on every build are a complete API inventory in strict sync with your local version — a veteran's first stop for API lookups.

Open the extra →

Level Up · EXTRA

From .vmodule to "Folders Are Modules"

The UEFN 23.20 module system overhaul: why making a folder means making a module today, and the design motive behind the internal default.

Open the extra →

Pro Tip · EXTRA

Referencing Your Own Modules Across Folders, the Right Way

A quick-reference for using syntax across same-directory, subfolder, and nested-module scenarios — plus the iron rule of outer-module-first import order.

Open the extra →