Conjuring Shells: SpawnProp at Runtime
In this lesson you'll learn to
- βStudent can call SpawnProp with a creative_prop_asset + transform to spawn (and Dispose) props at runtime at chosen positions.
Student can call SpawnProp with a creative_prop_asset + transform to spawn (and Dispose) props at runtime at chosen positions.
π Reference & full walkthrough: Conjuring Shells: SpawnProp at Runtime
π§© Your capstone piece: Runtime-spawning the N collectible shell props at shuffled spawn points each round
Welcome back to South Shores! So far you have wired up devices that were already sitting on the sand. Today Coral teaches you the trick every treasure hunt needs: making props appear out of thin air. SpawnProp takes a creative_prop_asset (the recipe for a prop) plus a transform (the where), and stamps a live creative_prop onto the island at runtime. When the round ends, Dispose clears them off again. No spawner device required β your Verse code is the spawner.
What you will build
A shell conjurer device for the Shell Hunt capstone: each round it shuffles a set of spawn-point markers, spawns N collectible shell props at the first N markers, waits out the round, then disposes every shell so the next round starts on a clean beach. This is exactly the "runtime-spawning the N collectible shells at shuffled spawn points" piece the South Shores capstone minigame is built around.
You will learn to:
- Reference a prop asset with
@editable ShellAsset : creative_prop_asset = DefaultCreativePropAsset - Call
SpawnProp(Asset, Transform)and understand its return value:tuple(?creative_prop, spawn_prop_result) - Check spawn success by unwrapping element 0 with
if (Shell := SpawnResult(0)?) - Track spawned props in a
vararray andDispose()them at round end - Shuffle spawn points with
Shufflefrom/Verse.org/Random
Walkthrough
Step 1 β Set the stage in UEFN
- Drop a shell prop asset into your project (any small prop works β a conch from the Fortnite props gallery is perfect).
- Place a handful of small marker props along the beach where shells are allowed to appear (8-12 markers gives the shuffle room to breathe). You can hide the markers under the sand or make them invisible β we only read their transforms.
- Create a new Verse device with the code below, drag it into the level, then wire up the Details panel: the shell asset into ShellAsset, and every marker prop into the SpawnMarkers array.
Step 2 β The complete device
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Random }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
# Spawns a round of collectible shells at shuffled marker positions,
# then clears them away so the next round starts fresh.
shell_conjurer_device := class(creative_device):
# The shell prop to spawn. Drag your shell asset into this
# field in the UEFN Details panel.
@editable
ShellAsset : creative_prop_asset = DefaultCreativePropAsset
# Marker props placed on the beach. Each marker's transform
# is a possible spawn point for a shell.
@editable
SpawnMarkers : []creative_prop = array{}
# How many shells each round should conjure.
@editable
ShellsPerRound : int = 5
# How long a round lasts before the shells are cleared.
@editable
RoundSeconds : float = 20.0
# Every shell spawned this round, so we can Dispose them later.
var SpawnedShells : []creative_prop = array{}
OnBegin<override>()<suspends>:void =
loop:
SpawnRound()
Sleep(RoundSeconds)
CleanupRound()
Sleep(2.0) # a short beat between rounds
# Shuffle the markers and spawn a shell at the first ShellsPerRound.
SpawnRound():void =
Shuffled := Shuffle(SpawnMarkers)
for (Index := 0..ShellsPerRound - 1, Marker := Shuffled[Index]):
SpawnShellAt(Marker.GetTransform())
# Spawn one shell and record it if the spawn succeeded.
SpawnShellAt(SpawnTransform : transform):void =
# SpawnProp returns tuple(?creative_prop, spawn_prop_result).
SpawnResult := SpawnProp(ShellAsset, SpawnTransform)
if (Shell := SpawnResult(0)?):
# Element 0 held a real prop - the spawn worked.
set SpawnedShells += array{Shell}
Print("Shell conjured! {SpawnedShells.Length} on the beach.")
else:
# Element 0 was false - element 1 says why (see spawn_prop_result).
Print("A shell refused to appear. Check the spawn_prop_result.")
# Dispose every shell that is still on the island.
CleanupRound():void =
for (Shell : SpawnedShells, Shell.IsValid[]):
Shell.Dispose()
set SpawnedShells = array{}
Print("Beach swept clean for the next round.")
Step 3 β How the spawn call works, line by line
| Piece | What it does |
|---|---|
ShellAsset : creative_prop_asset = DefaultCreativePropAsset |
An @editable asset reference. DefaultCreativePropAsset is the safe placeholder default until you drag in a real asset. |
Shuffle(SpawnMarkers) |
From /Verse.org/Random β returns a new array with the markers in random order, so every round uses different spawn points. |
for (Index := 0..ShellsPerRound - 1, Marker := Shuffled[Index]) |
Iterates the first N shuffled markers. The failable index Shuffled[Index] quietly skips out-of-range values, so asking for 5 shells with only 3 markers spawns 3 β no crash. |
SpawnProp(ShellAsset, SpawnTransform) |
The star of the show. Returns a tuple: element 0 is ?creative_prop (the spawned prop, or false on failure), element 1 is a spawn_prop_result enum explaining the outcome. |
if (Shell := SpawnResult(0)?) |
The success check: unwrapping the option succeeds only when a prop was actually created. Inside the if, Shell is a real creative_prop. |
Shell.IsValid[] |
Succeeds only if the prop has not already been disposed (a collected shell might already be gone). |
Shell.Dispose() |
Destroys the prop and removes it from the island. |
Why the result enum matters
spawn_prop_result tells you why a spawn failed: Ok, UnknownError, InvalidSpawnPoint (NaN/Inf coordinates), SpawnPointOutOfBounds (outside the island), InvalidAsset, or TooManyProps. That last one is the big one β the island rules currently allow 100 spawned props per script device and 200 total per island. A round-based cleanup with Dispose, like ours, is how you stay comfortably under that budget.
Common patterns
Pattern 1 β Scatter spawning with the Position + Rotation overload
SpawnProp has a second overload that takes a vector3 position and a rotation instead of a whole transform. Handy when you want random scatter around a point instead of exact marker positions:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Random }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
scatter_spawner_device := class(creative_device):
@editable
ShellAsset : creative_prop_asset = DefaultCreativePropAsset
var SpawnedShells : []creative_prop = array{}
OnBegin<override>()<suspends>:void =
# Scatter 3 shells around this device's own position.
BasePosition := GetTransform().Translation
for (Count := 0..2):
SpawnScattered(BasePosition)
# Spawn a shell near a base position with random offset,
# using the Position + Rotation overload of SpawnProp.
SpawnScattered(BasePosition : vector3):void =
Offset := vector3{
X := GetRandomFloat(-150.0, 150.0),
Y := GetRandomFloat(-150.0, 150.0),
Z := 0.0
}
SpawnResult := SpawnProp(ShellAsset, BasePosition + Offset, IdentityRotation())
if (Shell := SpawnResult(0)?):
set SpawnedShells += array{Shell}
Pattern 2 β Reading the result enum for diagnostics
When spawns fail mysteriously during testing, compare element 1 against the spawn_prop_result cases:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
diagnostic_spawner_device := class(creative_device):
@editable
ShellAsset : creative_prop_asset = DefaultCreativePropAsset
OnBegin<override>()<suspends>:void =
SpawnWithDiagnostics(GetTransform())
SpawnWithDiagnostics(SpawnTransform : transform):void =
Result := SpawnProp(ShellAsset, SpawnTransform)
if (Result(1) = spawn_prop_result.Ok):
Print("Spawn OK.")
else if (Result(1) = spawn_prop_result.TooManyProps):
Print("Prop budget hit: 100 per script device, 200 per island.")
else:
Print("Spawn failed - check InvalidAsset / SpawnPointOutOfBounds.")
Where this goes next
This device is the beating heart of the Shell Hunt capstone at the end of South Shores. The capstone imports this exact spawning skill: each game round it calls the same shuffle-then-SpawnProp routine to place the collectible shells, listens for players collecting them, and reuses CleanupRound between rounds so the beach β and the island prop budget β stays clean. Nail the SpawnResult(0)? success check now, and the capstone's round loop will feel like a warm tide coming in.
Keep going β free
You've read the intro. The rest of this lesson is free for members. Sign in to continue and track your progress.
Sign in free to continue this lessonSources
/guides/spawn-propBiloxi Studios original lesson
Add this lesson to your free study plan.
π§ The Keeperβs log
Quest complete? Chart your next heading from the 𦩠South Shores (Free) expedition.
β΅ Take me there