Reference Devices

service_station_device: Automated Pit Stops for Your Vehicles

The Vehicle Service Station is a one-stop pit stop: drive a car in and it tops off the fuel and patches up the damage automatically. With its Verse API you can react to every stage of that visit — entering, fueling, repairing, exiting — and bolt your own game logic on top, like awarding points for a clean refuel or unlocking a boost reward when a vehicle leaves at full health.

Updated
Watch the Knotservice_station_device in ~90 seconds.

Overview

The service_station_device is an automated refuel-and-repair station for vehicles. Drive any fort_vehicle into its volume and the station gradually restores its fuel and its health — no extra wiring required. The device's real power for creators is its event surface: it fires a separate listenable(fort_vehicle) for every meaningful moment of the visit so you can hang game logic off them.

Reach for this device when your mode revolves around vehicles — a racing circuit with pit lanes, a survival mode where cars are precious, a delivery game where keeping your truck fueled matters. Because every event hands you the exact fort_vehicle that triggered it, you can inspect its fuel (GetFuelRemaining/GetFuelCapacity), its drivers (GetDrivers), or its passengers, and tailor rewards or feedback per vehicle.

The class also mixes in healthful, damageable, and enableable, so the station itself can be enabled/disabled and damaged like other devices. The one method unique to the station is IsAnyVehicleInside() — a <decides> query you use to ask whether the bay is currently occupied.

API Reference

service_station_device

A one stop automated refueling and repairing station for your vehicles.

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

service_station_device<public> := class<concrete><final>(creative_device_base, healthful, damageable, enableable):

Events (subscribe a handler to react):

Event Signature Description
VehicleEnteredEvent VehicleEnteredEvent<public>:listenable(fort_vehicle) Fires when a vehicle enters the service station, returns the vehicle that entered.
VehicleExitedEvent VehicleExitedEvent<public>:listenable(fort_vehicle) Fires when a vehicle leaves the service station, returns the vehicle that exited.
VehicleFuelingBeginEvent VehicleFuelingBeginEvent<public>:listenable(fort_vehicle) Fires on the first tick of a vehicle refueling, returns the refueled vehicle.
VehicleFuelingEndEvent VehicleFuelingEndEvent<public>:listenable(fort_vehicle) Fires when a vehicle is at full fuel, returns the refueled vehicle.
VehicleRepairBeginEvent VehicleRepairBeginEvent<public>:listenable(fort_vehicle) Fires when a vehicle starts repairing, returns the repaired vehicle.
VehicleRepairEndEvent VehicleRepairEndEvent<public>:listenable(fort_vehicle) Fires when a vehicle is at full health, returns the repaired vehicle.

Methods (call these to make the device act):

Method Signature Description
IsAnyVehicleInside IsAnyVehicleInside<public>()<transacts><decides>:void Check if any vehicle is inside the service station.

Walkthrough

Let's build a pit-stop scoring system for a racing map. When a vehicle enters the station we note it; when it finishes refueling AND repairing we hand the driver a UI message celebrating a completed pit stop. We also poll IsAnyVehicleInside() to drive a "bay busy" indicator.

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

# Localized text helper — message params need a localized value, not a raw string.
pit_msg<localizes>(S:string):message = "{S}"

pit_stop_manager := class(creative_device):

    # Drag your Vehicle Service Station here in the Details panel.
    @editable
    Station : service_station_device = service_station_device{}

    OnBegin<override>()<suspends>:void =
        # React to each phase of a vehicle's visit.
        Station.VehicleEnteredEvent.Subscribe(OnVehicleEntered)
        Station.VehicleFuelingEndEvent.Subscribe(OnFuelingDone)
        Station.VehicleRepairEndEvent.Subscribe(OnRepairDone)
        Station.VehicleExitedEvent.Subscribe(OnVehicleExited)

        # Keep an eye on whether the bay is occupied.
        spawn { WatchBay() }

    # Fires when a vehicle rolls into the station.
    OnVehicleEntered(Vehicle : fort_vehicle):void =
        Fuel := Vehicle.GetFuelRemaining()
        Capacity := Vehicle.GetFuelCapacity()
        Print("A vehicle entered with {Fuel}/{Capacity} fuel")
        # Greet the driver via their UI.
        NotifyDrivers(Vehicle, "Pit stop started — sit tight!")

    # Fires when the vehicle hits full fuel.
    OnFuelingDone(Vehicle : fort_vehicle):void =
        NotifyDrivers(Vehicle, "Tank full!")

    # Fires when the vehicle reaches full health.
    OnRepairDone(Vehicle : fort_vehicle):void =
        NotifyDrivers(Vehicle, "Repairs complete — you're race-ready!")

    # Fires when the vehicle drives away.
    OnVehicleExited(Vehicle : fort_vehicle):void =
        Print("Vehicle left the bay.")

    # Poll the station once a second for an occupied/empty status.
    WatchBay()<suspends>:void =
        loop:
            Sleep(1.0)
            if (Station.IsAnyVehicleInside[]):
                Print("Bay status: BUSY")
            else:
                Print("Bay status: open")

    # Push a localized message onto every driver's UI.
    NotifyDrivers(Vehicle : fort_vehicle, Text : string):void =
        for (Driver : Vehicle.GetDrivers()):
            if:
                FortChar := Driver.GetFortCharacter[]
                Agent := FortChar.GetAgent[]
                Player := player[Agent]
                UI := GetPlayerUI[Player]
            then:
                Banner := text_block{DefaultText := pit_msg(Text)}
                Screen := canvas{Slots := array{ canvas_slot{ Widget := Banner } }}
                UI.AddWidget(Screen)

Line by line:

  • pit_msg<localizes> builds a message from a string — required because UI widgets take localized text, not raw strings. There is no StringToMessage.
  • @editable Station : service_station_device is the FIELD you bind to the placed device in UEFN. Without this field, you cannot call the device at all.
  • In OnBegin we Subscribe four of the station's events. Each handler is a class-scope METHOD whose parameter is the fort_vehicle the event hands us — no ?agent unwrap is needed here because these events return a concrete fort_vehicle.
  • OnVehicleEntered immediately reads the vehicle's fuel using GetFuelRemaining()/GetFuelCapacity() — both proven fort_vehicle calls.
  • OnFuelingDone and OnRepairDone use the End events, which fire only once the vehicle is at full fuel / full health respectively — the perfect moment to reward the driver.
  • WatchBay is a coroutine (spawn) that loops every second, calling IsAnyVehicleInside[] — note the square brackets because it's a <decides> query that can fail.
  • NotifyDrivers walks GetDrivers(), resolves each driver to a player, grabs their player_ui with GetPlayerUI[Player], and adds a simple text banner.

Common patterns

Reward boost when a vehicle leaves repaired

Use the Begin and End repair events together to detect a full repair, and react on exit. Here we just confirm the vehicle finished its repair before leaving.

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

repair_tracker := class(creative_device):

    @editable
    Station : service_station_device = service_station_device{}

    # Track which vehicles have finished repairing.
    var RepairedSpeeds : float = 0.0

    OnBegin<override>()<suspends>:void =
        Station.VehicleRepairBeginEvent.Subscribe(OnRepairStart)
        Station.VehicleRepairEndEvent.Subscribe(OnRepairEnd)

    OnRepairStart(Vehicle : fort_vehicle):void =
        Print("Repair started on a vehicle at speed {Vehicle.Speed}")

    OnRepairEnd(Vehicle : fort_vehicle):void =
        # Record the vehicle's current speed as a stand-in metric.
        set RepairedSpeeds = Vehicle.Speed
        Print("Repair finished; vehicle speed now {Vehicle.Speed}")

Count occupants when fueling begins

VehicleFuelingBeginEvent fires on the first tick of refueling. Inspect who's aboard with GetPassengers().

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

fuel_logger := class(creative_device):

    @editable
    Station : service_station_device = service_station_device{}

    OnBegin<override>()<suspends>:void =
        Station.VehicleFuelingBeginEvent.Subscribe(OnFuelStart)

    OnFuelStart(Vehicle : fort_vehicle):void =
        Passengers := Vehicle.GetPassengers()
        Count := Passengers.Length
        Remaining := Vehicle.GetFuelRemaining()
        Print("Refueling started with {Count} passenger(s); fuel at {Remaining}")

Gate logic on whether the bay is free

IsAnyVehicleInside() is a <decides> query — use it inside an if with square brackets to only run logic when a vehicle is (or isn't) present.

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

bay_gate := class(creative_device):

    @editable
    Station : service_station_device = service_station_device{}

    OnBegin<override>()<suspends>:void =
        Station.VehicleExitedEvent.Subscribe(OnExit)

    OnExit(Vehicle : fort_vehicle):void =
        # Only declare the bay clear if nothing else is still inside.
        if (not Station.IsAnyVehicleInside[]):
            Print("Bay is now completely empty.")
        else:
            Print("A vehicle left, but another is still inside.")

Gotchas

  • IsAnyVehicleInside is <decides>, not a boolean. Call it inside a failure context with square brackets: if (Station.IsAnyVehicleInside[]):. Calling it like IsAnyVehicleInside() outside an if will not compile. Negate with not Station.IsAnyVehicleInside[].
  • Events return a concrete fort_vehicle, not ?agent. You do NOT need the if (A := Agent?) unwrap here — the handler parameter is already a usable fort_vehicle. The unwrap pattern applies to listenable(?agent) events, which these are not.
  • You must declare the @editable field. Calling service_station_device's methods directly without a placed-and-bound field gives 'Unknown identifier'. Drag the actual device onto the field in the Details panel.
  • UI text must be localized. AddWidget / text_block take a message, so build one with a <localizes> function (pit_msg("...")). Passing a raw string fails to compile.
  • GetFuelRemaining/GetFuelCapacity return -1.0 for non-fuel vehicles. Don't assume every vehicle uses fuel — check for the sentinel before doing fuel math.
  • Don't fight the automation. The station fuels and repairs on its own; your Verse code should react to its events rather than try to set fuel/health directly. The Begin/End event pairs let you bracket each operation.
  • The 31.30 release fixed IsEnabled for this device. If you're using the enableable mixin to gate the station, make sure your editor build is recent.

Device Settings & Options

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

Service Station Device settings and options panel in the UEFN editor — Seconds Per Restore Tick, Heal Percentage Per Restore Tick, Fuel Refill Percentage Per Restore..
Service Station Device — User Options in the UEFN editor: Seconds Per Restore Tick, Heal Percentage Per Restore Tick, Fuel Refill Percentage Per Restore..
⚙️ Settings on this device (3)

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

Seconds Per Restore Tick
Heal Percentage Per Restore Tick
Fuel Refill Percentage Per Restore..

Guides & scripts that use service_station_device

Step-by-step tutorials that put this object to work.

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