Overview
String concatenation is the act of gluing pieces of text together into one bigger string. In Verse you rarely reach for a Concat() device — the language itself gives you two clean tools:
- The
+operator joins twostringvalues:"Hello, " + Name. - String interpolation drops any expression straight into a literal with curly braces:
"Score: {Points}".
The game problem this solves is dynamic feedback. A trigger on the dock doesn't know a player's name at build time, and a shell counter changes every second. Concatenation lets you assemble a fresh sentence at runtime — "Welcome, surfer #3!" — and then show it.
The one catch: UEFN's on-screen UI (like HUD Message) and any device parameter typed message do not take a raw string. You concatenate your string, then wrap it in a <localizes> function to turn it into a message. That wrapping step is the bridge between "text you built" and "text a player sees." We'll use it in every example, styled around a sunny 2D cove.
API Reference
(API surface could not be resolved for this device.)
Walkthrough
Picture a wooden dock jutting into a turquoise cove. Each time a player steps on the trigger plate at the end of the dock, we bump a counter and flash a personalized welcome banner on screen: "Aloha, surfer #3 — welcome to Sunset Cove!"
The player's display name comes from GetFortCharacter() / agent APIs, but for a name-free version we'll build the banner purely from a running count plus static shore text — pure concatenation and interpolation. The banner uses player.GetPlayerUI() and ShowMessage, both from using { /UnrealEngine.com/Temporary/UI }.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
cove_greeter := class(creative_device):
# The dock plate players walk onto.
@editable DockPlate : trigger_device = trigger_device{}
# A running tally of how many surfers have arrived.
var VisitorCount : int = 0
# Wrap a finished string into a localized message for the UI.
Banner<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends>:void =
# When someone steps on the dock, greet them.
DockPlate.TriggeredEvent.Subscribe(OnDockStepped)
OnDockStepped(Agent : ?agent) : void =
# A listenable(?agent) event hands us an optional agent — unwrap it.
if (A := Agent?):
# Bump the counter.
set VisitorCount += 1
# Build the sentence with interpolation + the + operator.
Middle : string = "Aloha, surfer #{VisitorCount}"
FullText : string = Middle + " — welcome to Sunset Cove!"
# Wrap the finished string as a message and show it on that player's UI.
if (Player := player[A]):
UI := Player.GetPlayerUI()
UI.ShowMessage(Banner(FullText))
Line by line:
@editable DockPlate : trigger_device— a placed trigger you drag into the field in the Details panel. You can't call methods on a bare device; it must be an editable field.var VisitorCount : int = 0— mutable state we grow every arrival.Banner<localizes>(S : string) : message = "{S}"— the tiny helper that turns anystringinto amessage. There is noStringToMessagebuilt-in; this pattern is the idiomatic replacement.DockPlate.TriggeredEvent.Subscribe(OnDockStepped)— subscribing inOnBeginwires the plate to our handler method.OnDockStepped(Agent : ?agent)— theTriggeredEventis alistenable(?agent), so the handler receives an optional agent.if (A := Agent?)unwraps it.set VisitorCount += 1— increment before building text so the count reads correctly.Middle : string = "Aloha, surfer #{VisitorCount}"— interpolation: theintVisitorCountis converted to text inside the braces automatically (this is a display conversion, not an int→float cast).FullText := Middle + " — welcome..."— the+operator joins two strings into one.player[A]casts the agent to aplayer, thenGetPlayerUI()+ShowMessage(Banner(FullText))renders the assembled, localized sentence.
Drop this device on the island, assign the trigger, and every step on the dock greets the arriving surfer with a fresh, correctly-numbered banner.
Common patterns
Pattern 1 — Interpolate a score into a HUD line
A button on the clifftop awards a shell; the message rebuilds the tally each press using interpolation of two ints.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
shell_counter := class(creative_device):
@editable ShellButton : button_device = button_device{}
var Collected : int = 0
Goal : int = 5
ToMessage<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends>:void =
ShellButton.InteractedWithEvent.Subscribe(OnPressed)
OnPressed(Agent : agent) : void =
set Collected += 1
# Two interpolated ints inside one literal.
Line : string = "Shells: {Collected}/{Goal}"
if (Player := player[Agent]):
Player.GetPlayerUI().ShowMessage(ToMessage(Line))
Pattern 2 — Join several fragments with +
Build a longer sentence from multiple pieces, mixing static shore-flavor text with a dynamic count.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
tide_reporter := class(creative_device):
@editable TidePlate : trigger_device = trigger_device{}
var WaveNumber : int = 0
Say<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends>:void =
TidePlate.TriggeredEvent.Subscribe(OnWave)
OnWave(Agent : ?agent) : void =
if (A := Agent?):
set WaveNumber += 1
# Assemble from parts with the + operator.
Prefix : string = "The tide rolls in... "
Count : string = "wave {WaveNumber}"
Suffix : string = " crashes on the cove."
Report : string = Prefix + Count + Suffix
if (Player := player[A]):
Player.GetPlayerUI().ShowMessage(Say(Report))
Pattern 3 — Concatenate a name onto a greeting
Pull a value into a variable, glue it on, and show a per-player line.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
sunrise_welcome := class(creative_device):
@editable StartPlate : trigger_device = trigger_device{}
IslandName : string = "Sunset Cove"
Greet<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends>:void =
StartPlate.TriggeredEvent.Subscribe(OnArrive)
OnArrive(Agent : ?agent) : void =
if (A := Agent?):
# Concatenate greeting + island name with interpolation folded in.
Message : string = "Good morning! You've reached " + IslandName + "."
if (Player := player[A]):
Player.GetPlayerUI().ShowMessage(Greet(Message))
Gotchas
messageis notstring. Any UI or device parameter typedmessagerejects a raw string. Always route through a<localizes>helper likeBanner<localizes>(S:string):message = "{S}". There is noStringToMessagefunction — don't search for one.- Interpolation is a display conversion, not a numeric cast.
"Score: {MyInt}"works fine, but Verse still won't auto-convertinttofloatin arithmetic. Interpolation only formats a value into text. - Unwrap the optional agent.
TriggeredEventislistenable(?agent), so the handler gets(Agent : ?agent). Useif (A := Agent?):before you touch it.button_device.InteractedWithEventhands you a plainagent, so no unwrap is needed there — mixing them up causes type errors. player[Agent]can fail. Casting an agent to aplayeris a<decides>operation; wrap it inif (Player := player[A]):so the code only runs for real players, not non-player agents.- Bare devices don't compile. You cannot call
TidePlate.TriggeredEvent...unlessTidePlateis an@editablefield on yourcreative_deviceand assigned in the editor. A local placeholder will never fire. +only joins two strings at a time, but it chains:A + B + Cis fine. If a piece is anint, interpolate it into a string first ("{N}") rather than trying to+a number onto text.