Mastering Local HUD Widgets with @Client in Verse
What you'll learn
You'll discover how to use @Client functions to run UI logic directly on the player's device. You'll learn to safely fetch each player's UI container, construct a canvas widget, position it, and drive dynamic updates like text changes and visibility toggles—all without triggering network replication errors.
How it works
When a creative_device begins, its OnBegin runs on the server. To affect the client's screen, you must either mark your device as local or call a function annotated with @Client. The @Client pattern is ideal here: the server iterates over players and dispatches a setup task that executes on each machine.
Inside that client task, you use GetPlayerUI[] to grab the player_ui handle. Because GetPlayerUI is a fallible <decides> function, you must bind it in a failure context like if (UI := GetPlayerUI(Player)):. Once you have the UI, you can construct a widget (like a canvas), configure its anchors and offsets, and call AddWidget to render it. From there, you can enter a suspension loop to update the widget using SetText and SetVisibility.
Let's build it
This device demonstrates the full pipeline. It defines integer math helpers to avoid the forbidden % operator, marks the update function with @Client and <transacts>, and safely wires up the player UI.
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Progression }
using { /Verse.org/SceneGraph/CollisionProfiles }
using { /Verse.org/Simulation }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Conversations }
using { /Fortnite.com/Devices }
my_hud_device := class<concrete>(creative_device):
# Total integer helpers prevent the "no modulo" compiler error.
VC_IntMod(A:int, B:int):int =
if (R := Mod[A, B]): R else: 0
VC_IntDiv(A:int, B:int):int =
if (B > 0, R := Mod[A, B], Q := Floor[(A - R) * 1.0 / (B * 1.0)]): Q else: 0
# @Client ensures this runs on the player's machine.
# <transacts> is required because we mutate state via SetText/SetVisibility.
SetupLocalHUD<client><transacts>(Player:player)<suspends>: void =
# GetPlayerUI is fallible; bind it safely.
if (UI := GetPlayerUI(Player)):
# Construct a canvas widget for positioning.
HUDCanvas := canvas{
Anchors: anchors{
Minimum: vector2{X:0.5, Y:0.5},
Maximum: vector2{X:0.5, Y:0.5}
},
Offsets: vector2{X:0.0, Y:0.0},
Alignment: vector2{X:0.5, Y:0.5},
ZOrder: 1,
SizeToContent: false
}
# Add the widget to the player's UI layer.
UI.AddWidget(HUDCanvas)
# Dynamic update loop.
Counter := 0
while (true):
set Counter += 1
# Interpolate text using Message interpolation.
HUDCanvas.SetText(Message{"Reticle Count: {Counter}"})
# Use VC_IntMod instead of %. Compare with =.
if (VC_IntMod(Counter, 6) = 0):
# Toggle visibility safely.
if (Vis := HUDCanvas.GetVisibility[]):
if (Vis = widget_visibility::Visible):
HUDCanvas.SetVisibility(widget_visibility::Hidden)
else:
HUDCanvas.SetVisibility(widget_visibility::Visible)
end
end
# Yield to other coroutines.
Sleep(0.1)
end
OnBegin<override>()<transacts><suspends>: void =
# Iterate all players in the playspace.
for (Player : GetPlayspace().GetPlayers()):
# Dispatch the client-side setup.
SetupLocalHUD(Player)
end
Try it yourself
- Place
my_hud_devicein your island and compile. - Test in preview mode; notice the reticle updates instantly for each player.
- Experiment: Change the
Offsetsto move the widget to a corner, or adjustZOrderto draw behind other UI. - Challenge: Add a second widget that tracks the player's health by reading a device value and updating both widgets simultaneously.
Recap
- Use
@Clientto execute UI logic locally and avoid replication lag. - Always bind
<decides>results likeGetPlayerUI[]in anifstatement. - Call
AddWidgetto render your constructed widget into theplayer_ui. - Avoid
%and==; useVC_IntModand=respectively. - Mark functions that touch UI state as
<transacts>and ensure callers match.
Check your understanding
Test yourself with an interactive quiz and track your progress + earn XP — free for members.
Turn this into a guided course
Add Local HUD Widget Creation with @Client Functions to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.
Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.