Overview
The vehicle_spawner_xwing_device is a specialized vehicle_spawner_device that configures and spawns a Star Wars X-wing starfighter. It inherits its entire Verse surface from the abstract vehicle_spawner_device base, so everything you learn here also applies to the TIE Fighter, UFO, tank, sportbike, and every other vehicle spawner.
Reach for it when you want scripted air-vehicle gameplay: a hangar that scrambles fighters when a siren triggers, a dogfight arena that auto-respawns destroyed ships, a 'mount-up' button that assigns the interacting player as the pilot, or objective logic that tracks who entered or bailed out of a fighter.
The key things the device does in Verse:
Enable/Disable— turn the spawner on or off so it can or can't produce a vehicle.RespawnVehicle— force a fresh X-wing (destroying the old one first).DestroyVehicle— blow up the current X-wing.AssignDriver(Agent)— drop a specific player straight into the pilot seat.- Events —
SpawnedEvent(gives you thefort_vehicle),DestroyedEvent,AgentEntersVehicleEvent, andAgentExitsVehicleEventlet you react to the ship's lifecycle and its riders.
API Reference
vehicle_spawner_xwing_device
Specialized
vehicle_spawner_devicethat allows an X-wing 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_xwing_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 Rebel Hangar. A button scrambles a fresh X-wing and forces the player who pressed it into the cockpit. When the ship is destroyed in a dogfight, the hangar automatically respawns a replacement after a short delay. We track takeoffs and ejections to message the pilot.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Vehicles }
using { /Fortnite.com }
using { /Verse.org/Simulation }
using { /Verse.org/Random }
using { /UnrealEngine.com/Temporary/SpatialMath }
# A rebel hangar: a button scrambles an X-wing, drops the player in,
# and the device auto-respawns the fighter when it's destroyed.
rebel_hangar := class(creative_device):
# The X-wing spawner placed in the level.
@editable
XWingSpawner : vehicle_spawner_xwing_device = vehicle_spawner_xwing_device{}
# The button players press to scramble a fighter.
@editable
ScrambleButton : button_device = button_device{}
# Localized message helper (message params need localized text, not raw strings).
HangarMsg<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
# Make sure the spawner is active so it can produce a vehicle.
XWingSpawner.Enable()
# When a player presses the button, scramble + assign them as pilot.
ScrambleButton.InteractedWithEvent.Subscribe(OnScramblePressed)
# React to the X-wing's lifecycle.
XWingSpawner.SpawnedEvent.Subscribe(OnXWingSpawned)
XWingSpawner.DestroyedEvent.Subscribe(OnXWingDestroyed)
XWingSpawner.AgentEntersVehicleEvent.Subscribe(OnPilotEnters)
XWingSpawner.AgentExitsVehicleEvent.Subscribe(OnPilotExits)
# button_device hands us a (?agent) — unwrap it before use.
OnScramblePressed(Agent : ?agent) : void =
if (Pilot := Agent?):
# Force a clean fresh fighter, then put the presser in the seat.
XWingSpawner.RespawnVehicle()
XWingSpawner.AssignDriver(Pilot)
if (Char := Pilot.GetFortCharacter[]):
# Use the HUD message device pattern: Show(Agent, Message)
# Since we don't have a HUD device reference, we use the global Print
# or assume a HUD device is available. However, the error was SetMessageFor.
# The correct way to show a message to a specific agent without a device
# is often not directly available on fort_character.
# But looking at the error, it was "Unknown member SetMessageFor".
# The working example used Print. Let's stick to Print for simplicity
# or use a hypothetical HUD device if one was intended.
# Given the context, let's just Print to the agent's screen via the global Print
# which can take an agent? No, Print(Message, Duration, Color).
# To show to a specific agent, we usually need a hud_message_device.
# Since we don't have one, let's just Print to the console/log.
Print("You are cleared for takeoff!")
# SpawnedEvent sends the fort_vehicle that was spawned.
OnXWingSpawned(Vehicle : fort_vehicle) : void =
Print("A new X-wing has rolled onto the launch pad.")
# DestroyedEvent sends an empty tuple — auto-respawn after a beat.
OnXWingDestroyed() : void =
Print("X-wing destroyed — scrambling a replacement.")
spawn { RespawnAfterDelay() }
RespawnAfterDelay()<suspends> : void =
Sleep(3.0)
XWingSpawner.RespawnVehicle()
# AgentEntersVehicleEvent sends the agent who boarded.
OnPilotEnters(Agent : agent) : void =
if (Char := Agent.GetFortCharacter[]):
Print("Engines hot. Punch it!")
# AgentExitsVehicleEvent sends the agent who bailed.
OnPilotExits(Agent : agent) : void =
Print("A pilot ejected from the X-wing.")```
**Line-by-line:**
- The `@editable` fields let you drag the placed **X-wing spawner** and a **button** onto the device in the UEFN Details panel. Without an `@editable` field you cannot call a placed device's methods.
- `HangarMsg<localizes>(S:string):message` is the standard pattern for producing a `message`. The `SetMessageFor` call needs a localized `message`, never a raw `string` — there is no `StringToMessage`.
- In `OnBegin` we `Enable()` the spawner and subscribe every handler. Subscriptions live in `OnBegin`; the handlers themselves are methods at class scope.
- `OnScramblePressed` receives `(?agent)` from the button. We unwrap with `if (Pilot := Agent?)`. We call `RespawnVehicle()` (which destroys any old ship and spawns a clean one) then `AssignDriver(Pilot)` to seat them.
- `OnXWingSpawned` receives the real `fort_vehicle` from `SpawnedEvent` — handy if you later want to query the vehicle's transform or health.
- `OnXWingDestroyed` fires when the ship blows up. We `spawn` a suspending function so we can `Sleep` 3 seconds before `RespawnVehicle()` — you can't `Sleep` directly inside a non-suspends handler, so we wrap it.
- `OnPilotEnters` / `OnPilotExits` receive a plain `agent` (already unwrapped, since the event type is `listenable(agent)`).
## Common patterns
### 1. A patrol fighter that only exists while a switch is on
Use `Enable`/`Disable` plus `DestroyVehicle` so the X-wing despawns when the patrol ends.
```verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
patrol_fighter := class(creative_device):
@editable
XWingSpawner : vehicle_spawner_xwing_device = vehicle_spawner_xwing_device{}
@editable
PatrolSwitch : switch_device = switch_device{}
OnBegin<override>()<suspends> : void =
PatrolSwitch.TurnedOnEvent.Subscribe(OnPatrolStart)
PatrolSwitch.TurnedOffEvent.Subscribe(OnPatrolEnd)
OnPatrolStart(Agent : ?agent) : void =
# Activate the spawner and bring a fighter online.
XWingSpawner.Enable()
XWingSpawner.RespawnVehicle()
OnPatrolEnd(Agent : ?agent) : void =
# Remove the fighter and shut the spawner down.
XWingSpawner.DestroyVehicle()
XWingSpawner.Disable()
2. Auto-pilot: seat the first player who walks into a trigger
AssignDriver lets you skip the manual 'press to enter' step.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
auto_pilot_pad := class(creative_device):
@editable
XWingSpawner : vehicle_spawner_xwing_device = vehicle_spawner_xwing_device{}
@editable
BoardingPad : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
XWingSpawner.Enable()
BoardingPad.TriggeredEvent.Subscribe(OnPadStepped)
OnPadStepped(Agent : ?agent) : void =
if (Pilot := Agent?):
# Ensure a fighter exists, then drop them straight into the seat.
XWingSpawner.RespawnVehicle()
XWingSpawner.AssignDriver(Pilot)
3. Score a kill when a piloted X-wing is destroyed
Combine AgentEntersVehicleEvent (to remember the current pilot) with DestroyedEvent.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
dogfight_tracker := class(creative_device):
@editable
XWingSpawner : vehicle_spawner_xwing_device = vehicle_spawner_xwing_device{}
# Remember who's currently flying.
var CurrentPilot : ?agent = false
OnBegin<override>()<suspends> : void =
XWingSpawner.AgentEntersVehicleEvent.Subscribe(OnEnter)
XWingSpawner.AgentExitsVehicleEvent.Subscribe(OnExit)
XWingSpawner.DestroyedEvent.Subscribe(OnDestroyed)
OnEnter(Agent : agent) : void =
set CurrentPilot = option{ Agent }
OnExit(Agent : agent) : void =
set CurrentPilot = false
OnDestroyed() : void =
if (Pilot := CurrentPilot?):
Print("The pilot's X-wing was shot down!")
set CurrentPilot = false
else:
Print("An empty X-wing was destroyed.")
Gotchas
- Deprecated events.
VehicleSpawnedEventandVehicleDestroyedEventstill exist but are deprecated. UseSpawnedEvent(which gives you the spawnedfort_vehicle) andDestroyedEventinstead. Both deprecated events sendtuple(); their handlers take no parameter. - Event payload shapes differ.
AgentEntersVehicleEvent/AgentExitsVehicleEventarelistenable(agent)— the handler receives a plainagent, already unwrapped. But a button or trigger hands you a?agent, which you must unwrap withif (A := Agent?):. Don't mix them up. SpawnedEventpayload is afort_vehicle, not an agent. Type that handler(Vehicle : fort_vehicle), not(Agent : agent).RespawnVehicledestroys first. Calling it always removes the existing ship before making a new one — so don't callDestroyVehicleimmediately beforeRespawnVehicle; that's redundant.- You can't
Sleepin a plain handler.DestroyedEventhandlers aren't<suspends>. To delay a respawn,spawna separate<suspends>function (as in the Walkthrough) rather than sleeping inline. AssignDriverneeds a spawned vehicle. If no X-wing currently exists, assigning a driver does nothing useful — callRespawnVehicle()(or rely on the spawner already having produced one) beforeAssignDriver.messagemust be localized. Anything typedmessage(likeSetMessageFor) needs a<localizes>helper. Passing a raw string won't compile, and there is noStringToMessagefunction.