Talk to Players: HUD Message Device
In this lesson you'll learn to
- Student can show, update, and hide on-screen messages from Verse via hud_message_device (the UI arc's first rung).
Student can show, update, and hide on-screen messages from Verse via hud_message_device (the UI arc's first rung).
π§© Your capstone piece: All hunt feedback text: welcome banner, shell-count updates, winner announcement
Walkthrough
Overview
The hud_message_device solves a fundamental game-design problem: players need feedback. When a guard spots them, when the final zone opens, when they earn a bonus β they need to know. The HUD message device lets you surface that information as an on-screen text overlay without building custom UI from scratch.
Key capabilities:
- Show to everyone (
Show()) or show to one player (Show(Agent)) β great for personal score updates vs. global announcements. - Inline custom text at runtime via
SetText(Text:message)or the overloadedShow(Agent, Message, ?DisplayTime)/Show(Message, ?DisplayTime)β no need to pre-bake every string in the editor. - Control display duration with
SetDisplayTime/GetDisplayTime; pass0.0to pin the message permanently. - React to lifecycle events β
ShowMessageEvent,HideMessageEvent, andClearAllMessagesEventlet your Verse code respond when messages appear or disappear. - Clean up with
Hide(),Hide(Agent), orClearAllMessages()when the moment has passed.
Reach for this device whenever you need lightweight, event-driven text feedback: countdown timers, wave announcements, per-player kill streaks, objective updates, or tutorial hints.
API Reference
hud_message_device
Used to show custom HUD messages to one or more
agents.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
hud_message_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
ShowMessageEvent |
ShowMessageEvent<public>:listenable(agent) |
Called when a Message has been Shown on-screen. Returns an Agent if it was Shown on a specified Agent's screen. |
HideMessageEvent |
HideMessageEvent<public>:listenable(agent) |
Called when a Message has been Hidden on-screen. Returns an Agent if it was Hidden from a specified Agent's screen. |
ClearAllMessagesEvent |
ClearAllMessagesEvent<public>:listenable(agent) |
Called when all queued Messages from all players that are affected by this HUD Message Device have been cleared. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Show |
Show<public>(Agent:agent):void |
Shows the currently set HUD Message on Agents screen. Will replace any previously active message. Use this when the device is setup to target specific agents. |
Show |
Show<public>():void |
Shows the currently set Message HUD message on screen. Will replace any previously active message. |
Hide |
Hide<public>():void |
Hides the HUD message. |
Hide |
Hide<public>(Agent:agent):void |
Hides the currently set HUD Message on Agents screen. Use this when the device is setup to target specific agents. |
Show |
Show<public>(Agent:agent, Message:message, ?DisplayTime:float |
Displays a Custom message to a specific Agent that you define.Setting DisplayTime to 0.0 will display the HUD message persistently.If not defined, or less than 0.0 the message will show for the time set on the device. |
Show |
Show<public>(Message:message, ?DisplayTime:float |
Displays a Custom message that you define for all PlayersSetting DisplayTime to 0.0 will display the HUD message persistently.If not defined, or less than 0.0 the message will show for the time set on the device. |
SetDisplayTime |
SetDisplayTime<public>(Time:float):void |
Sets the time (in seconds) the HUD message will be displayed. 0.0 will display the HUD message persistently. |
GetDisplayTime |
GetDisplayTime<public>()<transacts>:float |
Returns the time (in seconds) for which the HUD message will be displayed. 0.0 means the message is displayed persistently. |
SetText |
SetText<public>(Text:message):void |
Sets the Message to be displayed when the HUD message is activated. Text is clamped to 150 characters. |
ClearAllMessages |
ClearAllMessages<public>():void |
Clears all queued Messages from all players that are affected by this HUD Message Device. |
Walkthrough
Scenario: Vault Alert System
A player steps on a pressure plate. The vault door opens, and:
- A global "Vault Opened!" message flashes for 3 seconds.
- The player who triggered it gets a personal persistent message: "You found the vault β grab the loot!"
- When that personal message is hidden, we log it via
HideMessageEvent.
This walkthrough uses SetText, SetDisplayTime, Show(), Show(Agent, Message, ?DisplayTime:=...), Hide(Agent), HideMessageEvent, and ClearAllMessages.
vault_alert_device := class(creative_device):
# Wire these up in the UEFN editor
@editable
Plate : trigger_device = trigger_device{}
# One device for the global broadcast, one for the personal tip
@editable
GlobalHUD : hud_message_device = hud_message_device{}
@editable
PersonalHUD : hud_message_device = hud_message_device{}
# Localizer helper β message params must be of type `message`
VaultOpened<localizes>(S : string) : message = "{S}"
PersonalTip<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
# Subscribe to the pressure plate
Plate.TriggeredEvent.Subscribe(OnPlateTriggered)
# React when the personal message is hidden
PersonalHUD.HideMessageEvent.Subscribe(OnPersonalMessageHidden)
# Pre-configure the global HUD: 3-second flash
GlobalHUD.SetDisplayTime(3.0)
GlobalHUD.SetText(VaultOpened("β Vault Opened!"))
# Personal HUD will be shown persistently (DisplayTime = 0.0)
# We'll pass that inline when we call Show
# Handler called when a player steps on the plate
# trigger_device fires listenable(?agent)
OnPlateTriggered(Agent : ?agent) : void =
# 1. Global announcement to every player
GlobalHUD.Show()
# 2. Personal persistent message for the triggering player only
if (A := Agent?):
PersonalHUD.Show(A, PersonalTip("You found the vault β grab the loot!"), ?DisplayTime := 0.0)
# Called when the personal message is hidden for any agent
OnPersonalMessageHidden(A : agent) : void =
# Clean up any remaining queued messages across all players
PersonalHUD.ClearAllMessages()
Line-by-line breakdown:
| Line(s) | What it does |
|---|---|
@editable Plate |
Wires the pressure plate placed in the level. |
@editable GlobalHUD / PersonalHUD |
Two separate hud_message_device instances β one for everyone, one per-player. |
VaultOpened<localizes> |
Wraps a raw string into a message β required for any method that takes message. |
GlobalHUD.SetDisplayTime(3.0) |
Tells the global device to auto-hide after 3 seconds. |
GlobalHUD.SetText(...) |
Pre-loads the text so Show() has something to display. |
GlobalHUD.Show() |
Broadcasts to all players simultaneously. |
PersonalHUD.Show(A, ..., ?DisplayTime := 0.0) |
Shows a custom inline message to one agent, pinned permanently (0.0). |
PersonalHUD.HideMessageEvent.Subscribe(...) |
Fires whenever the personal message is hidden on any screen. |
PersonalHUD.ClearAllMessages() |
Wipes the queue for all affected players β good housekeeping. |
Common patterns
Pattern 1 β Dynamic countdown using SetText + SetDisplayTime
Update the HUD message every second to show a live countdown, then clear it when time is up.
countdown_hud_device := class(creative_device):
@editable
CountdownHUD : hud_message_device = hud_message_device{}
CountdownText<localizes>(N : int) : message = "Round starts in {N}..."
GoText<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
# Pin the message β we'll clear it manually
CountdownHUD.SetDisplayTime(0.0)
var SecondsLeft : int = 5
loop:
if (SecondsLeft <= 0):
break
CountdownHUD.SetText(CountdownText(SecondsLeft))
CountdownHUD.Show()
Sleep(1.0)
set SecondsLeft = SecondsLeft - 1
# Show "GO!" for 2 seconds then clear
CountdownHUD.SetDisplayTime(2.0)
CountdownHUD.SetText(GoText("GO!"))
CountdownHUD.Show()
Sleep(2.0)
CountdownHUD.ClearAllMessages()
Covers: SetText, SetDisplayTime, Show(), ClearAllMessages
Pattern 2 β Per-player elimination streak with Show(Agent, Message)
When a player gets an elimination, show them a personal streak message without interrupting other players' HUDs.
streak_hud_device := class(creative_device):
@editable
EliminationManager : elimination_manager_device = elimination_manager_device{}
@editable
StreakHUD : hud_message_device = hud_message_device{}
StreakMsg<localizes>(N : int) : message = "Elimination streak: {N}!"
# Track per-player streak counts
var Streaks : [agent]int = map{}
OnBegin<override>()<suspends> : void =
EliminationManager.EliminationEvent.Subscribe(OnElimination)
OnElimination(Result : elimination_result) : void =
if (Eliminator := Result.EliminatingAgent?):
CurrentStreak : int =
if (S := Streaks[Eliminator]):
S
else:
0
NewStreak := CurrentStreak + 1
if (set Streaks[Eliminator] = NewStreak) {}
# Show personal message for 2.5 seconds
StreakHUD.Show(Eliminator, StreakMsg(NewStreak), ?DisplayTime := 2.5)
Covers: Show(Agent, Message, ?DisplayTime)
Pattern 3 β React to ShowMessageEvent and hide for a specific agent
Listen for when any message appears, then hide it for a specific VIP agent who shouldn't see spoilers.
vip_filter_hud_device := class(creative_device):
@editable
AnnouncementHUD : hud_message_device = hud_message_device{}
# The VIP player agent reference (set via game logic elsewhere)
var VIPAgent : ?agent = false
OnBegin<override>()<suspends> : void =
AnnouncementHUD.ShowMessageEvent.Subscribe(OnMessageShown)
# Simulate acquiring a VIP after 2 seconds
Sleep(2.0)
Playspace := GetPlayspace()
Players := Playspace.GetPlayers()
if (First := Players[0]):
set VIPAgent = option{First.GetAgent[]}
# Broadcast a message to everyone
AnnouncementHUD.SetDisplayTime(5.0)
AnnouncementHUD.SetText(SpoilerText("Boss location revealed!"))
AnnouncementHUD.Show()
SpoilerText<localizes>(S : string) : message = "{S}"
# Fires for each agent the message is shown to
OnMessageShown(A : agent) : void =
# If this is our VIP, immediately hide it for them
if (VIP := VIPAgent?):
if (A = VIP):
AnnouncementHUD.Hide(VIP)
Covers: ShowMessageEvent, SetText, SetDisplayTime, Show(), Hide(Agent)
Gotchas
1. message is NOT a string β use <localizes>
Every method that takes text (SetText, Show(Agent, Message, ...), Show(Message, ...)) expects a message type, not a plain string. There is no StringToMessage function. You must declare a localizer:
MyLabel<localizes>(S : string) : message = "{S}"
Then call SetText(MyLabel("Hello!")). Passing a raw string literal directly will fail to compile.
2. DisplayTime := 0.0 means forever, not "instant hide"
Passing 0.0 to SetDisplayTime or the ?DisplayTime parameter pins the message on screen indefinitely. You must call Hide(), Hide(Agent), or ClearAllMessages() to remove it. This is intentional and useful for persistent objective text, but easy to forget.
3. Show() replaces the active message β queue carefully
Calling Show() while a message is already visible will replace it immediately. If you need sequential messages, Sleep between calls or use GetDisplayTime() to know when the current one expires.
4. Unwrap ?agent before calling Show(Agent)
Events like trigger_device.TriggeredEvent fire listenable(?agent) β an optional agent. You must unwrap it before passing to Show(Agent:agent):
OnTriggered(MaybeAgent : ?agent) : void =
if (A := MaybeAgent?):
MyHUD.Show(A) # safe β A is agent, not ?agent
Passing ?agent directly to a method expecting agent is a compile error.
5. ClearAllMessagesEvent fires with an agent parameter
Despite clearing all messages, ClearAllMessagesEvent is typed listenable(agent). Your handler must accept an agent argument. It represents one of the affected agents β don't assume it's a specific player.
6. Text is clamped to 150 characters
SetText silently clamps its input. If your dynamic string might exceed 150 characters, truncate it in Verse before passing it in β there's no error or event to warn you.
7. Use two devices for global + per-player simultaneously
You cannot send a global Show() and a targeted Show(Agent) from the same device instance in the same tick and have both work independently. Use two separate hud_message_device instances β one configured for all players, one for targeted messages.
Take on the Challenge
Pass the 5-question challenge to master this lesson and chart the quest in your journal.
Quick Quiz
5 quick questions. Pick an answer to see if you've got it.
-
1.
-
2.
-
3.
-
4.
-
5.
Recap
One step closer to Shell-Hunt β All hunt feedback text: welcome banner, shell-count updates, winner announcement
Sources
/guides/hud-message-deviceΒ© Biloxi Studios Inc. β original Verse Island content.
Turn this into a guided course
Add Talk to Players: HUD Message Device 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.
π§ The Keeper's log
Quest complete? Chart your next heading from the 𦩠South Shores (Free) expedition.