Reference Devices compiles

vehicle_spawner_shopping_cart_device: Build a Shopping Cart Race

The `vehicle_spawner_shopping_cart_device` lets you place a rideable shopping cart anywhere in your island and control it entirely from Verse — spawn it on demand, assign a driver, destroy it when a race ends, and react to players hopping in or out. Whether you're building a chaotic cart derby or a timed obstacle course, this device gives you the hooks to make it feel alive.

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

Overview

The vehicle_spawner_shopping_cart_device is a concrete specialization of the abstract vehicle_spawner_device base class. Drop one into your UEFN level and you get a fully driveable shopping cart that your Verse code can spawn, destroy, respawn, and monitor in real time.

When to reach for it:

  • You want a shopping cart that appears only when a race starts (not sitting idle at load).
  • You need to auto-assign a player as driver the moment they trigger a plate.
  • You want to detect when a player bails out of the cart and penalize them.
  • You need to reset the cart to its spawn point after it's destroyed or driven off a cliff.

The device inherits every method and event from vehicle_spawner_device, so everything documented below applies equally to the other specialized spawners (vehicle_spawner_sedan_device, vehicle_spawner_quadcrasher_device, etc.).

API Reference

vehicle_spawner_shopping_cart_device

Specialized vehicle_spawner_device that allows a shopping cart 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_shopping_cart_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: A shopping-cart race mini-game. When a player steps on a trigger plate, the cart spawns, that player is automatically assigned as driver, and a barrier blocking the track drops. When the cart is destroyed (player wipes out), the barrier goes back up and the cart respawns after a short delay so the next player can try.

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

# ─── shopping_cart_race_manager ───────────────────────────────────────────────
# Place this creative_device in your level, then wire up the @editable fields
# in the Details panel to the matching placed devices.
cart_race_manager := class(creative_device):

    # The shopping cart spawner placed on the track start line.
    @editable
    CartSpawner : vehicle_spawner_shopping_cart_device = vehicle_spawner_shopping_cart_device{}

    # A trigger plate the player steps on to begin the race.
    @editable
    StartTrigger : trigger_device = trigger_device{}

    # A barrier blocking the track — disabled when the race is live.
    @editable
    TrackBarrier : barrier_device = barrier_device{}

    # Localized helper — needed any time we pass text to a message param.
    RaceStartText<localizes>(S : string) : message = "{S}"

    # ── Lifecycle ────────────────────────────────────────────────────────────
    OnBegin<override>()<suspends> : void =
        # Start with the barrier UP and the cart NOT yet spawned.
        TrackBarrier.Enable()
        CartSpawner.Disable()          # cart won't auto-spawn at level load

        # Subscribe to the start trigger.  TriggeredEvent sends ?agent.
        StartTrigger.TriggeredEvent.Subscribe(OnStartTriggered)

        # React when the cart is destroyed (player wiped out or drove off map).
        CartSpawner.DestroyedEvent.Subscribe(OnCartDestroyed)

        # React when a player enters the cart.
        CartSpawner.AgentEntersVehicleEvent.Subscribe(OnDriverEntered)

        # React when a player exits the cart mid-race.
        CartSpawner.AgentExitsVehicleEvent.Subscribe(OnDriverExited)

    # ── Handlers ─────────────────────────────────────────────────────────────

    # Called when a player steps on the start plate.
    OnStartTriggered(MaybeAgent : ?agent) : void =
        if (Agent := MaybeAgent?):
            # Enable the spawner so RespawnVehicle works, then spawn the cart.
            CartSpawner.Enable()
            CartSpawner.RespawnVehicle()          # destroys any old cart, spawns fresh
            CartSpawner.AssignDriver(Agent)        # put this player in the driver seat
            TrackBarrier.Disable()                 # open the track

    # Called when the cart is destroyed (DestroyedEvent sends tuple()).
    OnCartDestroyed(Payload : tuple()) : void =
        # Close the track while we reset.
        TrackBarrier.Enable()
        # Wait 3 seconds then respawn the cart for the next attempt.
        spawn:
            DelayedRespawn()

    # Async helper — waits, then respawns.
    DelayedRespawn()<suspends> : void =
        Sleep(3.0)
        CartSpawner.RespawnVehicle()
        TrackBarrier.Disable()

    # Called when an agent actually sits in the cart.
    OnDriverEntered(Agent : agent) : void =
        # You could start a timer, grant a boost item, etc.
        # Here we simply ensure the barrier is down for the driver.
        TrackBarrier.Disable()

    # Called when the driver bails out voluntarily.
    OnDriverExited(Agent : agent) : void =
        # Close the track — player must go back to the start plate.
        TrackBarrier.Enable()
        CartSpawner.DestroyVehicle()   # clean up the abandoned cart

Line-by-line highlights:

Line / call Why it matters
CartSpawner.Disable() in OnBegin Prevents the cart from auto-spawning when the level loads — players must trigger it.
CartSpawner.Enable() before RespawnVehicle The device must be enabled for RespawnVehicle to work.
CartSpawner.RespawnVehicle() Destroys any existing cart and spawns a fresh one at the device's position.
CartSpawner.AssignDriver(Agent) Teleports Agent into the driver seat immediately.
if (Agent := MaybeAgent?) Safely unwraps the ?agent from TriggeredEvent before use.
DestroyedEvent.Subscribe(OnCartDestroyed) DestroyedEvent sends tuple() — the handler signature must match.
spawn: DelayedRespawn() Fires an async task so the 3-second wait doesn't block the event handler.
CartSpawner.DestroyVehicle() Explicitly cleans up an abandoned cart when the driver exits voluntarily.

Common patterns

Pattern 1 — Enable / Disable gating (two-cart derby)

Start both carts disabled. Enable and spawn them only when enough players are present.

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

cart_derby_gate := class(creative_device):

    @editable
    CartSpawnerA : vehicle_spawner_shopping_cart_device = vehicle_spawner_shopping_cart_device{}

    @editable
    CartSpawnerB : vehicle_spawner_shopping_cart_device = vehicle_spawner_shopping_cart_device{}

    # A trigger that fires when the host presses "Start Game".
    @editable
    StartTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        # Both carts are disabled at level load — no vehicles exist yet.
        CartSpawnerA.Disable()
        CartSpawnerB.Disable()
        StartTrigger.TriggeredEvent.Subscribe(OnGameStart)

    OnGameStart(MaybeAgent : ?agent) : void =
        # Enable both spawners, then call RespawnVehicle to materialize them.
        CartSpawnerA.Enable()
        CartSpawnerB.Enable()
        CartSpawnerA.RespawnVehicle()
        CartSpawnerB.RespawnVehicle()

Pattern 2 — React to SpawnedEvent (receive the fort_vehicle handle)

SpawnedEvent is the modern replacement for the deprecated VehicleSpawnedEvent. It sends the actual fort_vehicle object so you can store or inspect it.

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

cart_spawn_logger := class(creative_device):

    @editable
    CartSpawner : vehicle_spawner_shopping_cart_device = vehicle_spawner_shopping_cart_device{}

    @editable
    StartTrigger : trigger_device = trigger_device{}

    # Store the last spawned vehicle so we can reference it later.
    var LastCart : ?fort_vehicle = false

    OnBegin<override>()<suspends> : void =
        CartSpawner.SpawnedEvent.Subscribe(OnCartSpawned)
        StartTrigger.TriggeredEvent.Subscribe(OnStart)

    OnStart(MaybeAgent : ?agent) : void =
        CartSpawner.Enable()
        CartSpawner.RespawnVehicle()

    # SpawnedEvent sends fort_vehicle directly — no unwrap needed.
    OnCartSpawned(Vehicle : fort_vehicle) : void =
        set LastCart = option{Vehicle}
        # Vehicle handle is now stored; use it with other fort_vehicle APIs.

Pattern 3 — Detect driver exit and auto-destroy with AgentExitsVehicleEvent

Penalize players who bail out of the cart mid-race by immediately destroying the vehicle and forcing a respawn.

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

cart_bail_punisher := class(creative_device):

    @editable
    CartSpawner : vehicle_spawner_shopping_cart_device = vehicle_spawner_shopping_cart_device{}

    @editable
    StartTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        CartSpawner.AgentExitsVehicleEvent.Subscribe(OnBailOut)
        CartSpawner.AgentEntersVehicleEvent.Subscribe(OnEnterCart)
        StartTrigger.TriggeredEvent.Subscribe(OnStart)

    OnStart(MaybeAgent : ?agent) : void =
        if (Agent := MaybeAgent?):
            CartSpawner.Enable()
            CartSpawner.RespawnVehicle()
            CartSpawner.AssignDriver(Agent)

    # AgentEntersVehicleEvent sends agent directly — no ?agent unwrap.
    OnEnterCart(Agent : agent) : void =
        # Could grant a speed boost item here.
        CartSpawner.Enable()

    # AgentExitsVehicleEvent also sends agent directly.
    OnBailOut(Agent : agent) : void =
        # Destroy the cart immediately — player must restart.
        CartSpawner.DestroyVehicle()
        spawn:
            PenaltyRespawn()

    PenaltyRespawn()<suspends> : void =
        Sleep(5.0)
        CartSpawner.RespawnVehicle()

Gotchas

1. Enable before RespawnVehicle If the spawner is Disable()d, calling RespawnVehicle() has no effect — the cart simply won't appear. Always call Enable() first when you're programmatically spawning.

2. AgentEntersVehicleEvent and AgentExitsVehicleEvent send agent, not ?agent Unlike trigger_device.TriggeredEvent (which sends ?agent), these two vehicle events send a non-optional agent directly. Do not try to unwrap them with if (A := Agent?) — that pattern is only for ?agent parameters.

3. DestroyedEvent sends tuple(), not an agent The handler signature must be (Payload : tuple()) : void. You cannot get the last driver from this event alone — track that separately in AgentExitsVehicleEvent if you need it.

4. VehicleSpawnedEvent and VehicleDestroyedEvent are deprecated Prefer SpawnedEvent (which gives you the fort_vehicle handle) and DestroyedEvent. The deprecated events still compile but provide no payload.

5. AssignDriver requires the cart to exist Call AssignDriver after RespawnVehicle() has been called. If no vehicle has been spawned yet, the call is silently ignored. If you need to guarantee timing, subscribe to SpawnedEvent and call AssignDriver from that handler.

6. spawn for async work inside event handlers Event handler methods are not suspending contexts. If you need Sleep() or any <suspends> call inside a handler, wrap it in spawn: MyAsyncMethod(). Forgetting this causes a compile error about calling a suspending function from a non-suspending context.

7. Localized text for message parameters If any device you chain to (e.g., a HUD message device) takes a message parameter, you cannot pass a raw string. Declare a localizes helper: MyText<localizes>(S:string):message = "{S}" and pass MyText("your text"). There is no StringToMessage function in Verse.

Device Settings & Options

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

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

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