The Eye of the Storm: Building a Chaotic Storm Trap with Verse
Tutorial beginner compiles

The Eye of the Storm: Building a Chaotic Storm Trap with Verse

Updated beginner Code verified

The Eye of the Storm: Building a Chaotic Storm Trap with Verse

So, you want to make your island feel less like a static playground and more like a pressure cooker? You need a storm. But not just any storm—you need one that moves, shrinks, and forces players into a fight they can't run away from.

In this tutorial, we're going to use Verse to control the Basic Storm Controller. This isn't just about setting a timer and hoping for the best. We're going to write code that calculates a random direction and speed, then tells the storm to move there. It's the difference between a storm that sits still like a boring wall and a storm that hunts you down like a predator.

By the end, you'll have a storm that spawns, waits for a signal, and then chases players around the map with randomized chaos. No more static circles. Let's make the weather violent.

What You'll Learn

  • Variables vs. Constants: How to store data that changes (random movement) vs. data that stays fixed (storm size).
  • Functions: How to package up a set of instructions (like "start storm") so you can call them when you need them.
  • Events: How to listen for specific moments (like a button press or game start) to trigger your code.
  • Scene Graph Basics: Understanding how your code (the logic) attaches to devices (the physical objects in the world).

How It Works

Before we touch a single line of code, let's translate what we're building into Fortnite mechanics.

Imagine the Basic Storm Controller as a giant, invisible hurricane eye. Inside that eye, you're safe. Outside? You're taking damage that ignores your shield bar. It's brutal.

Normally, in the Creative UI, you set the storm size and maybe a timer. But Verse gives you superpowers. We're going to teach the storm to move.

Here is the plan:

  1. The Setup: We place a Basic Storm Controller in our world.
  2. The Trigger: We use a device (like a Button or a Timer) to send a signal to our Verse script.
  3. The Logic: When the signal hits, our script:
    • Picks a random direction (North, South, East, West, or diagonal).
    • Picks a random speed.
    • Tells the storm to shift its center to that new location.
  4. The Result: The storm circle slides across the map, forcing players to keep building or keep moving.

Key Concept: The Scene Graph

In Verse, everything exists in a hierarchy called the Scene Graph. Think of this like the hierarchy of a squad in a party game.

  • The Island is the Lobby.
  • Devices (like the Storm Controller) are the Players in the lobby.
  • Verse Scripts are the Instructions or Rules that apply to those players.

You don't just write code in a void. You attach your Verse script to a specific Device (or a Group of devices). When that device exists in the world, your code exists with it. If you delete the device, your code vanishes. It's that simple.

Variables: Your Health Bar

In programming, a Variable is a named container that holds a value that can change. Think of it like a player's Health Bar.

  • At the start, it's full (100).
  • You take damage, it changes (50).
  • You get healed, it changes again (80).

In our storm script, we'll use variables to store the storm's current X and Y coordinates, and variables to store the new target coordinates.

Constants, on the other hand, are like your Loadout. Once you pick your shotgun and pickaxe, they stay the same for that match. We'll use constants for things like the maximum distance the storm can move, so we don't accidentally make it teleport across the entire map.

Let's Build It

We are going to create a script that moves the storm when a specific event happens. We'll assume you've already placed a Basic Storm Controller in your island.

Step 1: The Script

Create a new Verse file. Let's call it StormChaser.verse.

Here is the complete code. Don't panic at the syntax; we're going to break it down line by line.

using { /Fortnite.com/Devices }
using { /Verse.org/Random }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }

# This is our script. It attaches to a device in the UEFN scene.
StormChaserScript := class(creative_device):

    # We need a reference to the storm device.
    # Think of this as "equipping" the storm in our script's inventory.
    # Drag your Basic Storm Controller into this slot in the Details Panel.
    @editable
    StormDevice : basic_storm_controller_device = basic_storm_controller_device{}

    # The maximum number of centimeters the storm center can shift per move.
    # Keeping this as a constant stops the storm from teleporting off the map.
    MaxOffset : float = 5000.0  # 5000 cm = 50 meters in Unreal units

    # OnBegin fires automatically when the game session starts.
    # <suspends> means this function is allowed to sleep/wait mid-execution.
    OnBegin<override>()<suspends> : void =
        MoveStormRandomly()

    # Packages the storm-movement logic into a reusable function.
    # Call this from OnBegin, a button event, or a loop—your choice.
    MoveStormRandomly() : void =
        # 1. Get the storm controller's current world transform,
        #    then read the translation vector as our "current position".
        CurrentTransform := StormDevice.GetTransform()
        CurrentPos := CurrentTransform.Translation

        # 2. Generate random offsets on the X and Y axes.
        #    GetRandomFloat() returns a value in [0.0, 1.0], so we
        #    remap it to [-MaxOffset, +MaxOffset] by hand.
        RawX := GetRandomFloat(0.0, 1.0)          # 0.0 … 1.0
        RawY := GetRandomFloat(0.0, 1.0)
        OffsetX := (RawX * 2.0 - 1.0) * MaxOffset   # -MaxOffset … +MaxOffset
        OffsetY := (RawY * 2.0 - 1.0) * MaxOffset

        # 3. Calculate the new target position.
        #    We keep Z unchanged so the storm stays at its original height.
        NewX := CurrentPos.X + OffsetX
        NewY := CurrentPos.Y + OffsetY
        NewZ := CurrentPos.Z

        # 4. Build the destination vector and teleport the device there.
        #    Moving the creative_device itself repositions the storm circle.
        NewPosition := vector3{X := NewX, Y := NewY, Z := NewZ}
        NewRotation := StormDevice.GetTransform().Rotation
        if (StormDevice.TeleportTo[NewPosition, NewRotation]):
            # Teleport succeeded
        # note: basic_storm_controller_device has no SetStormCircleCenter() API;
        # repositioning the device via TeleportTo is the supported approach.```

### Step 2: Breaking It Down

Let's look at the "Game Mechanics" of this code.

#### 1. The `using` Statements
```verse
using { /Engine/Engine }
using { /Fortnite.com/Devices }
using { /Verse.org/Random }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }

Game Analogy: This is like checking your Loadout before dropping. You're telling the game, "I need the basic engine tools, I need Fortnite device controls, and I need simulation tools (like randomness)." Without these, your script doesn't know what a "Storm" or a "Random Number" is.

2. The Class Definition

StormChaserScript := class(creative_device):

Game Analogy: This is creating a new Custom Device Type. You're defining a new rule set. creative_device is the base class for all placeable Verse devices in UEFN. It's like saying, "This script behaves like a standard Creative device."

3. The Storm Device Reference

@editable
StormDevice : basic_storm_controller_device = basic_storm_controller_device{}

Game Analogy: This is binding a button. You're creating a slot in your script's inventory for the Storm Controller. The @editable attribute makes this slot visible in the UEFN Details Panel. When you place this script in UEFN, you will drag and drop your actual Basic Storm Controller device into this slot. Until you do, it's an empty slot.

4. The OnBegin Event

OnBegin<override>()<suspends> : void =
    MoveStormRandomly()

Game Analogy: This is the Match Start or a Trigger Activation. OnBegin is a special event that fires when the script starts running. However, in our case, we want it to run when the storm moves.

Note: In a more complex script, we might use a button device's InteractedWithEvent to listen for a button press. For simplicity, this example shows the core logic of how to access and move the storm. In a real-world scenario, you'd likely wrap this logic in a function and call it from an OnBegin or a button-event handler.

5. Random Movement

RawX := GetRandomFloat()
OffsetX := (RawX * 2.0 - 1.0) * MaxOffset
verse
NewPosition := vector3{X := NewX, Y := NewY, Z := NewZ}
StormDevice.TeleportTo[NewPosition, StormDevice.GetTransform().Rotation]

Game Analogy: This is the Edit Mode snap. You're taking the current position, adding the random offset, and snapping the storm's center to that new coordinate. vector3 is a 3D coordinate (X, Y, Z). We preserve the original Z value because the storm moves horizontally across the map.

Step 3: Placing It in UEFN

  1. Open UEFN.
  2. Place a Basic Storm Controller device in your world.
  3. Create a new Verse script and paste the code above.
  4. In the Details Panel for the script, you will see a slot for StormDevice.
  5. Drag your Basic Storm Controller from the scene into that StormDevice slot.
  6. Now, you need to trigger it. Add a Button device.
  7. Wire the Button's Output to the Script's Input (if using Verse events) or simply set the script to run on OnBegin for testing.

Pro Tip: To make it truly reactive, you'd listen to the button device's InteractedWithEvent in Verse. Spawn an async task inside OnBegin that calls StormDevice.InteractedWithEvent.Await(), then calls MoveStormRandomly() in a loop. But the core concept remains: The script reads the storm's position, calculates a new one, and writes it back.

Try It Yourself

Challenge: The storm currently moves randomly every time the script runs. Make it more dangerous.

Hint: Instead of moving the storm randomly, make it move towards the nearest player. You'll need to:

  1. Find a way to get the list of players (hint: look up GetPlayers() in the Verse API).
  2. Calculate the distance between the storm and each player.
  3. Move the storm in the direction of the closest player.

This turns the storm from a random hazard into a predator. Good luck, and may your builds be high.

Recap

  • Variables are like health bars—they change during the game. Constants are like your loadout—they stay fixed.
  • The Scene Graph is your squad hierarchy. Scripts attach to devices, and devices exist in the world.
  • The Basic Storm Controller is a powerful tool for forcing player interaction. By using Verse, you can make it move, shrink, and hunt.
  • Randomness (GetRandomFloat) is your best friend for creating unpredictable gameplay.

References

  • https://dev.epicgames.com/documentation/en-us/fortnite/using-basic-storm-controller-devices-in-fortnite-creative
  • https://dev.epicgames.com/documentation/en-us/fortnite-creative/using-basic-storm-controller-devices-in-fortnite-creative
  • https://dev.epicgames.com/documentation/en-us/fortnite-creative/storm-wars-in-fortnite-creative
  • https://dev.epicgames.com/documentation/en-us/fortnite/storm-wars-in-fortnite-creative
  • https://dev.epicgames.com/documentation/en-us/uefn/verse-api/fortnitedotcom/devices/basic_storm_controller_device

Get the complete code — free

You've read the full walkthrough. The complete, copy-paste-ready Verse solution is free for members — sign in to unlock it.

Free with your BrainDead.TV / BrainDeadGuild Discord account. The walkthrough above is always free.

Verse source files

Turn this into a guided course

Add using-basic-storm-controller-devices-in-fortnite-creative to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.

Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in