Verse Damage API: Programmatic Health Control with UI
What you'll learn
You will learn how to:
- Subscribe to a
button_deviceinteraction event and identify the acting agent. - Convert an
agentinto afort_characterand use it as adamageableto callDamage(Amount:float). - Build a
canvas+text_blockwidget and attach it to the player's HUD withGetPlayerUI[]/AddWidget.
How it works
Fortnite characters implement a stack of interfaces including damageable, which exposes Damage(Amount:float):void. An agent is not itself damageable, so we first resolve the agent's fort_character with Agent.GetFortCharacter[] (a <decides> call — it lives inside an if). Once we have the character we can treat it as damageable and call Damage.
To give feedback we use the Verse UI system. GetPlayerUI[Player] fails-or-returns the player_ui for a player, and AddWidget(Widget) places a widget on their screen. We create the widget once in OnBegin, keep a reference to its text_block, and update its text each time damage is dealt with SetText.
Because Damage and HUD updates are one-way side effects, we validate everything (the agent maps to a player, the character exists, the UI resolves) before mutating state.
Let's build it
Place a button_device in your level and assign it to the @editable TriggerButton slot. Paste this into a new Verse file, build, and drop the device into the level.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices/Patchwork }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Damages the player who presses a button and shows feedback on their HUD.
damage_ui_device := class<concrete>(creative_device):
# Button whose interaction triggers the damage.
@editable TriggerButton : button_device = button_device{}
# How much damage each press applies.
@editable DamageAmount : float = 15.0
# Per-player HUD text block, kept so we can update it on repeat hits.
var StatusTexts : [player]text_block = map{}
OnBegin<override>()<suspends>: void =
# Device events subscribe WITHOUT parentheses on the event name.
TriggerButton.InteractedWithEvent.Subscribe(OnButtonPressed)
# Handler receives the agent who interacted with the button.
OnButtonPressed(Agent : agent) : void =
# Resolve the acting agent to a concrete player.
if (Player := player[Agent]):
# Make sure the HUD text exists for this player, then apply damage.
Text := EnsureStatusText(Player)
# An agent is not damageable; its fort_character is. GetFortCharacter is <decides>.
if (Char := Agent.GetFortCharacter[]):
# fort_character implements damageable, so call Damage directly.
Char.Damage(DamageAmount)
Text.SetText(StringToMessage("Took {DamageAmount} damage!"))
Print("Applied {DamageAmount} damage to player")
# Returns the player's text_block, creating and attaching its HUD the first time.
EnsureStatusText(Player : player) : text_block =
if (Existing := StatusTexts[Player]):
return Existing
NewText := text_block{DefaultText := StringToMessage("Ready")}
# Position the text with a canvas slot and add it to the player's UI.
Root := canvas:
Slots := array:
canvas_slot:
Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.1}, Maximum := vector2{X := 0.5, Y := 0.1}}
Widget := NewText
if (UI := GetPlayerUI[Player]):
UI.AddWidget(Root)
set StatusTexts[Player] = NewText
return NewText
# Small helper so interpolation returns a message for SetText/DefaultText.
StringToMessage<localizes>(S : string) : message = "{S}"
Try it yourself
- Change
DamageAmountin the details panel and confirm the HUD text reflects the new value. - Track cumulative damage per player in a second
[player]floatmap and show a running total in the text block. - Guard the damage behind a
damage_volume_deviceand only apply it whenVolume.IsInVolume[Agent]succeeds, so players are safe outside the zone. - Swap the plain
text_blockfor a styled color by setting its text color, or add a secondcanvas_slotfor a title line.
Recap
You subscribed to a button_device.InteractedWithEvent, resolved the acting agent to a player, converted it to a fort_character with the fallible GetFortCharacter[], and called the damageable interface's Damage(Amount:float). For feedback you built a canvas holding a text_block, attached it via GetPlayerUI[] and AddWidget, and updated it with SetText. The key idioms: fallible calls (player[...], GetFortCharacter[], GetPlayerUI[...], map indexing) live inside if, device events subscribe without parentheses, and one-way UI/damage side effects run only after all validations pass.
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 Applying Damage via Verse API 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.