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 var array and Dispose() them at round end
  • Shuffle spawn points with Shuffle from /Verse.org/Random

Walkthrough

Step 1 β€” Set the stage in UEFN

  1. Drop a shell prop asset into your project (any small prop works β€” a conch from the Fortnite props gallery is perfect).
  2. 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.
  3. 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 lesson
Pass the quiz above to chart this quest in your Journal.

Sources

/guides/spawn-prop
Source

Biloxi Studios original lesson

Guided course

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