Overview
String interpolation lets you inject a value directly into a string literal using curly braces { }. Instead of concatenating pieces with + (which Verse is strict about), you write the whole sentence once and let the compiler fill in the blanks.
Name := "Alice"
Announcement : string = "...And the winner is: {Name}!"
The game problem it solves: almost every player-facing message is partly dynamic. "Welcome, {PlayerName}!", "You have {Coins} coins", "Wave {Round} incoming". Building those by hand with + is painful because Verse does not auto-convert numbers to text — you'd need ToString() everywhere and lots of + glue. Interpolation reads like a sentence and handles the conversion inside the braces.
Key rules to remember:
- Any expression inside
{ }must resolve to something with a validToString()in scope. Astringworks directly; afloatneedsToString(MyFloat). - Verse does NOT auto-convert
int↔float, and it won't let you+a number onto a string. Interpolation is the clean path. - The result is a plain
string. To show it on a device that wants amessage(like a HUD), wrap it with a<localizes>helper.
Reach for interpolation whenever the text depends on live game state — a player's name, a score, a countdown, a splash count on the cove.
API Reference
(API surface could not be resolved for this device.)
Walkthrough
Here's the sunny scene: a trigger_device sits at the edge of the dock. Every time a player runs across it and dives into the cove, we bump their personal splash count and flash a HUD banner built entirely with interpolation. We also read a float (their splash "score") and turn it into text with ToString.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
# A cel-shaded cove: step off the dock, splash into the surf,
# and a banner announces your name and splash count.
cove_dock_device := class(creative_device):
# The plate at the edge of the dock.
@editable
DockPlate : trigger_device = trigger_device{}
# A localized-message helper: turns a raw string into a `message`.
MakeMessage<localizes>(S : string) : message = "{S}"
# Runs once when the game starts.
OnBegin<override>()<suspends> : void =
# Subscribe our handler to the plate's fire event.
DockPlate.TriggeredEvent.Subscribe(OnDockStep)
# Called each time a player steps on the dock plate.
OnDockStep(Agent : ?agent) : void =
if (A := Agent?):
# Pretend this player has splashed some number of times.
SplashCount : int = 3
# A float score we want to show as text.
SplashScore : float = 42.5
# Build the banner ENTIRELY with interpolation.
# ToString turns the float into a string inside the braces.
Banner : string =
"Splash #{SplashCount}! Cove score: {ToString(SplashScore)}"
# Show it on the player's HUD as a localized message.
if (FortChar := A.GetFortCharacter[]):
Player := FortChar.GetAgent[]
ShowBanner(A, Banner)
# Puts the finished string on screen as a HUD message.
ShowBanner(A : agent, Text : string) : void =
if (PlayerUI := GetPlayerUI[A]):
PlayerUI.ShowMessage(MakeMessage(Text))
Line by line:
@editable DockPlate : trigger_device— the placed plate. It MUST be an editable field on acreative_deviceclass so Verse can call its methods; a bare device reference would fail with 'Unknown identifier'.MakeMessage<localizes>(S:string):message = "{S}"— a tiny helper. Device UI wants amessage, not a rawstring, and there is noStringToMessage. This<localizes>function converts on demand. Note it also uses interpolation ({S}) internally.OnBeginsubscribesOnDockSteptoDockPlate.TriggeredEvent. Event handlers are methods at class scope; we wire them up here.OnDockStep(Agent : ?agent)— the triggered event hands us an optional agent. We unwrap it withif (A := Agent?):before using it.Banner : string = "Splash #{SplashCount}! Cove score: {ToString(SplashScore)}"— the star of the show.{SplashCount}interpolates anintdirectly;{ToString(SplashScore)}converts thefloatto text first, because a barefloathas no default text form we can+in.ShowBannerwraps the finished string withMakeMessageand callsPlayerUI.ShowMessage, so the banner actually appears on the diver's screen.
Common patterns
1. Interpolating a float score with ToString. When a value is a float, always call ToString inside the braces — Verse won't convert it silently.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
score_board_device := class(creative_device):
@editable
ReadoutTrigger : trigger_device = trigger_device{}
AsMessage<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
ReadoutTrigger.TriggeredEvent.Subscribe(OnRead)
OnRead(Agent : ?agent) : void =
if (A := Agent?):
Distance : float = 128.75
Line : string = "You dove {ToString(Distance)} meters into the cove!"
if (UI := GetPlayerUI[A]):
UI.ShowMessage(AsMessage(Line))
2. Composing several values in one sentence. You can drop many { } slots into a single literal — cleaner than chaining +.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
welcome_dock_device := class(creative_device):
@editable
ArrivalPlate : trigger_device = trigger_device{}
ToMessage<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
ArrivalPlate.TriggeredEvent.Subscribe(OnArrive)
OnArrive(Agent : ?agent) : void =
if (A := Agent?):
Wave : int = 2
Enemies : int = 6
Reward : float = 150.0
Brief : string =
"Wave {Wave}: {Enemies} husks incoming. Survive for {ToString(Reward)} gold!"
if (UI := GetPlayerUI[A]):
UI.ShowMessage(ToMessage(Brief))
3. Interpolating right inside the <localizes> message helper. Because the helper body is a string literal, you can build the whole line in one step by passing the pieces in.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
cliff_banner_device := class(creative_device):
@editable
JumpPad : trigger_device = trigger_device{}
# The interpolation happens inside the localized message body.
JumpMessage<localizes>(Name : string, Count : int) : message =
"{Name} launched off the clifftop — jump #{Count}!"
OnBegin<override>()<suspends> : void =
JumpPad.TriggeredEvent.Subscribe(OnJump)
OnJump(Agent : ?agent) : void =
if (A := Agent?):
if (UI := GetPlayerUI[A]):
UI.ShowMessage(JumpMessage("Diver", 5))
Gotchas
- Numbers don't
+onto strings."Score: " + Scoreis a compile error. Use"Score: {Score}"instead. For afloat, you additionally need"...{ToString(MyFloat)}"because a raw float has no direct text form to splice. - No int↔float auto-convert.
{SomeInt}is fine on its own, but you can't mix anintwhere afloatis expected. If a value started as a float, keep it a float and useToString. messageis notstring. Device UI methods likeShowMessagetake a localizedmessage. There is NOStringToMessage. Declare aMyText<localizes>(S:string):message = "{S}"helper and pass your interpolated string through it.- Braces are special.
{ }inside a string always means interpolation. If you genuinely need a literal brace character in text, keep it out of interpolation contexts — don't accidentally leave an empty{}. - Unwrap the agent first. The
TriggeredEventhandler receives?agent. Alwaysif (A := Agent?):before building per-player text, or you'll try to read state off a value that might not exist. - Expressions inside braces must be valid in scope.
{PlayerName}only works ifPlayerNameis a defined, in-scope value with aToString. A misspelled name reports 'Unknown identifier' — from inside the string.