Beach Buffs: Powerup Devices

In this lesson you'll learn to

  • βœ“Student can place/configure concrete powerup devices (movement-speed etc.) and Pickup/grant them from Verse when the golden shell is collected.

Student can place/configure concrete powerup devices (movement-speed etc.) and Pickup/grant them from Verse when the golden shell is collected.

πŸ“– Reference & full walkthrough: Beach Buffs: Powerup Devices

🧩 Your capstone piece: The speed-boost reward the golden shell grants its finder


What you'll learn

  • How to spawn and despawn a powerup_device from Verse instead of relying on editor triggers.
  • How to grant a buff directly to a player with Pickup(Agent) and check it with HasEffect.
  • How to read the live remaining time of a buff with GetRemainingTime.
  • How to react the moment any agent picks up the powerup off the ground via ItemPickedUpEvent.

How it works

powerup_device is the shared abstract base behind Fortnite's collectible buffs β€” Health Powerup, Damage Amplifier, and friends. Because it's abstract you place a concrete powerup in your level and reference it, but every method below works on all subclasses.

The key surface, resolved from the live digest:

Member Signature Notes
Spawn Spawn():void Places the powerup into the world so players can grab it.
Despawn Despawn():void Removes it from the world.
IsSpawned IsSpawned()<transacts><decides>:void Fallible β€” call inside if/for with [].
SetDuration SetDuration(Time:float):void Clamped to the device Min/Max; won't touch already-applied effects.
GetDuration GetDuration()<transacts>:float Returns a plain float β€” call with ().
Pickup Pickup(Agent:agent):void Grants the buff directly to that agent.
GetRemainingTime GetRemainingTime(Agent:agent)<transacts>:float -1.0 = infinite, 0.0 = agent doesn't have it.
HasEffect HasEffect(Agent:agent)<transacts><decides>:void Fallible β€” use if (Powerup.HasEffect[Agent]):.
ItemPickedUpEvent listenable(agent) Fires with the agent who picked it up.

Watch the effect specifiers: IsSpawned and HasEffect end in <decides>, so you call them with [] inside a failure context. GetRemainingTime and GetDuration return a real float, so you call them with () and read the value β€” calling them with [] would not compile.

Let's build it

We build a reward-orb objective: stepping on a finish plate spawns the powerup (if needed), stretches its duration, and grants it straight to that player. When anyone picks a powerup up off the ground, we announce who got it and how many seconds of buff remain.

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

# Drives a concrete powerup (Health / Damage Amplifier) from Verse as a reward orb.
reward_orb := class(creative_device):

    # A concrete powerup placed in the level (e.g. Health Powerup or Damage Amplifier).
    @editable
    RewardPowerup : health_powerup_device = health_powerup_device{}

    # A trigger standing in for "challenge complete".
    @editable
    FinishPlate : trigger_device = trigger_device{}

    OnBegin<override>()<suspends>: void =
        # React whenever a player steps on the finish plate.
        FinishPlate.TriggeredEvent.Subscribe(OnFinished)
        # React whenever ANY agent scoops the powerup off the ground.
        RewardPowerup.ItemPickedUpEvent.Subscribe(OnPickedUp)

    # Triggered param is ?agent, so bind it before use.
    OnFinished(MaybeAgent : ?agent): void =
        if (Agent := MaybeAgent?):
            # Make sure the orb is in the world; Spawn is fallible-free but IsSpawned decides.
            if (RewardPowerup.IsSpawned[]):
                Print("Reward orb already spawned.")
            else:
                RewardPowerup.Spawn()
            # Stretch the buff to 30s (clamped to the device's Min/Max), then read it back.
            RewardPowerup.SetDuration(30.0)
            Duration := RewardPowerup.GetDuration()  # returns float -> use ()
            Print("Reward duration set to {Duration}s.")
            # Grant the buff straight to the player who finished.
            RewardPowerup.Pickup(Agent)
            # Confirm the effect actually landed (HasEffect decides -> use []).
            if (RewardPowerup.HasEffect[Agent]):
                Print("Buff applied directly to finisher.")

    # ItemPickedUpEvent sends the agent that picked it up.
    OnPickedUp(Agent : agent): void =
        # GetRemainingTime returns a float: -1.0 infinite, 0.0 none.
        Remaining := RewardPowerup.GetRemainingTime(Agent)
        if (Remaining < 0.0):
            Print("Player grabbed the orb: infinite duration buff!")
        else:
            Print("Player grabbed the orb: {Remaining}s of buff remaining.")```

## Try it yourself

- Swap the referenced powerup between a Health Powerup and a Damage Amplifier β€” the same code drives both because they share the `powerup_device` base.
- Add a second `@editable trigger_device` that calls `RewardPowerup.Despawn()` to pull the orb out of the world when a timer expires.
- In `OnPickedUp`, iterate `GetPlayspace().GetPlayers()` and only announce for players who *don't* already have the effect using `if (not RewardPowerup.HasEffect[OtherAgent]):`.
- Use `SetDuration` with a very large value and confirm the device clamps it to its editor-defined Max via the value returned by `GetDuration()`.

## Recap

You drove a `powerup_device` entirely from Verse: `Spawn`/`IsSpawned` to place it, `SetDuration`/`GetDuration` to control its timer, `Pickup(Agent)` to grant it directly, `HasEffect`/`GetRemainingTime` to inspect a player's buff, and `ItemPickedUpEvent` to react to grabs. The one rule to remember: `<decides>` methods (`IsSpawned`, `HasEffect`) use `[]` inside a failure context, while methods that return a `float` (`GetDuration`, `GetRemainingTime`) use `()` and are read as values.
πŸ”’

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/powerup-device
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