What you'll learn
- How to enable and control a
vehicle_mod_box_spawner_devicefrom Verse. - How to spawn mod boxes on demand (
SpawnBox,SpawnModBoxByIndex,CycleToPreviousValidIndex). - How to subscribe to the device's events (
BoxSpawnedEvent,ModAppliedEvent,ModApplyFailedEvent,BoxDestroyedEvent) and read their payloads. - How to re-apply a mod manually with
TryApplyModByVehicle, which is a<decides>call.
How it works
The device holds a list of possible mods when Possible Mods is set to Custom List. Each entry has an index starting at 0. Almost every method and event speaks in those indices — and if you're not on a custom list, the reported index is -1.
Events on this device are plain listenable fields, so you subscribe without parentheses on the event name: Device.ModAppliedEvent.Subscribe(Handler). The handler receives a tuple. For example ModAppliedEvent gives tuple(?agent, fort_vehicle, int) — the optional driver, the fort_vehicle the mod hit, and the mod index. Because the driver is an ?agent, bind it with if (Agent := OptAgent?): rather than any == nil check.
One important correctness note: TryApplyModByVehicle(Index, Vehicle) is declared <transacts><decides> — it fails as control flow. So you call it with [] inside an if condition, never as a bare statement. The events, by contrast, are subscribed with ().
Let's build it
using { /Fortnite.com/Devices }
using { /Fortnite.com/Vehicles }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Drives a vehicle mod box spawner entirely from Verse.
mod_box_controller := class(creative_device):
# Set this in the Details panel to your placed Vehicle Mod Box Spawner.
@editable
ModBoxSpawner : vehicle_mod_box_spawner_device = vehicle_mod_box_spawner_device{}
OnBegin<override>()<suspends>: void =
# Enable the device so boxes can spawn and be interacted with.
ModBoxSpawner.Enable()
# Subscribe to lifecycle events. These are listenable fields -> no () on the name.
ModBoxSpawner.BoxSpawnedEvent.Subscribe(OnBoxSpawned)
ModBoxSpawner.ModAppliedEvent.Subscribe(OnModApplied)
ModBoxSpawner.ModApplyFailedEvent.Subscribe(OnModApplyFailed)
ModBoxSpawner.BoxDestroyedEvent.Subscribe(OnBoxDestroyed)
# Kick off the first box immediately (a mod is chosen from the list).
ModBoxSpawner.SpawnBox()
# Fired whenever a box spawns; Index is the chosen mod (or -1 if not a Custom List).
OnBoxSpawned(Index : int) : void =
Print("Mod box spawned with mod index {Index}")
# Fired when a mod is successfully applied to a driven vehicle.
OnModApplied(Result : tuple(?agent, fort_vehicle, int)) : void =
Print("Mod {Result(2)} applied")
if (Driver := Result(0)?):
Print("Applied to a vehicle with a driver")
# Fired when a mod fails to apply. Re-attempt the same mod manually on that vehicle.
OnModApplyFailed(Result : tuple(?agent, fort_vehicle, int)) : void =
Vehicle := Result(1)
Index := Result(2)
Print("Mod {Index} failed; retrying manually")
# TryApplyModByVehicle is <decides> -> call with [] inside a failure context.
if (ModBoxSpawner.TryApplyModByVehicle[Index, Vehicle]):
Print("Manual re-apply succeeded")
# After a box is destroyed, cycle to the previous valid mod and respawn.
OnBoxDestroyed(Result : tuple(?agent, int)) : void =
Print("Box destroyed (mod index {Result(1)}); cycling next crate")
ModBoxSpawner.CycleToPreviousValidIndex()
ModBoxSpawner.SpawnBox()```
## Try it yourself
1. Place a **Vehicle Mod Box Spawner** and set *Possible Mods* to **Custom List** with a few mods so indices are meaningful.
2. Add this Verse device, then assign the spawner to its `ModBoxSpawner` field in the Details panel.
3. Push play, drive a supported vehicle (Sedan, Sports Car, SUV…) into the box, and watch the log fill with spawn/apply events.
4. Experiment: swap `CycleToPreviousValidIndex()` for `SpawnModBoxByIndex(0)` to always spawn the first mod, or call `SpawnLastChosenMod()` to repeat the previous roll.
## Recap
You enabled the spawner, subscribed to its `listenable` events with `.Subscribe(...)` (no parentheses on the event name), read tuple payloads including the optional `?agent` driver, and re-applied a mod with the fallible `TryApplyModByVehicle[...]`. That's the full loop: spawn a crate, react to the hit, and drive the next crate from code.