Reference Devices compiles

pinball_bumper_device: Knockback Bumpers That Score and Sting

The pinball_bumper_device is the springy obstacle that flings players away, chips their health, and racks up points — perfect for pinball arenas, bounce-pad chaos rooms, and gauntlet courses. In Verse you can listen for when a bumper goes off, turn bumpers on and off mid-match, and even fire them remotely. This article shows you exactly how, using the device's real ActivatedEvent, Enable, Disable, and Activate members.

Updated Examples verified on the live UEFN compiler
Watch the Knotpinball_bumper_device in ~90 seconds.

Overview

A pinball_bumper_device is a triggered bumper. By default it activates when a player touches it, knocking them back, optionally damaging them, and optionally awarding points. It's the building block of any pinball-style minigame — but it's just as useful for momentum gauntlets, knockback arenas, or 'don't touch the walls' challenges.

Reach for it when you want a physical reaction to a player making contact, plus a Verse hook to run game logic the moment it fires. From Verse you get four things:

  • ActivatedEvent — a listenable(agent) that fires when the bumper is hit, handing you the agent who hit it. This is where you score, count, or react.
  • Enable() / Disable() — turn the whole bumper on or off (knockback, effects, scoring — all of it).
  • Activate() — fire the bumper from code, even if nobody touched it. Great for scripted chain reactions or testing.

Because it's a placed device, you must declare it as an @editable field inside your creative_device class and assign it in the UEFN Details panel before any of these calls will work.

API Reference

pinball_bumper_device

A triggered bumper that can knock players back, damage them, and award points.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

pinball_bumper_device<public> := class<concrete><final>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
ActivatedEvent ActivatedEvent<public>:listenable(agent) Signaled when this device is activated by an agent. Sends the agent that activated this device.

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.
Activate Activate<public>():void Activates this device.

Walkthrough

Let's build a pinball survival round. Three bumpers are scattered in an arena. Each time a player hits any bumper we award a point through a score_manager_device and count total hits. When the round's hit budget is reached, we Disable() every bumper so the arena goes quiet — and we display a localized callout.

# Pinball survival: bumpers score points, then shut off when the budget runs out.
pinball_arena_device := class(creative_device):

    # Drag your three placed bumpers onto these slots in the Details panel.
    @editable
    BumperA : pinball_bumper_device = pinball_bumper_device{}

    @editable
    BumperB : pinball_bumper_device = pinball_bumper_device{}

    @editable
    BumperC : pinball_bumper_device = pinball_bumper_device{}

    # A Score Manager handles the actual point granting.
    @editable
    Scorer : score_manager_device = score_manager_device{}

    # How many total bumper hits the round allows before bumpers shut off.
    @editable
    HitBudget : int = 10

    # Running count of how many times any bumper has fired.
    var Hits : int = 0

    # Localized text helper — message params need this, NOT a raw string.
    Callout<localizes>(S : string) : message = "{S}"

    OnBegin<override>()<suspends> : void =
        # Make sure every bumper is live at round start.
        BumperA.Enable()
        BumperB.Enable()
        BumperC.Enable()

        # React to a hit on any of the three bumpers with the SAME handler.
        BumperA.ActivatedEvent.Subscribe(OnBumperHit)
        BumperB.ActivatedEvent.Subscribe(OnBumperHit)
        BumperC.ActivatedEvent.Subscribe(OnBumperHit)

    # ActivatedEvent hands us the agent who hit the bumper.
    OnBumperHit(Hitter : agent) : void =
        set Hits = Hits + 1

        # Award points to the player who hit it.
        Scorer.Activate(Hitter)

        # Once the budget is spent, kill all the bumpers.
        if (Hits >= HitBudget):
            BumperA.Disable()
            BumperB.Disable()
            BumperC.Disable()
            Print("Bumpers offline — hit budget reached.")

Line by line:

  • The three @editable pinball_bumper_device fields are how Verse reaches your placed bumpers. Without these you can't call any method — a bare pinball_bumper_device.Enable() fails with 'Unknown identifier'.
  • Scorer is a score_manager_device. The bumper itself can award points via its UEFN settings, but routing through a Score Manager from Verse gives us full control of when and to whom.
  • var Hits : int = 0 is mutable state we update with set.
  • In OnBegin, we call Enable() on each bumper so the round always starts with them active, then Subscribe the same OnBumperHit method to each bumper's ActivatedEvent. One handler, three sources.
  • OnBumperHit(Hitter : agent)ActivatedEvent is listenable(agent), so the handler receives a non-optional agent directly (no ? unwrap needed here).
  • Scorer.Activate(Hitter) grants the configured score to the player who hit the bumper.
  • When Hits reaches HitBudget, we Disable() all three bumpers and they stop knocking players or firing events.

Common patterns

Fire a bumper from code (Activate)

Use Activate() to set a bumper off without a player touching it — for a scripted chain reaction or a 'demo' showing players how it works. Here a button triggers the center bumper.

bumper_remote_fire_device := class(creative_device):

    @editable
    CenterBumper : pinball_bumper_device = pinball_bumper_device{}

    @editable
    TestButton : button_device = button_device{}

    OnBegin<override>()<suspends> : void =
        CenterBumper.Enable()
        # When the button is pressed, fire the bumper from code.
        TestButton.InteractedWithEvent.Subscribe(OnButtonPressed)

    OnButtonPressed(Agent : agent) : void =
        # Activate() sets the bumper off even with no contact.
        CenterBumper.Activate()

Temporarily disable a bumper after a hit (Enable/Disable cooldown)

Make a bumper one-shot-then-cool-down: when hit, disable it, wait a few seconds, re-enable. This uses <suspends> with Sleep.

bumper_cooldown_device := class(creative_device):

    @editable
    Bumper : pinball_bumper_device = pinball_bumper_device{}

    @editable
    CooldownSeconds : float = 3.0

    OnBegin<override>()<suspends> : void =
        Bumper.Enable()
        Bumper.ActivatedEvent.Subscribe(OnHit)

    OnHit(Hitter : agent) : void =
        # Kick off the cooldown without blocking the handler.
        spawn{ RunCooldown() }

    RunCooldown()<suspends> : void =
        Bumper.Disable()
        Sleep(CooldownSeconds)
        Bumper.Enable()

Trigger a cinematic when a bumper is hit

React to ActivatedEvent by playing a sequence — for example, a flashing light show every time the jackpot bumper fires.

bumper_cinematic_device := class(creative_device):

    @editable
    JackpotBumper : pinball_bumper_device = pinball_bumper_device{}

    @editable
    LightShow : cinematic_sequence_device = cinematic_sequence_device{}

    OnBegin<override>()<suspends> : void =
        JackpotBumper.Enable()
        JackpotBumper.ActivatedEvent.Subscribe(OnJackpot)

    OnJackpot(Hitter : agent) : void =
        # Play the light-show sequence for the player who hit it.
        LightShow.Play(Hitter)

Gotchas

  • You can't call methods on an unassigned device. The @editable field gives you a typed handle, but until you drag the actual placed bumper onto that slot in the Details panel, calls do nothing (or the field stays the default empty instance). Always assign in UEFN.
  • ActivatedEvent is listenable(agent), not listenable(?agent). Your handler receives a plain agent — no if (A := Agent?) unwrap is needed. (Compare this to timer_device.SuccessEvent, which is ?agent and does need unwrapping.)
  • Disable() stops everything, including the physical knockback and any UEFN-configured score/damage on the device — not just the Verse event. Re-Enable() to bring it back.
  • Activate() takes no agent. Unlike pinball_flipper_device.Activate(Agent) or teleporter_device.Activate(Agent), the bumper's Activate() is parameterless. Don't pass an agent to it.
  • Subscribe in OnBegin, handlers are methods. Event handlers like OnBumperHit must be methods at class scope, and you wire them up with .Subscribe(...) inside OnBegin. Subscribing elsewhere or making the handler a local function won't work.
  • message needs localization. If you display callouts (e.g. on a billboard or HUD), declare a <localizes> helper like Callout<localizes>(S:string):message = "{S}" and pass Callout("..."). There is no StringToMessage.

Device Settings & Options

The pinball_bumper_device User Options panel in the UEFN editor — every setting you can tune.

Pinball Bumper Device settings and options panel in the UEFN editor — Knockback, Fall Damage, Damage, Reset Time, Bumper Color, Score Value
Pinball Bumper Device — User Options in the UEFN editor: Knockback, Fall Damage, Damage, Reset Time, Bumper Color, Score Value
⚙️ Settings on this device (6)

Setting names read from the panel above — may be partial; the screenshots are the source of truth.

Knockback
Fall Damage
Damage
Reset Time
Bumper Color
Score Value

Build your own lesson with pinball_bumper_device

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →