Overview
The Healing Cactus device is a placeable prop that grows fruit over time and can be burst — either by a player interacting with it or by your Verse code — to heal players standing nearby. It solves the problem of giving players a skill-expression healing option: they must choose when to burst the cactus, and your Verse code can control whether it is even available.
Reach for healing_cactus_device when you want:
- Zone-based healing — a cactus that only grows during a safe phase and is disabled during combat.
- Scripted healing moments — burst the cactus automatically when a boss dies to reward the whole team.
- Healing economy — track bursts, limit total heals, or tie healing to puzzle completion.
Key device settings you configure in the UEFN editor (not in Verse):
- Heal Targets —
Triggering Player,Nearby Players, orEveryone. When you call the no-argumentBurst()overload there is no triggering agent, so healing only fires if this is set toEveryone. - Maximum Regrowths / Infinite Regrowths — controls how many times
Grow()can be called before the cactus stops. - Regrowth Delay — seconds between a burst and the next allowed grow.
API Reference
healing_cactus_device
Use to create a cactus with healing fruits that can be burst to heal nearby players.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
healing_cactus_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
GrowEvent |
GrowEvent<public>:listenable(tuple()) |
Triggers when the plant grows. |
BurstEvent |
BurstEvent<public>:listenable(?agent) |
Triggers when the plant bursts, passing in the triggering agent. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables the device to allow interaction and let it grow. |
Disable |
Disable<public>():void |
Disables the device to prevent interaction and growth. |
Grow |
Grow<public>():void |
Grows the plant if the device is enabled. If Infinite Regrowths is false, this is limited by Maximum Regrowths. If someone is too close, the plant won't grow until they move away. |
Burst |
Burst<public>(Agent:agent):void |
Burst the plant if the device is enabled, passing in the triggering agent. If there is no triggering agent, players will only be healed if Heal Targets is set to Everyone. |
Burst |
Burst<public>():void |
Burst the plant if the device is enabled, passing in the triggering agent. If there is no triggering agent, players will only be healed if Heal Targets is set to Everyone. |
Walkthrough
Scenario: The Healing Shrine
A capture-point island has a central shrine. When a team captures the point (simulated here by a trigger_device the player steps on), the cactus grows. When a second trigger is activated — say, a button the player presses — the cactus bursts and heals everyone nearby. A HUD message announces each event. The cactus is disabled at round start and only enabled once the round begins.
healing_shrine_manager := class(creative_device):
# Drop a healing_cactus_device onto the island and wire it here
@editable
HealingCactus : healing_cactus_device = healing_cactus_device{}
# A trigger_device the player steps on to "capture" the point
@editable
CaptureTrigger : trigger_device = trigger_device{}
# A button_device the player presses to burst the cactus
@editable
BurstButton : button_device = button_device{}
# A hud_message_device to display status
@editable
StatusHUD : hud_message_device = hud_message_device{}
# Track how many times the cactus has been burst this round
var BurstCount : int = 0
OnBegin<override>()<suspends> : void =
# Start disabled — cactus won't grow or accept interaction yet
HealingCactus.Disable()
# Subscribe to device events
CaptureTrigger.TriggeredEvent.Subscribe(OnCapture)
BurstButton.InteractedWithEvent.Subscribe(OnBurstPressed)
# Subscribe to the cactus's own events so we can react
HealingCactus.GrowEvent.Subscribe(OnCactusGrew)
HealingCactus.BurstEvent.Subscribe(OnCactusBurst)
# Enable the cactus after a 3-second round-start delay
Sleep(3.0)
HealingCactus.Enable()
# Called when a player steps on the capture trigger
OnCapture(Agent : ?agent) : void =
# Grow the cactus — only works if the device is enabled
HealingCactus.Grow()
# Called when the burst button is pressed
OnBurstPressed(Agent : agent) : void =
# Burst with the triggering agent so "Heal Targets: Triggering Player" works
HealingCactus.Burst(Agent)
# Fires when the cactus successfully grows
OnCactusGrew(Unused : tuple()) : void =
# Show a message to all players that the shrine is ready
StatusHUD.Show()
# Fires when the cactus bursts; Agent is optional (?agent)
OnCactusBurst(Agent : ?agent) : void =
set BurstCount += 1
# If a specific player triggered the burst, we know who healed
if (A := Agent?):
# Could award score, log stats, etc.
HealingCactus.Grow() # Immediately try to regrow for the next use
Line-by-line explanation:
| Lines | What's happening |
|---|---|
@editable fields |
Wires placed devices from the UEFN editor into Verse — mandatory for any placed device. |
HealingCactus.Disable() |
Prevents the cactus from growing or being interacted with until the round starts. |
CaptureTrigger.TriggeredEvent.Subscribe(OnCapture) |
Hooks the trigger's event to our handler. |
HealingCactus.GrowEvent.Subscribe(OnCactusGrew) |
Listens for the cactus's own grow confirmation — fires after a successful Grow(). |
HealingCactus.BurstEvent.Subscribe(OnCactusBurst) |
Listens for bursts, whether player-initiated or code-initiated. |
Sleep(3.0) |
Suspends OnBegin for 3 seconds before enabling — valid because OnBegin has <suspends>. |
HealingCactus.Grow() |
Programmatically grows the cactus fruit. Respects Maximum Regrowths and proximity checks. |
HealingCactus.Burst(Agent) |
Bursts with a triggering agent — required for Heal Targets: Triggering Player to heal anyone. |
if (A := Agent?): |
Safely unwraps the ?agent optional from BurstEvent before using it. |
Common patterns
Pattern 1 — Timed Auto-Burst (no agent, heals Everyone)
A survival mode where the cactus auto-bursts every 30 seconds to give passive healing. Because there is no triggering agent, set Heal Targets to Everyone in the editor.
auto_burst_cactus := class(creative_device):
@editable
HealingCactus : healing_cactus_device = healing_cactus_device{}
OnBegin<override>()<suspends> : void =
HealingCactus.Enable()
# Grow immediately at round start
HealingCactus.Grow()
# Then auto-burst on a 30-second cycle forever
loop:
Sleep(30.0)
# No-argument Burst — heals everyone nearby
# Requires "Heal Targets: Everyone" in device settings
HealingCactus.Burst()
# Wait a moment then regrow for the next cycle
Sleep(2.0)
HealingCactus.Grow()
Pattern 2 — Disable the Cactus During Combat Phase
A zone-wars map disables healing during the fight phase and re-enables it only in the safe phase. Subscribes to GrowEvent to log readiness.
phase_cactus_controller := class(creative_device):
@editable
HealingCactus : healing_cactus_device = healing_cactus_device{}
# Two trigger_devices: one fires when combat starts, one when safe phase starts
@editable
CombatStartTrigger : trigger_device = trigger_device{}
@editable
SafePhaseStartTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
HealingCactus.Enable()
HealingCactus.GrowEvent.Subscribe(OnGrew)
CombatStartTrigger.TriggeredEvent.Subscribe(OnCombatStart)
SafePhaseStartTrigger.TriggeredEvent.Subscribe(OnSafePhaseStart)
OnCombatStart(Agent : ?agent) : void =
# Lock out healing during combat
HealingCactus.Disable()
OnSafePhaseStart(Agent : ?agent) : void =
# Re-enable and immediately grow a fresh fruit
HealingCactus.Enable()
HealingCactus.Grow()
OnGrew(Unused : tuple()) : void =
# GrowEvent confirms the cactus is ready to burst
# Could ping a UI indicator here
var Ready : logic = true
Pattern 3 — Track Who Burst the Cactus with BurstEvent
Award bonus score to the player who triggers a burst. Demonstrates full BurstEvent handler with safe ?agent unwrap.
burst_tracker_device := class(creative_device):
@editable
HealingCactus : healing_cactus_device = healing_cactus_device{}
@editable
ScoreManager : score_manager_device = score_manager_device{}
var TotalBursts : int = 0
OnBegin<override>()<suspends> : void =
HealingCactus.Enable()
HealingCactus.Grow()
HealingCactus.BurstEvent.Subscribe(OnBurst)
OnBurst(Agent : ?agent) : void =
set TotalBursts += 1
# BurstEvent passes ?agent — must unwrap before use
if (A := Agent?):
# Award 50 score to the player who burst the cactus
ScoreManager.Activate(A)
# Whether or not a player triggered it, regrow for next use
HealingCactus.Grow()
Gotchas
1. Burst() vs Burst(Agent) — Heal Targets setting matters
The device has two overloads:
Burst(Agent : agent)— passes a triggering agent. Works with allHeal Targetssettings.Burst()— no agent. Players are only healed ifHeal Targetsis set toEveryonein the editor. If you call the no-argument version withHeal Targets: Triggering Player, nobody gets healed.
2. Grow() silently fails when disabled or a player is too close
Grow() does nothing if:
- The device is currently disabled (
Disable()was called). - A player is standing too close to the cactus (proximity check).
Infinite RegrowthsisfalseandMaximum Regrowthshas been reached.
There is no return value or failure event — the cactus simply won't grow. Use GrowEvent to confirm growth actually happened.
3. BurstEvent handler receives ?agent, not agent
BurstEvent is typed listenable(?agent). Your handler signature must be (Agent : ?agent). Trying to write (Agent : agent) will not compile. Always unwrap with if (A := Agent?): before calling any agent-typed API.
4. GrowEvent handler receives tuple(), not nothing
GrowEvent is typed listenable(tuple()). Your handler must accept a tuple() parameter: OnGrew(Unused : tuple()) : void. You cannot subscribe a zero-parameter function to it.
5. Enable/Disable affects both interaction AND programmatic calls
Calling Disable() prevents players from interacting and makes Grow() and Burst() no-ops from Verse. Always call Enable() before attempting to grow or burst from code.
6. @editable is mandatory for placed devices
You cannot write var C := healing_cactus_device{} and expect it to control a placed device. Every device you place in the UEFN editor must be declared as an @editable field in your creative_device class, then wired in the editor's Details panel.