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 amessagefrom a string — required because UI widgets take localized text, not raw strings. There is noStringToMessage.@editable Station : service_station_deviceis the FIELD you bind to the placed device in UEFN. Without this field, you cannot call the device at all.- In
OnBeginweSubscribefour of the station's events. Each handler is a class-scope METHOD whose parameter is thefort_vehiclethe event hands us — no?agentunwrap is needed here because these events return a concretefort_vehicle. OnVehicleEnteredimmediately reads the vehicle's fuel usingGetFuelRemaining()/GetFuelCapacity()— both provenfort_vehiclecalls.OnFuelingDoneandOnRepairDoneuse the End events, which fire only once the vehicle is at full fuel / full health respectively — the perfect moment to reward the driver.WatchBayis a coroutine (spawn) that loops every second, callingIsAnyVehicleInside[]— note the square brackets because it's a<decides>query that can fail.NotifyDriverswalksGetDrivers(), resolves each driver to aplayer, grabs theirplayer_uiwithGetPlayerUI[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
IsAnyVehicleInsideis<decides>, not a boolean. Call it inside a failure context with square brackets:if (Station.IsAnyVehicleInside[]):. Calling it likeIsAnyVehicleInside()outside anifwill not compile. Negate withnot Station.IsAnyVehicleInside[].- Events return a concrete
fort_vehicle, not?agent. You do NOT need theif (A := Agent?)unwrap here — the handler parameter is already a usablefort_vehicle. The unwrap pattern applies tolistenable(?agent)events, which these are not. - You must declare the
@editablefield. Callingservice_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_blocktake amessage, so build one with a<localizes>function (pit_msg("...")). Passing a raw string fails to compile. GetFuelRemaining/GetFuelCapacityreturn -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
IsEnabledfor this device. If you're using theenableablemixin to gate the station, make sure your editor build is recent.