Reference Devices compiles

vehicle_spawner_tank_device: Armored Combat on Demand

The `vehicle_spawner_tank_device` puts a fully driveable tank on your island and gives your Verse code complete control over it — spawn it, destroy it, assign a driver, and react to every boarding or destruction event. Whether you're building a king-of-the-hill mode where only the round winner gets the tank, or a wave-defense map where the tank resets between rounds, this device is your armored command center.

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

Overview

The vehicle_spawner_tank_device is a specialized concrete subclass of vehicle_spawner_device that lets you place a configurable tank in your UEFN level and drive its entire lifecycle from Verse. Out of the box the device can spawn the tank automatically when the round starts, but the real power comes from Verse: you can disable the spawner so no tank appears until your script decides the moment is right, force-assign a specific player as driver, blow up the tank mid-match, and respawn a fresh one for the next wave — all while reacting to events that fire whenever an agent hops in or out, or whenever the vehicle is destroyed.

Reach for this device when you need:

  • Scripted vehicle gates — only the round MVP gets to drive the tank.
  • Wave resets — destroy and respawn the tank cleanly between combat waves.
  • Stat tracking — count how many players entered the tank or how many times it was destroyed.
  • Cinematic moments — assign a specific player as driver the instant a cutscene ends.

Because vehicle_spawner_tank_device inherits every method and event from vehicle_spawner_device, everything documented here applies equally to the base class pattern used by all other vehicle spawners.

API Reference

vehicle_spawner_tank_device

Specialized vehicle_spawner_device that allows a tank to be configured and spawned.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from vehicle_spawner_device.

vehicle_spawner_tank_device<public> := class<concrete><final>(vehicle_spawner_device):

Events (subscribe a handler to react):

Event Signature Description
AgentEntersVehicleEvent AgentEntersVehicleEvent<public>:listenable(agent) Signaled when an agent enters the vehicle. Sends the agent that entered the vehicle.
AgentExitsVehicleEvent AgentExitsVehicleEvent<public>:listenable(agent) Signaled when an agent exits the vehicle. Sends the agent that exited the vehicle.
SpawnedEvent SpawnedEvent<public>:listenable(fort_vehicle) Signaled when a vehicle is spawned or respawned by this device. Sends the fort_vehicle who was spawned.
VehicleSpawnedEvent VehicleSpawnedEvent<public>:listenable(tuple()) Signaled when a vehicle is spawned or respawned by this device. Deprecated, use SpawnedEvent instead.
VehicleDestroyedEvent VehicleDestroyedEvent<public>:listenable(tuple()) Signaled when a vehicle is destroyed. Deprecated, use DestroyedEvent instead.
DestroyedEvent DestroyedEvent<public>:listenable(tuple()) Signaled when a vehicle is destroyed.

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.
AssignDriver AssignDriver<public>(Agent:agent):void Sets agent as the vehicle's driver.
DestroyVehicle DestroyVehicle<public>():void Destroys the vehicle if it exists.
RespawnVehicle RespawnVehicle<public>():void Spawns a new vehicle. The previous vehicle will be destroyed before a new vehicle spawns.

vehicle_spawner_device

Base class for various specialized vehicle spawners which allow specific vehicle types to be spawned and configured with specialized options.

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

vehicle_spawner_device<public> := class<abstract><epic_internal>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
AgentEntersVehicleEvent AgentEntersVehicleEvent<public>:listenable(agent) Signaled when an agent enters the vehicle. Sends the agent that entered the vehicle.
AgentExitsVehicleEvent AgentExitsVehicleEvent<public>:listenable(agent) Signaled when an agent exits the vehicle. Sends the agent that exited the vehicle.
SpawnedEvent SpawnedEvent<public>:listenable(fort_vehicle) Signaled when a vehicle is spawned or respawned by this device. Sends the fort_vehicle who was spawned.
VehicleSpawnedEvent VehicleSpawnedEvent<public>:listenable(tuple()) Signaled when a vehicle is spawned or respawned by this device. Deprecated, use SpawnedEvent instead.
VehicleDestroyedEvent VehicleDestroyedEvent<public>:listenable(tuple()) Signaled when a vehicle is destroyed. Deprecated, use DestroyedEvent instead.
DestroyedEvent DestroyedEvent<public>:listenable(tuple()) Signaled when a vehicle is destroyed.

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.
AssignDriver AssignDriver<public>(Agent:agent):void Sets agent as the vehicle's driver.
DestroyVehicle DestroyVehicle<public>():void Destroys the vehicle if it exists.
RespawnVehicle RespawnVehicle<public>():void Spawns a new vehicle. The previous vehicle will be destroyed before a new vehicle spawns.

Walkthrough

Scenario: The Tank Gauntlet

A team-deathmatch map has one tank that only the round MVP (tracked by an external eliminations counter, simplified here to the first player who interacts with a button) may drive. When the round ends the tank is destroyed and respawned clean for the next round. A trigger_device acts as the "MVP button".

Here is the complete, compilable device:

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

# Place this Verse device in your level, then wire up the
# @editable fields in the Details panel.
tank_gauntlet_manager := class(creative_device):

    # The tank spawner placed in the level.
    @editable TankSpawner : vehicle_spawner_tank_device = vehicle_spawner_tank_device{}

    # A trigger_device the MVP steps on to claim the tank.
    @editable MVPTrigger : trigger_device = trigger_device{}

    # A button_device the game master presses to end the round.
    @editable RoundEndButton : button_device = button_device{}

    # Tracks whether a driver has already been assigned this round.
    var DriverAssigned : logic = false

    OnBegin<override>()<suspends> : void =
        # Start with the tank disabled so it doesn't spawn until we're ready.
        TankSpawner.Disable()

        # Subscribe to all relevant events.
        MVPTrigger.TriggeredEvent.Subscribe(OnMVPTriggered)
        TankSpawner.AgentEntersVehicleEvent.Subscribe(OnAgentEnters)
        TankSpawner.AgentExitsVehicleEvent.Subscribe(OnAgentExits)
        TankSpawner.SpawnedEvent.Subscribe(OnTankSpawned)
        TankSpawner.DestroyedEvent.Subscribe(OnTankDestroyed)
        RoundEndButton.InteractedWithEvent.Subscribe(OnRoundEnd)

        # Enable the spawner — the tank appears on the map.
        TankSpawner.Enable()

    # Called when the MVP steps on the trigger plate.
    OnMVPTriggered(Agent : ?agent) : void =
        # Unwrap the optional agent safely.
        if (A := Agent?):
            if (not DriverAssigned?):
                set DriverAssigned = true
                # Assign this player as the tank's driver immediately.
                TankSpawner.AssignDriver(A)

    # Called every time any agent boards the tank.
    OnAgentEnters(Agent : agent) : void =
        # AgentEntersVehicleEvent sends a plain agent, no unwrap needed.
        Print("Agent entered the tank.")

    # Called every time any agent leaves the tank.
    OnAgentExits(Agent : agent) : void =
        Print("Agent exited the tank.")

    # SpawnedEvent sends the fort_vehicle that was spawned.
    OnTankSpawned(Vehicle : fort_vehicle) : void =
        Print("Tank spawned or respawned.")
        set DriverAssigned = false

    # DestroyedEvent sends tuple() — no payload.
    OnTankDestroyed() : void =
        Print("Tank destroyed.")

    # Game master ends the round — destroy the tank then respawn it fresh.
    OnRoundEnd(Agent : agent) : void =
        TankSpawner.DestroyVehicle()
        # RespawnVehicle destroys any existing vehicle and spawns a new one.
        # We call it here so the next round starts with a clean tank.
        TankSpawner.RespawnVehicle()```

### Line-by-line explanation

| Lines | What's happening |
|---|---|
| `@editable TankSpawner` | Declares the tank spawner as an editable field so you can wire it to the placed device in the Details panel. A bare `vehicle_spawner_tank_device{}` in a local variable would be an unconnected default — always use `@editable`. |
| `TankSpawner.Disable()` | Prevents the tank from auto-spawning while we finish setup. |
| `MVPTrigger.TriggeredEvent.Subscribe(OnMVPTriggered)` | `trigger_device.TriggeredEvent` fires with `?agent`, so the handler receives `Agent : ?agent`. |
| `TankSpawner.AgentEntersVehicleEvent.Subscribe(OnAgentEnters)` | This event fires with a plain `agent` (not optional), so the handler takes `Agent : agent` directly. |
| `TankSpawner.SpawnedEvent.Subscribe(OnTankSpawned)` | `SpawnedEvent` is `listenable(fort_vehicle)`, so the handler receives the spawned `fort_vehicle`. |
| `TankSpawner.DestroyedEvent.Subscribe(OnTankDestroyed)` | `DestroyedEvent` is `listenable(tuple())`, so the handler takes no parameters. |
| `TankSpawner.AssignDriver(A)` | Teleports the unwrapped agent into the driver's seat immediately. |
| `TankSpawner.DestroyVehicle()` | Blows up the current tank instance. |
| `TankSpawner.RespawnVehicle()` | Spawns a brand-new tank (destroying any existing one first). |

## Common patterns

### Pattern 1 — Disable the tank until a countdown finishes

Keep the tank locked away and only enable it after a timed delay, useful for battle-royale-style "tank drops in at 60 seconds".

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

tank_delayed_enable := class(creative_device):

    @editable TankSpawner : vehicle_spawner_tank_device = vehicle_spawner_tank_device{}

    # Seconds before the tank spawns.
    @editable DelaySeconds : float = 60.0

    OnBegin<override>()<suspends> : void =
        # Tank is disabled in the device settings; we enable it after the delay.
        TankSpawner.Disable()
        Sleep(DelaySeconds)
        TankSpawner.Enable()
        # Enable() causes the spawner to spawn the tank immediately.

Pattern 2 — Auto-respawn the tank every time it is destroyed

For a king-of-the-hill mode where the tank must always be on the field.

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

tank_always_present := class(creative_device):

    @editable TankSpawner : vehicle_spawner_tank_device = vehicle_spawner_tank_device{}

    OnBegin<override>()<suspends> : void =
        TankSpawner.DestroyedEvent.Subscribe(OnTankDestroyed)

    # DestroyedEvent payload is tuple() — handler takes no arguments.
    OnTankDestroyed() : void =
        # Brief pause so destruction VFX can finish, then respawn.
        # We spawn a task so we can Sleep without blocking the event thread.
        spawn { RespawnAfterDelay() }

    RespawnAfterDelay()<suspends> : void =
        Sleep(3.0)
        TankSpawner.RespawnVehicle()

Pattern 3 — Track total time a player spends inside the tank

Use AgentEntersVehicleEvent and AgentExitsVehicleEvent together to measure ride duration.

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

tank_ride_timer := class(creative_device):

    @editable TankSpawner : vehicle_spawner_tank_device = vehicle_spawner_tank_device{}

    # Wall-clock second when the current rider boarded.
    var BoardTime : float = 0.0

    # Accumulated ride seconds this session.
    var TotalRideSeconds : float = 0.0

    OnBegin<override>()<suspends> : void =
        TankSpawner.AgentEntersVehicleEvent.Subscribe(OnEnter)
        TankSpawner.AgentExitsVehicleEvent.Subscribe(OnExit)

    # AgentEntersVehicleEvent sends a plain agent.
    OnEnter(Agent : agent) : void =
        set BoardTime = GetSimulationElapsedTime()

    # AgentExitsVehicleEvent sends a plain agent.
    OnExit(Agent : agent) : void =
        ExitTime : float = GetSimulationElapsedTime()
        RideDuration : float = ExitTime - BoardTime
        set TotalRideSeconds = TotalRideSeconds + RideDuration
        Print("Ride duration: {RideDuration}s | Total: {TotalRideSeconds}s")

Gotchas

1. Always use @editable — never construct the device inline

Writing TankSpawner : vehicle_spawner_tank_device = vehicle_spawner_tank_device{} without @editable creates a disconnected default object that has no connection to the placed device in your level. Every method call on it silently does nothing. Always declare the field with @editable and assign the placed device in the Details panel.

2. Event payload types differ — check before you write the handler

Event Payload type Handler signature
AgentEntersVehicleEvent agent (plain) OnEnter(Agent : agent) : void
AgentExitsVehicleEvent agent (plain) OnExit(Agent : agent) : void
SpawnedEvent fort_vehicle OnSpawned(Vehicle : fort_vehicle) : void
DestroyedEvent tuple() OnDestroyed() : void
VehicleSpawnedEvent (deprecated) tuple() OnVehicleSpawned() : void
VehicleDestroyedEvent (deprecated) tuple() OnVehicleDestroyed() : void

Mixing these up (e.g. writing OnSpawned(Agent : agent) for SpawnedEvent) is a compile error.

3. trigger_device.TriggeredEvent sends ?agent, not agent

When you chain a trigger to your tank logic, remember that TriggeredEvent fires with an optional agent. Unwrap it before passing to AssignDriver:

OnTriggered(Agent : ?agent) : void =
    if (A := Agent?):
        TankSpawner.AssignDriver(A)

Skipping the unwrap is a type error — AssignDriver expects a plain agent.

4. RespawnVehicle destroys the existing tank first

Calling RespawnVehicle() when a tank is already on the field will destroy it (firing DestroyedEvent) and then spawn a fresh one (firing SpawnedEvent). If your DestroyedEvent handler also calls RespawnVehicle(), you'll get an infinite loop. Guard with a flag or unsubscribe the handler before calling respawn.

5. Disable does not destroy the tank

Calling Disable() prevents the spawner from spawning new vehicles, but any tank already on the field stays alive. If you want to remove the tank entirely, call DestroyVehicle() first, then Disable().

6. Deprecated events — prefer the modern ones

VehicleSpawnedEvent and VehicleDestroyedEvent both send tuple() and are marked deprecated. Use SpawnedEvent (which gives you the fort_vehicle) and DestroyedEvent in all new code.

Device Settings & Options

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

Vehicle Spawner Tank Device settings and options panel in the UEFN editor
Vehicle Spawner Tank Device — User Options in the UEFN editor

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