Overview
The Automated Turret Device (automated_turret_device) is a self-firing gun you place in the world. Out of the box it searches for valid targets within range, acquires the best one, and shoots it. What makes it powerful for creators is that Verse can reach in and reconfigure it live: change how much damage each shot deals, change the meters at which it wakes up and locks on, ask who it's currently shooting, and clear that target so it re-scans.
Reach for the turret when you want an automated threat that reacts to players — a boss-arena defense system, a hazard that gets deadlier each wave, a security post that only becomes dangerous once an alarm trips. Because it implements the healthful and healable interfaces, you can also treat it like a destructible objective the players must survive or destroy.
The key Verse handles you'll use:
SetDamage(Damage:float)— damage per shot.SetActivationRange(Range:float)— meters at which the turret activates (clamped 2–100).SetTargetRange(Range:float)— meters at which it targets (clamped 2–100; below 2 disables targeting).GetTarget():?agent— who it's shooting right now (an optional agent).ClearTarget()— drop the current target and re-search.Hide()— remove the device visually from the world.
API Reference
(API surface could not be resolved for this device.)
Walkthrough
Let's build a wave-escalation defense: a turret guards a chokepoint. When a player steps on a trigger plate (the "alarm"), the turret powers up — bigger damage, longer sightlines. A second trigger acts as a "kill the power" switch that shrinks its range and clears whatever it was shooting. We also announce over a HUD message who the turret has locked on to.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporal }
# A turret that escalates when an alarm plate is stepped on,
# and stands down when a reset plate is used.
turret_defense := class(creative_device):
# The placed Automated Turret we control.
@editable
Turret : automated_turret_device = automated_turret_device{}
# Alarm plate: powers the turret up.
@editable
AlarmPlate : trigger_device = trigger_device{}
# Reset plate: stands the turret down.
@editable
ResetPlate : trigger_device = trigger_device{}
# HUD message device to announce the turret's current target.
@editable
Announcer : hud_message_device = hud_message_device{}
# Localized text helper: message params need a localized value,
# not a raw string.
LockedOnMsg<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends>:void =
# Start calm: short range, light damage.
Turret.SetActivationRange(15.0)
Turret.SetTargetRange(12.0)
Turret.SetDamage(10.0)
# Wire up the two plates.
AlarmPlate.TriggeredEvent.Subscribe(OnAlarm)
ResetPlate.TriggeredEvent.Subscribe(OnReset)
# Fired when a player steps on the alarm plate.
OnAlarm(Agent : ?agent) : void =
# Escalate: max sightlines, heavy damage.
Turret.SetActivationRange(80.0)
Turret.SetTargetRange(80.0)
Turret.SetDamage(45.0)
# Ask who the turret is shooting and announce it.
if (Victim := Turret.GetTarget?):
Announcer.Show(Victim)
# Fired when a player uses the reset plate.
OnReset(Agent : ?agent) : void =
# Stand down: short range, light damage, forget the target.
Turret.SetActivationRange(15.0)
Turret.SetTargetRange(12.0)
Turret.SetDamage(10.0)
Turret.ClearTarget()
Line by line:
- The
@editablefields (Turret,AlarmPlate,ResetPlate,Announcer) are how Verse gets a handle on placed devices — you drop the real devices into these slots in the Details panel. A bareautomated_turret_device{}default is just a placeholder until you assign it. LockedOnMsg<localizes>turns a plain string into amessage. Any device method that wants text (like a HUD message) requires this — there is noStringToMessage.- In
OnBegin, we set a calm baseline withSetActivationRange,SetTargetRange, andSetDamage. Ranges are in meters and clamp to 2–100. - We subscribe both plates'
TriggeredEventto handler methods.TriggeredEventhands us a?agent. OnAlarmescalates the turret's stats, then callsGetTarget(). Because that returns a?agent(optional), we unwrap it withif (Victim := Turret.GetTarget?):before using it.OnResetrestores the calm baseline and callsClearTarget()so the turret forgets whoever it was firing at and re-scans from scratch.
Common patterns
Ramp damage every wave with a timer
Make the turret hit harder the longer the round runs — a pressure mechanic.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporal }
escalating_turret := class(creative_device):
@editable
Turret : automated_turret_device = automated_turret_device{}
OnBegin<override>()<suspends>:void =
var CurrentDamage : float = 15.0
Turret.SetDamage(CurrentDamage)
Turret.SetTargetRange(60.0)
# Every 20 seconds, add 10 damage per shot.
loop:
Sleep(20.0)
set CurrentDamage = CurrentDamage + 10.0
Turret.SetDamage(CurrentDamage)
Only fire once alarmed, then hide when disarmed
Disable targeting by shrinking target range below 2m, and remove the turret from view entirely with Hide().
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
hideable_turret := class(creative_device):
@editable
Turret : automated_turret_device = automated_turret_device{}
@editable
DisarmButton : button_device = button_device{}
OnBegin<override>()<suspends>:void =
# Start hot.
Turret.SetTargetRange(50.0)
Turret.SetDamage(30.0)
DisarmButton.InteractedWithEvent.Subscribe(OnDisarm)
OnDisarm(Agent : agent) : void =
# Setting target range below 2m disables targeting.
Turret.SetTargetRange(1.0)
Turret.ClearTarget()
# Then vanish from the world.
Turret.Hide()
React to who the turret is targeting on a poll
Check the current target periodically and grant something (here, just log — swap in your reward device) whenever the turret has locked on.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporal }
target_watcher := class(creative_device):
@editable
Turret : automated_turret_device = automated_turret_device{}
@editable
ThreatAnnouncer : hud_message_device = hud_message_device{}
ThreatMsg<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends>:void =
Turret.SetTargetRange(70.0)
Turret.SetDamage(25.0)
loop:
Sleep(1.0)
# If the turret currently has a target, show a warning to them.
if (Locked := Turret.GetTarget?):
ThreatAnnouncer.Show(Locked)
Gotchas
GetTarget()returns?agent, notagent. You must unwrap it:if (Victim := Turret.GetTarget?):. Using the result directly won't compile, and there may genuinely be no target (the turret is idle), so always guard for the empty case.- Ranges clamp to 2.0–100.0 meters. Passing
SetTargetRange(1.0)doesn't error — it disables targeting. That's a feature (a clean off-switch) but a surprise if you expected it to still shoot. SetActivationRangeandSetTargetRangeare different knobs. Activation is when the turret wakes; target is when it locks. Keep target ≤ activation or the turret may 'see' nothing to shoot even while awake.- All device calls must go through an
@editablefield. You cannot callautomated_turret_device.SetDamage(...)on a bare type. Declare the field, assign the placed device in the editor, then call methods on the field insideOnBeginor a subscribed handler. - Message params need localized values. Anywhere you display text (HUD message
Show), wrap it with a<localizes>helper likeLockedOnMsg(S:string):message. There is noStringToMessage. ClearTarget()may instantly re-acquire. If the same enemy is still the best target in range, the turret picks it right back up. To keep it off a target, combineClearTarget()with shrinking the target range (disable targeting), as in the disarm example.