Reference Devices compiles

sentry_device: AI Guards That Spawn, Alert, and Attack

The sentry_device drops a hostile AI turret-bot into your level that hunts and attacks players in range. With Verse you can spawn it on cue, switch its team, force it to target a specific player, and react to every alert, attack, and elimination — turning a static guard into a fully scripted boss encounter.

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

Overview

The sentry_device generates an AI bot that spawns at a fixed location and attacks players (and creatures) that come within its range. It's the go-to device for guarded vaults, ambush rooms, boss fights, and escape-room set pieces where you want a threat the player has to fight or sneak past.

Where it really shines is scripted combat. Instead of letting the sentry just sit there, Verse lets you:

  • Spawn / DestroySentry it on a trigger (e.g. only after the player grabs the key).
  • Enable / Disable the whole device.
  • JoinTeam / ResetTeam so the sentry temporarily fights for the player, then turns hostile again.
  • Target / Pacify / EnableAlert / ResetAlertCooldown to micromanage who it shoots and when.
  • React to AlertedEvent, AttackingEvent, EliminatedEvent, EliminatingAgentEvent and more to drive cinematics, score, and follow-up waves.

Reach for it whenever you need an enemy that responds to where the player is — not a scripted projectile, but a living guard you can choreograph.

API Reference

sentry_device

Generates an AI bot that spawns in a location and usually attacks players when they come in range.

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

sentry_device<public> := class<concrete><final>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
AlertedEvent AlertedEvent<public>:listenable(agent) Signaled when the sentry is alerted to an agent. Sends the agent who alerted the sentry.
ExitsAlertEvent ExitsAlertEvent<public>:listenable(tuple()) Signaled when the sentry exists the alert state.
EntersAlertCooldownEvent EntersAlertCooldownEvent<public>:listenable(tuple()) Signaled when the sentry enters the alert state.
AttackingEvent AttackingEvent<public>:listenable(agent) Signaled when a sentry attacks an agent. Sends the agent who is being attacked.
EliminatedEvent EliminatedEvent<public>:listenable(?agent) Signaled when a sentry is eliminated. Sends the agent that eliminated the sentry. If the sentry was eliminated by a non-agent then false is returned.
EliminatingACreatureEvent EliminatingACreatureEvent<public>:listenable(tuple()) Signaled when the sentry eliminates a creature.
EliminatingAgentEvent EliminatingAgentEvent<public>:listenable(agent) Signaled when a sentry eliminates an agent. Sends the agent who was eliminated by the sentry.

Methods (call these to make the device act):

Method Signature Description
Enable Enable<public>():void Enables this device.
Disable Disable<public>():void Disables this device.
Spawn Spawn<public>():void Spawns the sentry.
DestroySentry DestroySentry<public>():void Destroys the current sentry.
JoinTeam JoinTeam<public>(Agent:agent):void Sets the sentry to the same team Agent is on.
ResetTeam ResetTeam<public>():void Resets the sentry to the original team designated in the device options.
Pacify Pacify<public>():void Puts the sentry into the pacify state, preventing from entering the alert (attacking) state.
EnableAlert EnableAlert<public>():void Puts the sentry into the alert state.
Target Target<public>(Agent:agent):void Sets the sentry to target Agent. The sentry will not target agents on the same team as the sentry.
ResetAlertCooldown ResetAlertCooldown<public>():void Resets the alert state.

Walkthrough

Let's build a vault guardian. The sentry stays hidden until the player steps on a pressure plate. When the plate fires, the sentry spawns and we force it to target the triggering player. When the player finally eliminates the sentry, we open the vault (a prop_mover_device) and award the win. We also log alerts so you can see the state machine in action.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

vault_guardian := class(creative_device):

    @editable
    Guardian : sentry_device = sentry_device{}

    @editable
    StartPlate : trigger_device = trigger_device{}

    @editable
    VaultDoor : prop_mover_device = prop_mover_device{}

    Logger : log = log{Channel := vault_log}

    OnBegin<override>()<suspends>:void =
        # Sentry is off until the player triggers the fight.
        Guardian.Disable()

        # When the player steps on the plate, start the encounter.
        StartPlate.TriggeredEvent.Subscribe(OnPlateStepped)

        # React to the sentry's combat lifecycle.
        Guardian.AlertedEvent.Subscribe(OnAlerted)
        Guardian.AttackingEvent.Subscribe(OnAttacking)
        Guardian.EliminatedEvent.Subscribe(OnSentryEliminated)

    OnPlateStepped(Agent : ?agent):void =
        Guardian.Enable()
        Guardian.Spawn()
        # Force the sentry onto whoever started the fight.
        if (Player := Agent?):
            Guardian.Target(Player)
            Logger.Print("Vault guardian spawned and locked onto the intruder!")

    OnAlerted(Attacker : agent):void =
        Logger.Print("Guardian is alerted!")

    OnAttacking(Victim : agent):void =
        Logger.Print("Guardian is firing on a player!")

    OnSentryEliminated(MaybeAgent : ?agent):void =
        # The sentry is down — open the vault.
        VaultDoor.Begin()
        if (Winner := MaybeAgent?):
            Logger.Print("Guardian defeated! Vault is opening.")
        else:
            Logger.Print("Guardian destroyed by the environment. Vault opening.")

vault_log := class(log_channel){}

Line by line:

  • The @editable fields (Guardian, StartPlate, VaultDoor) let you drag the placed devices into the script from the Details panel. Without the @editable field you cannot call the device's methods.
  • In OnBegin we immediately Disable() the sentry so it doesn't exist until the fight starts.
  • We Subscribe the plate's TriggeredEvent and three of the sentry's events. Handlers are plain methods at class scope.
  • OnPlateStepped receives (Agent : ?agent) from the trigger. We Enable() then Spawn() the sentry, then unwrap the agent with if (Player := Agent?) and call Target(Player) so the bot zeroes in on the intruder.
  • OnSentryEliminated receives ?agent because the eliminator might be a non-agent (fall damage, a trap). We unwrap it; either way we call VaultDoor.Begin() to open the vault.
  • vault_log is the log channel referenced by the Logger field.

Common patterns

Make the sentry fight FOR the player, then betray them

JoinTeam puts the sentry on the player's team (it won't shoot teammates). ResetTeam snaps it back to its original hostile team. Great for an allied-turret-turns-traitor twist.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

turncoat_sentry := class(creative_device):

    @editable
    Sentry : sentry_device = sentry_device{}

    @editable
    AllyButton : button_device = button_device{}

    @editable
    BetrayButton : button_device = button_device{}

    OnBegin<override>()<suspends>:void =
        Sentry.Spawn()
        AllyButton.InteractedWithEvent.Subscribe(OnRecruit)
        BetrayButton.InteractedWithEvent.Subscribe(OnBetray)

    OnRecruit(Agent : agent):void =
        # Sentry joins the player's team and stops attacking them.
        Sentry.JoinTeam(Agent)

    OnBetray(Agent : agent):void =
        # Back to the original hostile team.
        Sentry.ResetTeam()

Pacify during a cutscene, then re-alert

Pacify stops the sentry from entering its attack state — perfect while a cinematic plays. EnableAlert forces it back into combat afterward, and ResetAlertCooldown clears the cooldown so it can re-acquire immediately.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

scripted_sentry := class(creative_device):

    @editable
    Sentry : sentry_device = sentry_device{}

    @editable
    CutsceneStart : trigger_device = trigger_device{}

    @editable
    CutsceneEnd : trigger_device = trigger_device{}

    OnBegin<override>()<suspends>:void =
        Sentry.Spawn()
        CutsceneStart.TriggeredEvent.Subscribe(OnCutsceneStart)
        CutsceneEnd.TriggeredEvent.Subscribe(OnCutsceneEnd)

    OnCutsceneStart(Agent : ?agent):void =
        # Freeze the sentry so it won't shoot mid-cutscene.
        Sentry.Pacify()

    OnCutsceneEnd(Agent : ?agent):void =
        # Wake it up and let it acquire targets right away.
        Sentry.EnableAlert()
        Sentry.ResetAlertCooldown()

Track kills and creature cleanup

React to what the sentry eliminates. EliminatingAgentEvent sends the downed player; EliminatingACreatureEvent carries no payload (it's tuple()).

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

kill_tracker := class(creative_device):

    @editable
    Sentry : sentry_device = sentry_device{}

    Logger : log = log{Channel := kill_log}

    OnBegin<override>()<suspends>:void =
        Sentry.Spawn()
        Sentry.EliminatingAgentEvent.Subscribe(OnEliminatedPlayer)
        Sentry.EliminatingACreatureEvent.Subscribe(OnEliminatedCreature)

    OnEliminatedPlayer(Victim : agent):void =
        Logger.Print("The sentry eliminated a player!")

    OnEliminatedCreature():void =
        Logger.Print("The sentry cleared out a creature.")

kill_log := class(log_channel){}

Gotchas

  • SpawnEnable. Enable() turns the device on; Spawn() actually creates the bot. A disabled device won't spawn. In the walkthrough we call Enable() before Spawn(). If you set Spawn on Game Start to false in the device options, you must call Spawn() from Verse for the bot to appear.
  • EliminatedEvent hands you ?agent, not agent. The sentry might be killed by something with no agent (a trap, fall damage). Always unwrap with if (Winner := MaybeAgent?): before using the eliminator. The same is true of trigger handlers (Agent : ?agent).
  • AttackingEvent / AlertedEvent / EliminatingAgentEvent hand you a plain agent (already unwrapped) — don't try to ?-unwrap those or you'll get a type error.
  • Target only sticks if the agent is reachable. The sentry will refuse to target an agent outside its activation radius, out of line-of-sight, on its own team, or Down-But-Not-Out. Calling Target on an out-of-range player silently does nothing.
  • JoinTeam makes the sentry ignore that agent's whole team. If you want it hostile again, you must call ResetTeam() — there's no automatic timeout.
  • Pacify blocks alert; EnableAlert overrides it. If you pacified the sentry and want it fighting again, call EnableAlert() (and optionally ResetAlertCooldown()), not just Enable().
  • Event handlers must be class-scope methods, and you subscribe in OnBegin. A bare Sentry.Spawn() outside a creative_device class with an @editable field fails with 'Unknown identifier'.

Device Settings & Options

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

Sentry Device settings and options panel in the UEFN editor — Weapon Type, Health, Shield, Respawn Time, Range, Accuracy, Sentry Scale
Sentry Device — User Options (1 of 2) in the UEFN editor: Weapon Type, Health, Shield, Respawn Time, Range, Accuracy, Sentry Scale
Sentry Device settings and options panel in the UEFN editor — Weapon Type, Health, Shield, Respawn Time, Range, Accuracy, Sentry Scale
Sentry Device — User Options (2 of 2) in the UEFN editor: Weapon Type, Health, Shield, Respawn Time, Range, Accuracy, Sentry Scale
⚙️ Settings on this device (7)

Setting names read from the panel above — may be partial; the screenshots are the source of truth.

Weapon Type
Health
Shield
Respawn Time
Range
Accuracy
Sentry Scale

Guides & scripts that use sentry_device

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

Build your own lesson with sentry_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 →