Overview
prop_spawner_base_device is the abstract base class for devices that spawn a configured prop object into your world at runtime. You don't place this exact class — you place a concrete prop spawner in UEFN, configure which prop it spawns in the Details panel, then reference it from Verse and call its methods.
The game problem it solves: you want props to appear or disappear on cue rather than always being present. Think of a destructible barricade that materializes when defenders press a button, a supply crate that pops in when a wave begins, or a pile of decorative debris you sweep away when the round resets. Because the spawner already knows what prop to spawn (you set that in the editor), your Verse code only has to decide when.
The API is intentionally small:
SpawnObject()— spawn one instance of the configured prop.DestroyAllSpawnedObjects()— remove every prop this device has spawned.Enable()/Disable()— turn the device on or off so it does (or ignores) spawn requests.
Reach for this device whenever the prop and its placement are fixed but the timing is dynamic. (If you need fully procedural placement at arbitrary coordinates, the free-function SpawnProp() is the lower-level alternative — but the spawner device is far simpler for fixed setups.)
API Reference
prop_spawner_base_device
Base class for devices that spawn a prop object.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
prop_spawner_base_device<public> := class<abstract><epic_internal>(creative_device_base):
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. |
SpawnObject |
SpawnObject<public>():void |
Spawns the prop associated with this device. |
DestroyAllSpawnedObjects |
DestroyAllSpawnedObjects<public>():void |
Destroys all props spawned from this device. |
Walkthrough
Let's build a barricade station. A button spawns a defensive prop, and a second button clears every prop the station has produced. We'll also disable the spawn button briefly after each spawn so players can't spam it.
Because prop_spawner_base_device is abstract, you place a concrete prop spawner in your level and configure its prop. In Verse we declare the field with the base type so the methods are available; UEFN lets you bind a concrete spawner to a base-typed editable field.
barricade_station_device := class(creative_device):
# Bound in the Details panel to the prop spawner you placed.
@editable
Spawner : prop_spawner_base_device = prop_spawner_base_device{}
# Button players press to drop a new barricade prop.
@editable
SpawnButton : button_device = button_device{}
# Button that wipes all props this station spawned.
@editable
ClearButton : button_device = button_device{}
OnBegin<override>()<suspends>:void =
# Make sure the spawner is active when the round starts.
Spawner.Enable()
# Wire each button to its handler.
SpawnButton.InteractedWithEvent.Subscribe(OnSpawnPressed)
ClearButton.InteractedWithEvent.Subscribe(OnClearPressed)
# Runs when a player presses the spawn button.
OnSpawnPressed(Agent : agent):void =
# Spawn one configured prop.
Spawner.SpawnObject()
# Briefly lock the spawner so it can't be spammed, then re-enable.
spawn{ CooldownThenEnable() }
# Runs when a player presses the clear button.
OnClearPressed(Agent : agent):void =
# Remove every prop this station has spawned.
Spawner.DestroyAllSpawnedObjects()
# Disable the spawner for 2 seconds, then turn it back on.
CooldownThenEnable()<suspends>:void =
Spawner.Disable()
Sleep(2.0)
Spawner.Enable()
Line by line:
@editable Spawner : prop_spawner_base_device— the field that points at the placed spawner. The@editablemakes it bindable in the Details panel; without it, you'd get an Unknown identifier error trying to call the device.OnBeginis the entry point. We callSpawner.Enable()first so the device is guaranteed active at round start.SpawnButton.InteractedWithEvent.Subscribe(OnSpawnPressed)registers a class method as the handler. The button's interaction event hands the handler theagentwho pressed it.- In
OnSpawnPressedwe callSpawner.SpawnObject()— this is the core call that drops one prop. We thenspawn{ }a concurrent cooldown task so the handler returns immediately. OnClearPressedcallsSpawner.DestroyAllSpawnedObjects()to wipe everything the spawner has produced — perfect for a reset button.CooldownThenEnableis a<suspends>function: it disables the spawner,Sleeps 2 seconds, then re-enables. Running it insidespawn{ }keeps the button responsive.
Common patterns
Auto-stock a wave of props on a timer
Use a loop with Sleep to spawn a fresh prop at intervals — a slow trickle of supply crates, for example.
supply_trickle_device := class(creative_device):
@editable
Spawner : prop_spawner_base_device = prop_spawner_base_device{}
OnBegin<override>()<suspends>:void =
Spawner.Enable()
loop:
# Drop one configured prop every 10 seconds.
Spawner.SpawnObject()
Sleep(10.0)
Round reset: clear everything, then disable
Wipe the field and stop the spawner so nothing spawns between rounds.
round_reset_device := class(creative_device):
@editable
Spawner : prop_spawner_base_device = prop_spawner_base_device{}
@editable
ResetButton : button_device = button_device{}
OnBegin<override>()<suspends>:void =
ResetButton.InteractedWithEvent.Subscribe(OnReset)
OnReset(Agent : agent):void =
# Remove all spawned props and shut the spawner off.
Spawner.DestroyAllSpawnedObjects()
Spawner.Disable()
Toggle the spawner with a single button
Flip the device on and off using a tracked state variable.
spawner_toggle_device := class(creative_device):
@editable
Spawner : prop_spawner_base_device = prop_spawner_base_device{}
@editable
ToggleButton : button_device = button_device{}
var IsOn : logic = true
OnBegin<override>()<suspends>:void =
Spawner.Enable()
ToggleButton.InteractedWithEvent.Subscribe(OnToggle)
OnToggle(Agent : agent):void =
if (IsOn?):
Spawner.Disable()
set IsOn = false
else:
Spawner.Enable()
set IsOn = true
Gotchas
- The class is abstract. You cannot place a raw
prop_spawner_base_devicein the level. Place a concrete prop spawner, configure its prop in the Details panel, and bind it to your base-typed@editablefield. The Verse field type can stay as the base class so all four methods are available. - No events on this device. Unlike triggers or buttons,
prop_spawner_base_deviceexposes no listenable events — you only call into it. To react to when a prop should spawn, drive it from another device's event (a button'sInteractedWithEvent, a trigger, a timer) as shown above. SpawnObject()spawns the configured prop only. It does not let you choose a prop or a position from Verse — those come from the device's editor configuration. If you need arbitrary props at arbitrary coordinates, use the lower-level free functionSpawnProp(Asset, Position, Rotation)instead.DestroyAllSpawnedObjects()is all-or-nothing. It removes every prop this specific device produced — you can't selectively destroy one. If you need fine-grained control, spawn props yourself withSpawnPropand keep handles.Disable()stops future spawns but does not remove existing props. Disabling and clearing are separate concerns — call both if you want a clean, inert field (see the round-reset pattern).- Subscribe in
OnBegin. Event handlers likeOnSpawnPressedare ordinary class methods; you must register them with.Subscribe(...)insideOnBegin, not at field-declaration time. - Long-running calls need
<suspends>. Anything thatSleeps (cooldowns, timed loops) must be in a<suspends>function. Call it fromOnBegindirectly, or fire it concurrently withspawn{ }from a non-suspending event handler.