Shout into the Void: print/log debugging
In this lesson you'll learn to
- βStudent can instrument any Verse script with Print statements and read the output log to trace game flow and diagnose bugs.
Student can instrument any Verse script with Print statements and read the output log to trace game flow and diagnose bugs.
π Reference & full walkthrough: Shout into the Void: print/log debugging
π Builds on: north-jungle: verse language fundamentals (first-script, functions)
π§© Your capstone piece: The RaceDebug logger used in every later step (toggleable debug overlay of race state)
What you'll learn
You'll learn how to use Print() for log-based tracing with string interpolation, and how to surface those same debug values on-screen by building a canvas with a text_block and adding it to a player's UI via GetPlayerUI[] / AddWidget. Every button press updates both the log and the widget, so you can watch state change without squinting at the console.
How it works
Print() writes a single string to the Output Log (and screen). Its most important rules:
- One string only. Never pass comma-separated arguments. Combine values with string interpolation
{...}β the braces evaluate the expression and convert it to text:Print("2 + 2 = {2 + 2}")logs2 + 2 = 4. - No
+on messages. Build output with interpolation, not concatenation. - Top-to-bottom execution. The order your prints appear tells you the order your code ran β the cheapest way to see how far execution got.
The log is great for you, but invisible to players. To show debug text on screen we use the player UI:
Player.GetPlayerUI[]is fallible ([]), so bind it inside anif:if (UI := Player.GetPlayerUI[]):.- Build a
canvaswhose slot holds atext_block, then callUI.AddWidget(Canvas). - Keep a reference to the
text_blockand call.SetText(...)to update it live.SetTexttakes amessage, so we wrap interpolated text with a<localizes>helper.
Let's build it
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
using { /UnrealEngine.com/Temporary/SpatialMath }
# A debug device: logs with Print() AND mirrors values on an on-screen widget.
debug_print_device := class<concrete>(creative_device):
# Drag a Button device into this slot in the Details panel.
@editable TriggerButton : button_device = button_device{}
# Mutable counter so we can watch state change across presses.
var PressCount : int = 0
# The on-screen text widget we update live. Created in OnBegin.
var DebugText : text_block = text_block{}
# <localizes> helper turns interpolated text into a message for SetText.
MakeMessage<localizes>(Value : string) : message = "{Value}"
OnBegin<override>()<suspends> : void =
# 1. Prove OnBegin actually ran.
Print("[Debug] debug_print_device started!")
# 2. Interpolate a value and a calculation into the log.
Counter : int = 42
Print("[Debug] Counter = {Counter}, Doubled = {Counter * 2}")
# 3. Build the on-screen widget and add it to every player's UI.
set DebugText = text_block{DefaultText := MakeMessage("[Debug] Ready. Presses: 0")}
Canvas := canvas:
Slots := array:
canvas_slot:
Anchors := anchors{Minimum := vector2{X := 0.05, Y := 0.05}, Maximum := vector2{X := 0.05, Y := 0.05}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.0, Y := 0.0}
SizeToContent := true
Widget := DebugText
for (Player : GetPlayspace().GetPlayers()):
if (PlayerUI := GetPlayerUI[Player]):
PlayerUI.AddWidget(Canvas)
# 4. Subscribe so each press updates log AND widget.
TriggerButton.InteractedWithEvent.Subscribe(OnButtonPressed)
# Handler signature must match the button event: (agent):void.
OnButtonPressed(Agent : agent) : void =
set PressCount = PressCount + 1
# Log it...
Print("[Debug] Button pressed. PressCount = {PressCount}")
# ...and mirror it on the screen widget.
DebugText.SetText(MakeMessage("[Debug] Presses: {PressCount}"))```
## Try it yourself
1. Create a new Verse device in UEFN and paste in the code above.
2. Build Verse, then drag `debug_print_device` into your island.
3. Place a **Button** device and assign it to the `TriggerButton` slot.
4. Launch a session. Watch the Output Log for the `[Debug]` startup and counter lines, and confirm the on-screen text appears at the top-left.
5. Press the button repeatedly β the log AND the widget should both show `PressCount` climbing.
6. Change `Counter` or the `* 2` math, rebuild, and confirm the interpolated output updates in the log.
## Recap
- `Print()` takes exactly **one `string`**; use **string interpolation** `{...}` for values and calculations β never `+`, never comma-separated args.
- `GetPlayerUI[]` is fallible β bind it with `if (UI := Player.GetPlayerUI[]):` before calling `AddWidget`.
- Build a `canvas` containing a `text_block`, add it with `AddWidget`, and call `.SetText(...)` (with a `<localizes>` message) to update debug text live on screen.
- Print at the start of `OnBegin` and inside handlers to verify which code ran and in what order.
Keep going β free
You've read the intro. The rest of this lesson is free for members. Sign in to continue and track your progress.
Sign in free to continue this lessonSources
/guides/sug-using-print-for-verse-debuggingBiloxi Studios original lesson
Add this lesson to your free study plan.
π§ The Keeperβs log
Quest complete? Chart your next heading from the π¦ West Coves expedition.
β΅ Take me there