Reference Devices compiles

automated_turret_device: Smart Sentries That Hunt, Track, and Fire

The Automated Turret is Fortnite's plug-and-play sentry gun — but driving it from Verse turns it into a fully scriptable enemy. You can enable it on an alarm, force it to lock onto a specific player, scale its damage as a fight escalates, and react the instant it finds, loses, or gets destroyed. This article shows the real API doing real game things.

Updated Examples verified on the live UEFN compiler
Watch the Knotautomated_turret_device in ~90 seconds.

Overview

The automated_turret_device is a placed device that searches for nearby targets, rotates to track them, and fires automatically. Out of the box it solves the "I need a hostile defender" problem — guarding a vault, defending a capture point, or acting as a stationary boss.

Where Verse earns its keep is control and reaction. From code you can:

  • Turn the turret on/off in response to game events (an alarm, a button, a round start) with Enable() / Disable().
  • Tune its behavior live with SetDamage(), SetActivationRange(), and SetTargetRange() — great for difficulty ramps.
  • Override its AI by forcing a target with SetTarget(), reading the current one with GetTarget(), or releasing it with ClearTarget().
  • React to the fight with TargetFoundEvent, TargetLostEvent, ActivatedEvent, DamagedEvent, and DestroyedEvent.

Because the device implements healthful/healable, you can also read/set its health and heal it — handy for repairable defenses.

Reach for it whenever you want an enemy that aims and shoots without writing your own pathfinding or aiming code.

API Reference

automated_turret_device

Used to create a customizable turret that can search for nearby targets.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

automated_turret_device<public> := class<concrete><final>(creative_device_base, healthful, healable):

Events (subscribe a handler to react):

Event Signature Description
ActivatedEvent ActivatedEvent<public>:listenable(?agent) Triggers when someone enters the activation radius while nobody else is there. Sends the activating agent. If the activator is a non-agent then false is returned.
DamagedEvent DamagedEvent<public>:listenable(?agent) Triggers when the turret is damaged. Sends the triggering agent. If the activator is a non-agent then false is returned.
DestroyedEvent DestroyedEvent<public>:listenable(?agent) Triggers when the turret is destroyed. Sends the triggering agent. If the activator is a non-agent then false is returned.
TargetFoundEvent TargetFoundEvent<public>:listenable(agent) Triggers when the turret finds a target. Sends the agent that was found.
TargetLostEvent TargetLostEvent<public>:listenable(agent) Triggers when the turret loses a target. Sends the agent that was lost.

Methods (call these to make the device act):

Method Signature Description
Enable Enable<public>():void Enables the turret to rotate, target, and track.
Disable Disable<public>():void Disables the turret, causing it to close and ignore its activation radius.
UseDefaultTeam UseDefaultTeam<public>():void Set the turret to the Default Team. * Only usable if Possible Targets is not set to Everyone.
UseTeamWildlifeAndCreatures UseTeamWildlifeAndCreatures<public>():void Set the turret to the Wildlife & Creatures team. * Only usable if Possible Targets is not set to Everyone.
GetTarget GetTarget<public>():?agent Returns the agent currently targeted by the device.
SetTarget SetTarget<public>(Agent:agent):void Set the supplied Agent as the turret's target. * The target will only change if Agent is within the activation radius, has direct line-of-sight to the turret, is on a targetable team as determined by Possible Targets, and is not Down
ClearTarget ClearTarget<public>():void Clears the turret's current target and returns the turret to searching for targets. * If the current target is still in range, it'll likely be the best target, and will be reacquired. * Combine with disabled targeting for best results.
SetDamage SetDamage<public>(Damage:float):void Sets the amount of damage the turret will do per shot to targets to Damage.
SetActivationRange SetActivationRange<public>(Range:float):void Sets the range in meters at which the turret will activate to Range. This is clamped between 2.0 and 100.0 meters.
SetTargetRange SetTargetRange<public>(Range:float):void Sets the range in meters at which the turret will target to Range. This is clamped between 2.0 and 100.0 meters. Setting it lower than 2m will disable Targeting.

Walkthrough

Let's build a vault defense: the turret starts disabled and harmless. When a player steps on a security plate (a button_device), the turret arms, its damage ramps up, and we light a warning VFX. We announce on the HUD when the turret locks a target, when it loses one, and we disable it (and clear its target) the moment it's destroyed so it doesn't keep firing as a ghost.

Every placed device is referenced through an @editable field, then we subscribe handlers in OnBegin.

automated_turret_guard := class(creative_device):

    # The turret we are scripting. Drag your placed Automated Turret here in the Details panel.
    @editable
    Turret : automated_turret_device = automated_turret_device{}

    # A button players press to arm the defense.
    @editable
    ArmButton : button_device = button_device{}

    # An optional warning effect that pulses while the turret is hot.
    @editable
    WarningVFX : vfx_spawner_device = vfx_spawner_device{}

    # HUD announcer for combat callouts.
    @editable
    Announcer : hud_message_device = hud_message_device{}

    # Localized text helper — message params need a localized value, not a raw string.
    Msg<localizes>(S : string) : message = "{S}"

    OnBegin<override>()<suspends> : void =
        # Start safe: turret off, no VFX.
        Turret.Disable()
        WarningVFX.Disable()

        # Wire up gameplay reactions.
        ArmButton.InteractedWithEvent.Subscribe(OnArmPressed)
        Turret.TargetFoundEvent.Subscribe(OnTargetFound)
        Turret.TargetLostEvent.Subscribe(OnTargetLost)
        Turret.DestroyedEvent.Subscribe(OnTurretDestroyed)

    # Player pressed the security plate — arm and tune the turret.
    OnArmPressed(Agent : agent) : void =
        Turret.SetDamage(25.0)            # damage per shot
        Turret.SetActivationRange(20.0)   # wakes up at 20m
        Turret.SetTargetRange(30.0)       # fires out to 30m
        Turret.Enable()                   # start rotating + tracking
        WarningVFX.Enable()
        Announcer.Show(Msg("Vault defenses ARMED"))

    # TargetFoundEvent hands us a plain agent (not optional).
    OnTargetFound(Target : agent) : void =
        Announcer.Show(Msg("Turret has acquired a target!"))

    OnTargetLost(Target : agent) : void =
        Announcer.Show(Msg("Turret lost its target."))

    # DestroyedEvent sends ?agent (could be a non-agent source), so unwrap it.
    OnTurretDestroyed(Attacker : ?agent) : void =
        Turret.ClearTarget()   # stop chasing whatever it was on
        Turret.Disable()       # silence the wreck
        WarningVFX.Disable()
        if (A := Attacker?):
            Announcer.Show(Msg("Turret destroyed by an attacker!"))
        else:
            Announcer.Show(Msg("Turret destroyed."))

Line by line:

  • The four @editable fields are the only way to call placed devices — a bare Turret.Enable() with no field would fail with Unknown identifier.
  • Msg<localizes>(S:string):message is the standard trick to feed a localized message into Show(). There is no StringToMessage.
  • In OnBegin we put the turret in a safe state, then subscribe handlers. Each handler is a method at class scope.
  • OnArmPressed calls four real turret setters before Enable(). Note the float literals (25.0, not 25) — Verse never auto-converts int to float.
  • TargetFoundEvent/TargetLostEvent are listenable(agent) — the handler gets a plain agent, no unwrap needed.
  • DestroyedEvent is listenable(?agent), so OnTurretDestroyed takes ?agent and we unwrap with if (A := Attacker?):.

Common patterns

Force the turret onto a specific player (boss-target lock)

Use SetTarget() to override the AI — e.g. make the turret laser-focus the player who triggered a trap. We also read it back with GetTarget() to confirm the lock took (the engine ignores out-of-range or no-line-of-sight targets).

turret_focus_lock := class(creative_device):

    @editable
    Turret : automated_turret_device = automated_turret_device{}

    # Stepping here makes the turret hunt YOU.
    @editable
    TrapPlate : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        Turret.Enable()
        TrapPlate.TriggeredEvent.Subscribe(OnPlateStepped)

    # TriggeredEvent is listenable(?agent) — unwrap the agent.
    OnPlateStepped(Agent : ?agent) : void =
        if (Victim := Agent?):
            Turret.SetTarget(Victim)        # try to lock on
            if (Locked := Turret.GetTarget?):
                # GetTarget returned a value — the lock succeeded.
                Turret.SetDamage(40.0)

Pick a team and react to activation

If your turret's Possible Targets isn't set to Everyone, you can assign it a team from Verse. Here we make it defend the Default Team against wildlife by switching teams, and we announce whenever someone first walks into its activation radius via ActivatedEvent.

turret_team_setup := class(creative_device):

    @editable
    Turret : automated_turret_device = automated_turret_device{}

    @editable
    Announcer : hud_message_device = hud_message_device{}

    Msg<localizes>(S : string) : message = "{S}"

    OnBegin<override>()<suspends> : void =
        # Only valid when Possible Targets is NOT 'Everyone'.
        Turret.UseTeamWildlifeAndCreatures()
        Turret.SetActivationRange(15.0)
        Turret.Enable()
        Turret.ActivatedEvent.Subscribe(OnActivated)

    OnActivated(Agent : ?agent) : void =
        if (A := Agent?):
            Announcer.Show(Msg("Something entered the turret's zone!"))

Repair the turret when it takes damage

Because the turret is healthful/healable, you can read its health on DamagedEvent and Heal() it back up — a self-repairing defense.

turret_self_repair := class(creative_device):

    @editable
    Turret : automated_turret_device = automated_turret_device{}

    OnBegin<override>()<suspends> : void =
        Turret.Enable()
        Turret.DamagedEvent.Subscribe(OnDamaged)

    OnDamaged(Attacker : ?agent) : void =
        CurrentHealth := Turret.GetHealth()
        MaxHealth := Turret.GetMaxHealth()
        # Top it back up to full whenever it's hurt.
        if (CurrentHealth < MaxHealth):
            Turret.Heal(MaxHealth - CurrentHealth)

Gotchas

  • message params need localized text. Show() takes a message, not a string. Declare a Msg<localizes>(S:string):message = "{S}" helper and pass Msg("..."). There is no StringToMessage function.
  • Optional vs plain agent events. ActivatedEvent, DamagedEvent, and DestroyedEvent are listenable(?agent) — unwrap with if (A := Agent?):. But TargetFoundEvent and TargetLostEvent are listenable(agent) — the handler receives a plain agent and unwrapping it would fail to compile.
  • GetTarget() returns ?agent. Don't use the result directly. Unwrap it: if (T := Turret.GetTarget?):.
  • SetTarget() can silently no-op. The target only changes if the agent is within the activation radius, has line-of-sight, is on a targetable team, and isn't Down. Always read back with GetTarget() if you depend on the lock.
  • Float literals only. SetDamage, SetActivationRange, and SetTargetRange all take float. Write 25.0, never 25 — Verse does not auto-convert int to float.
  • Range clamping. SetActivationRange/SetTargetRange clamp to 2.0–100.0 meters. Setting target range below 2m disables targeting entirely.
  • UseDefaultTeam / UseTeamWildlifeAndCreatures only work when the device's Possible Targets option isn't Everyone. Set that in the Details panel first.
  • Disable a destroyed turret. A destroyed turret can keep behaving oddly; in DestroyedEvent call ClearTarget() and Disable() to make it inert.

Device Settings & Options

The automated_turret_device User Options panel in the UEFN editor — every setting you can tune.

Automated Turret Device settings and options panel in the UEFN editor
Automated Turret Device — User Options in the UEFN editor

Guides & scripts that use automated_turret_device

Step-by-step tutorials that put this object to work.

Build your own lesson with automated_turret_device

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →