Overview
The vehicle_spawner_turbolaser_device is a specialized vehicle_spawner_device that spawns a Turbolaser turret — a heavy, emplaced anti-vehicle/anti-air weapon. You reach for it whenever you want a powerful mounted gun your players can climb into to defend a base, hold a point, or shred incoming vehicles.
Because it inherits from vehicle_spawner_device, everything you learn here also applies to the tank, UFO, siege cannon, sportbike, and every other vehicle spawner — they share the exact same Verse surface. The interesting parts for a designer are:
- Lifecycle control:
Enable,Disable,RespawnVehicle, andDestroyVehiclelet you decide when a turret exists. - Occupancy events:
AgentEntersVehicleEventandAgentExitsVehicleEventtell you who is currently manning the gun. - Spawn/destroy events:
SpawnedEvent(sends you thefort_vehicle) andDestroyedEventlet you score, respawn, or play effects. - Driver assignment:
AssignDriverforces a specific agent into the turret seat.
A classic use: a defense round where the turret is disabled until the wave starts, respawns automatically a few seconds after it's destroyed, and grants the defender points for every kill they get from the seat.
API Reference
vehicle_spawner_turbolaser_device
Specialized
vehicle_spawner_devicethat allows a Turbolaser turret 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_turbolaser_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
Let's build a base-defense Turbolaser. Requirements:
- The turret starts disabled so nobody can hop in during setup.
- When the round begins (a trigger fires), we Enable and RespawnVehicle to drop a fresh turret.
- When a player enters the turret, we remember them as the current gunner.
- When the turret is destroyed, we wait 5 seconds and RespawnVehicle so the defense isn't permanently down.
- When a new turret spawns, we log the
fort_vehiclewe got back.
Place a Turbolaser spawner and a Trigger in your level, then bind both to the @editable fields of this device.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Vehicles }
using { /Verse.org/Simulation }
turbolaser_defense := class(creative_device):
# Bind these in the Details panel after placing the devices.
@editable
TurbolaserSpawner : vehicle_spawner_turbolaser_device = vehicle_spawner_turbolaser_device{}
@editable
StartRoundTrigger : trigger_device = trigger_device{}
# Holds whoever is currently manning the turret, if anyone.
var CurrentGunner : ?agent = false
OnBegin<override>()<suspends>:void =
# Keep the turret offline until the round starts.
TurbolaserSpawner.Disable()
# Wire up every reaction we care about.
StartRoundTrigger.TriggeredEvent.Subscribe(OnRoundStart)
TurbolaserSpawner.AgentEntersVehicleEvent.Subscribe(OnGunnerEnters)
TurbolaserSpawner.AgentExitsVehicleEvent.Subscribe(OnGunnerExits)
TurbolaserSpawner.SpawnedEvent.Subscribe(OnTurretSpawned)
TurbolaserSpawner.DestroyedEvent.Subscribe(OnTurretDestroyed)
# Trigger handler: the round begins, so bring the turret online.
OnRoundStart(Agent : ?agent):void =
TurbolaserSpawner.Enable()
TurbolaserSpawner.RespawnVehicle()
# AgentEntersVehicleEvent hands us the agent that climbed in.
OnGunnerEnters(Agent : agent):void =
set CurrentGunner = option{Agent}
Print("A defender manned the Turbolaser!")
# AgentExitsVehicleEvent hands us the agent that left.
OnGunnerExits(Agent : agent):void =
set CurrentGunner = false
Print("The Turbolaser is unmanned.")
# SpawnedEvent sends the actual fort_vehicle that was created.
OnTurretSpawned(Vehicle : fort_vehicle):void =
Print("A fresh Turbolaser is online.")
# DestroyedEvent has no payload (tuple()) — just react.
OnTurretDestroyed():void =
Print("Turbolaser destroyed — respawning in 5s.")
spawn { RespawnAfterDelay() }
RespawnAfterDelay()<suspends>:void =
Sleep(5.0)
TurbolaserSpawner.RespawnVehicle()```
**Line by line:**
- The two `@editable` fields are how Verse talks to the *placed* devices. Without these fields, calling `TurbolaserSpawner.Disable()` would be an unknown-identifier error.
- `var CurrentGunner : ?agent = false` stores an optional agent. `false` means "nobody"; `option{Agent}` wraps a real one.
- In `OnBegin` we immediately `Disable()` the spawner so the turret can't be used during setup, then subscribe each handler.
- `OnRoundStart` is the trigger handler. A `trigger_device.TriggeredEvent` hands us `(Agent : ?agent)`. We `Enable()` the spawner and `RespawnVehicle()` to actually create the turret.
- `OnGunnerEnters`/`OnGunnerExits` come from `AgentEntersVehicleEvent`/`AgentExitsVehicleEvent`, which are `listenable(agent)` — so the handler param is a plain `agent`, not an optional.
- `OnTurretSpawned` receives the `fort_vehicle` from `SpawnedEvent` — useful if you later want to query or affect the vehicle directly.
- `OnTurretDestroyed` takes no parameters because `DestroyedEvent` is `listenable(tuple())`. We `spawn` a suspending helper so the 5-second `Sleep` doesn't block the event handler, then `RespawnVehicle()`.
## Common patterns
### Force a specific player into the seat with AssignDriver
Great for a "you're the gunner this round" mechanic — the chosen agent is dropped straight into the turret.
```verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
turbolaser_assign := class(creative_device):
@editable
TurbolaserSpawner : vehicle_spawner_turbolaser_device = vehicle_spawner_turbolaser_device{}
@editable
AssignButton : button_device = button_device{}
OnBegin<override>()<suspends>:void =
TurbolaserSpawner.Enable()
TurbolaserSpawner.RespawnVehicle()
AssignButton.InteractedWithEvent.Subscribe(OnButtonPressed)
# button InteractedWithEvent hands us an agent directly.
OnButtonPressed(Agent : agent):void =
# Drop the interacting player straight into the turret seat.
TurbolaserSpawner.AssignDriver(Agent)
Tear the turret down between waves with DestroyVehicle
Use Disable + DestroyVehicle to remove the turret entirely during a downtime phase.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
turbolaser_cleanup := class(creative_device):
@editable
TurbolaserSpawner : vehicle_spawner_turbolaser_device = vehicle_spawner_turbolaser_device{}
@editable
EndWaveTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends>:void =
EndWaveTrigger.TriggeredEvent.Subscribe(OnWaveEnds)
OnWaveEnds(Agent : ?agent):void =
# Remove the turret and lock the spawner until the next wave.
TurbolaserSpawner.DestroyVehicle()
TurbolaserSpawner.Disable()
Count kills the gunner gets using SpawnedEvent + elimination tracking
React to a fresh turret and start watching the gunner's eliminations.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
turbolaser_score := class(creative_device):
@editable
TurbolaserSpawner : vehicle_spawner_turbolaser_device = vehicle_spawner_turbolaser_device{}
OnBegin<override>()<suspends>:void =
TurbolaserSpawner.Enable()
TurbolaserSpawner.SpawnedEvent.Subscribe(OnSpawned)
TurbolaserSpawner.AgentEntersVehicleEvent.Subscribe(OnEnters)
TurbolaserSpawner.RespawnVehicle()
OnSpawned(Vehicle : fort_vehicle):void =
Print("Turret ready for action.")
OnEnters(Agent : agent):void =
if (Char := Agent.GetFortCharacter[]):
# Now you have the manned player's character to track stats on.
Char.EliminatedEvent().Subscribe(OnGunnerGotKill)
OnGunnerGotKill(Result : elimination_result):void =
Print("Gunner scored an elimination!")
Gotchas
- You MUST declare the spawner as an
@editablefield inside aclass(creative_device)and bind it in the Details panel. A barevehicle_spawner_turbolaser_device{}literal does nothing — it isn't the placed device. DestroyedEventandSpawnedEventpayloads differ.SpawnedEventislistenable(fort_vehicle), so its handler takes(Vehicle : fort_vehicle).DestroyedEventislistenable(tuple()), so its handler takes no parameters. Mismatching the signature is a compile error.- Don't use the deprecated events.
VehicleSpawnedEventandVehicleDestroyedEventstill exist but are deprecated — preferSpawnedEvent/DestroyedEvent.SpawnedEventalso gives you thefort_vehicle, which the old one didn't. AgentEntersVehicleEventislistenable(agent), notlistenable(?agent). Its handler param is a plainagentyou can use directly — noif (A := Agent?)unwrap needed. Compare withtrigger_device.TriggeredEvent, which does hand you a?agent.RespawnVehicledestroys the old turret first. If a player is currently driving, callingRespawnVehiclewill eject them — don't call it mid-fight unless that's intended.- Don't
Sleepdirectly inside an event handler that returnsvoidwithout<suspends>. Move the delay into a<suspends>helper andspawnit, as shown in the walkthrough. AssignDriverneeds a valid agent in the world. If the agent isn't currently a spawned, alive player, the assignment silently won't seat anyone.