Reference Devices compiles

vehicle_spawner_surfboard_device: Ride the Wave with Verse

The `vehicle_spawner_surfboard_device` lets you place a rideable surfboard anywhere in your UEFN island and control it entirely from Verse. Whether you're building a surf-race minigame, a timed challenge where the board vanishes after 30 seconds, or a VIP mode that auto-mounts a player the moment they step on a trigger — this device gives you the hooks to do it all. It inherits every method and event from `vehicle_spawner_device`, so the patterns you learn here apply to every other vehicle spawn

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

Overview

The vehicle_spawner_surfboard_device is a concrete, final specialization of the abstract vehicle_spawner_device base class. Drop one into your level from the Content Browser and it will spawn a surfboard at its location when the game starts (if configured to do so). From Verse you can:

  • Enable / Disable the spawner so the board only appears during the right phase of your game.
  • RespawnVehicle to reset the board to its spawn point mid-match (great for a surf-race reset mechanic).
  • DestroyVehicle to blow the board up on a timer or as a punishment.
  • AssignDriver to force a specific player onto the board automatically.
  • React to AgentEntersVehicleEvent, AgentExitsVehicleEvent, SpawnedEvent, and DestroyedEvent to drive score, UI, or other game logic.

Reach for this device whenever your island needs a player-rideable surfboard that your Verse code must orchestrate — timed challenges, race gates, VIP transports, or wave-surfing arenas.

API Reference

vehicle_spawner_surfboard_device

Specialized vehicle_spawner_device that allows a surfboard 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_surfboard_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: Surf-Race Checkpoint Arena

A player steps on a trigger_device to start the race. The surfboard spawns (or respawns if it was already out), the player is automatically assigned as driver, a 60-second countdown begins, and when time runs out the board is destroyed. If the player bails early (exits the vehicle), the board is immediately respawned so the next racer can go.

Place in your level:

  • One vehicle_spawner_surfboard_device (name it SurfSpawner in the Outliner)
  • One trigger_device (name it StartTrigger)
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Fortnite.com/Vehicles }

surf_race_manager := class(creative_device):

    # Wire these up in the Details panel
    @editable
    SurfSpawner : vehicle_spawner_surfboard_device = vehicle_spawner_surfboard_device{}

    @editable
    StartTrigger : trigger_device = trigger_device{}

    # Track whether a race is in progress so we don't double-start
    var RaceActive : logic = false

    OnBegin<override>()<suspends> : void =
        # Subscribe to the start trigger
        StartTrigger.TriggeredEvent.Subscribe(OnRaceStart)

        # React when a player bails off the board
        SurfSpawner.AgentExitsVehicleEvent.Subscribe(OnSurferExited)

        # React when the board is destroyed (timer expired)
        SurfSpawner.DestroyedEvent.Subscribe(OnBoardDestroyed)

        # React when a fresh board finishes spawning
        SurfSpawner.SpawnedEvent.Subscribe(OnBoardSpawned)

        # Start disabled — only enable when a race begins
        SurfSpawner.Disable()

    # Called when the trigger fires (agent is ?agent so we unwrap it)
    OnRaceStart(Agent : ?agent) : void =
        if (set RaceActive = false, A := Agent?):
            set RaceActive = true
            # Enable the spawner and get a fresh board
            SurfSpawner.Enable()
            SurfSpawner.RespawnVehicle()
            # Assign the triggering player as driver
            SurfSpawner.AssignDriver(A)
            # Start the countdown on a separate async task
            spawn { RunCountdown() }

    # Fires when SpawnedEvent signals — receives the fort_vehicle
    OnBoardSpawned(Vehicle : fort_vehicle) : void =
        # You could store Vehicle here or display a UI message
        # For now we just note the board is live
        if (RaceActive?):
            # Board is ready — race is already running

    # If the surfer bails, respawn the board for the next player
    OnSurferExited(Agent : agent) : void =
        if (RaceActive?):
            set RaceActive = false
            SurfSpawner.RespawnVehicle()

    # When the board is destroyed, lock the spawner until next race
    OnBoardDestroyed(Empty : tuple()) : void =
        set RaceActive = false
        SurfSpawner.Disable()

    # 60-second race timer — destroys the board when it expires
    RunCountdown()<suspends> : void =
        Sleep(60.0)
        if (RaceActive?):
            SurfSpawner.DestroyVehicle()```

**Line-by-line highlights:**

| Lines | What's happening |
|---|---|
| `@editable SurfSpawner` | Declares the device field — without this, `SurfSpawner.Enable()` would fail with *Unknown identifier*. |
| `StartTrigger.TriggeredEvent.Subscribe(OnRaceStart)` | Hooks the trigger. The handler receives `?agent` — we unwrap with `if (A := Agent?)`. |
| `SurfSpawner.Disable()` | Hides the board at game start; only re-enabled when a race begins. |
| `SurfSpawner.RespawnVehicle()` | Destroys any existing board and spawns a fresh one at the spawner's location. |
| `SurfSpawner.AssignDriver(A)` | Puts the player on the board automatically  no manual boarding needed. |
| `SurfSpawner.SpawnedEvent.Subscribe(OnBoardSpawned)` | Uses the **non-deprecated** event that sends the actual `fort_vehicle`. |
| `SurfSpawner.DestroyedEvent.Subscribe(OnBoardDestroyed)` | Uses the **non-deprecated** replacement for `VehicleDestroyedEvent`. |
| `spawn { RunCountdown() }` | Runs the 60-second timer concurrently without blocking `OnBegin`. |
| `SurfSpawner.DestroyVehicle()` | Ends the race by destroying the board; triggers `DestroyedEvent`. |

---

## Common patterns

### Pattern 1 — Toggle the spawner with a button (Enable / Disable)

A button in the lobby activates the surfboard zone. A second button deactivates it and destroys any live board.

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

surf_toggle_device := class(creative_device):

    @editable
    SurfSpawner : vehicle_spawner_surfboard_device = vehicle_spawner_surfboard_device{}

    @editable
    ActivateButton : button_device = button_device{}

    @editable
    DeactivateButton : button_device = button_device{}

    OnBegin<override>()<suspends> : void =
        SurfSpawner.Disable()  # Off by default
        ActivateButton.InteractedWithEvent.Subscribe(OnActivate)
        DeactivateButton.InteractedWithEvent.Subscribe(OnDeactivate)

    OnActivate(Agent : agent) : void =
        SurfSpawner.Enable()
        SurfSpawner.RespawnVehicle()

    OnDeactivate(Agent : agent) : void =
        SurfSpawner.DestroyVehicle()  # Remove the board first
        SurfSpawner.Disable()         # Then lock the spawner

Pattern 2 — Auto-assign driver when a player enters a zone (AssignDriver + AgentEntersVehicleEvent)

When a player walks into a trigger zone near the board, they are automatically assigned as driver. When they exit the vehicle, the board respawns for the next player.

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

surf_autoboard_device := class(creative_device):

    @editable
    SurfSpawner : vehicle_spawner_surfboard_device = vehicle_spawner_surfboard_device{}

    @editable
    BoardingZone : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        BoardingZone.TriggeredEvent.Subscribe(OnPlayerEntersZone)
        SurfSpawner.AgentEntersVehicleEvent.Subscribe(OnMounted)
        SurfSpawner.AgentExitsVehicleEvent.Subscribe(OnDismounted)

    # Trigger sends ?agent — unwrap before use
    OnPlayerEntersZone(Agent : ?agent) : void =
        if (A := Agent?):
            SurfSpawner.AssignDriver(A)

    OnMounted(Agent : agent) : void =
        # Player is now riding — could start a score timer here

    OnDismounted(Agent : agent) : void =
        # Board is free — respawn it so the next player can ride
        SurfSpawner.RespawnVehicle()

Pattern 3 — Periodic board reset (RespawnVehicle on a loop)

In a free-roam surf park, the board resets to its spawn point every 45 seconds so it never drifts too far from the start.

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

surf_reset_loop_device := class(creative_device):

    @editable
    SurfSpawner : vehicle_spawner_surfboard_device = vehicle_spawner_surfboard_device{}

    # How often (seconds) the board resets
    ResetInterval : float = 45.0

    OnBegin<override>()<suspends> : void =
        SurfSpawner.Enable()
        SurfSpawner.SpawnedEvent.Subscribe(OnBoardSpawned)
        loop:
            Sleep(ResetInterval)
            SurfSpawner.RespawnVehicle()  # Destroys old board, spawns fresh one

    OnBoardSpawned(Vehicle : fort_vehicle) : void =
        # The fresh fort_vehicle reference is available here if needed

Gotchas

1. Always declare the device as an @editable field

You cannot write vehicle_spawner_surfboard_device{}.Enable() inline. The device must be an @editable field wired in the Details panel. A bare local variable has no connection to the placed actor and every method call silently does nothing (or fails to compile).

# ✅ Correct
@editable
SurfSpawner : vehicle_spawner_surfboard_device = vehicle_spawner_surfboard_device{}

# ❌ Wrong — not wired to anything in the level
LocalBoard := vehicle_spawner_surfboard_device{}
LocalBoard.Enable()  # This device is not the one in your scene

2. Use SpawnedEvent and DestroyedEvent, not the deprecated ones

VehicleSpawnedEvent and VehicleDestroyedEvent are deprecated as of 25.00. Use SpawnedEvent (which sends the fort_vehicle) and DestroyedEvent instead. The deprecated events send an empty tuple() and will be removed in a future release.

3. AgentEntersVehicleEvent sends agent, but trigger_device.TriggeredEvent sends ?agent

These are different types. AgentEntersVehicleEvent and AgentExitsVehicleEvent send a non-optional agent directly — no unwrapping needed. trigger_device.TriggeredEvent sends ?agent — always unwrap with if (A := Agent?): before calling any agent API.

# AgentEntersVehicleEvent — agent is NOT optional
OnMounted(Agent : agent) : void =
    # Use Agent directly

# trigger_device.TriggeredEvent — agent IS optional
OnTriggered(Agent : ?agent) : void =
    if (A := Agent?):
        SurfSpawner.AssignDriver(A)

4. RespawnVehicle destroys the existing board first

Calling RespawnVehicle() when a board is already live will destroy it and then spawn a fresh one. This triggers DestroyedEvent. If your DestroyedEvent handler calls RespawnVehicle() again you will create an infinite loop. Guard with a flag (var RaceActive : logic) as shown in the Walkthrough.

5. AssignDriver requires the vehicle to exist

If you call AssignDriver before the board has finished spawning, the call may have no effect. Subscribe to SpawnedEvent and call AssignDriver from inside that handler (or after RespawnVehicle has had time to complete) to be safe. Alternatively, call it immediately after RespawnVehicle — the engine queues the assignment for when the vehicle is ready.

6. No message parameters on this device

vehicle_spawner_surfboard_device has no text-display methods, so you won't hit the message vs string pitfall here. But if you pair it with a hud_message_device to show race text, remember: message parameters require a <localizes> function — there is no StringToMessage helper.

# Correct way to pass dynamic text to a message param elsewhere
RaceText<localizes>(S : string) : message = "{S}"

Device Settings & Options

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

Vehicle Spawner Surfboard Device settings and options panel in the UEFN editor — Supports Wraps
Vehicle Spawner Surfboard Device — User Options in the UEFN editor: Supports Wraps
⚙️ Settings on this device (1)

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

Supports Wraps

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