Reference Devices

prop_manipulator_device: Destructible Props That React to Players

Want a vault wall that crumbles when players mine it, a tree grove that restocks its loot every round, or hidden supply crates that pop into existence on cue? The prop_manipulator_device wraps one or more props in an area and lets you control their visibility, destructibility, and resource nodes — and react when players damage, destroy, harvest, or deplete them.

Updated
The code on this reference page is provided as-is and did not pass the latest compile check — treat the examples as a starting point and verify in your project.
Watch the Knotprop_manipulator_device in ~90 seconds.

Overview

The prop_manipulator_device is a controller you place over an area of props. Instead of scripting each prop individually, you point one manipulator at a region (or tag) and it governs all the props inside it at once.

It solves two related game problems:

  1. Bulk prop state — show/hide whole sets of props, restore their health, or empty/restock the resources players harvest from them (wood, stone, metal, loot).
  2. Reacting to player interaction — it fires events when affected props are damaged, destroyed, harvested, or fully depleted of resources, and each event hands you the agent responsible. That lets you award points, trigger cinematics, or respawn props.

Reach for it when you want a destructible objective (a wall players must break through), a renewable resource grove that resets each round, or a stash of props that appears only during a certain phase.

API Reference

prop_manipulator_device

Used to manipulate the properties of one or more props in a specified area (e.g. Visibility/Destructibility).

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

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

Events (subscribe a handler to react):

Event Signature Description
DamagedEvent DamagedEvent<public>:listenable(agent) Signaled when props affected by this device are damaged. Sends the agent that damaged the prop.
DestroyedEvent DestroyedEvent<public>:listenable(agent) Signaled when props affected by this device are destroyed. Sends the agent that destroyed the prop.
HarvestingEvent HarvestingEvent<public>:listenable(agent) Signaled when prop resource nodes affected by this device are harvested. Sends the agent that harvested resources from the prop.
ResourceDepletionEvent ResourceDepletionEvent<public>:listenable(agent) Signaled when prop resource nodes affected by this device are completely depleted of energy. Sends the agent that depleted the prop's energy.

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.
ShowProps ShowProps<public>():void Shows all props affected by this device.
HideProps HideProps<public>():void Hides all props affected by this device.
ExhaustResources ExhaustResources<public>():void Empties the resources of all props affected by this device.
RestockResources RestockResources<public>():void Restocks the resources of all props affected by this device.
RestoreHealth RestoreHealth<public>():void Restores health of all props affected by this device.
SetResourceOverridesActive SetResourceOverridesActive<public>():void Sets the Override Resource option to Yes.
DisableResourceNodeOverrides DisableResourceNodeOverrides<public>():void Sets the Override Resource option to No.

Walkthrough

Let's build a "Breach the Vault" scenario. A set of crates/walls inside the manipulator's area is hidden during a build phase. When the round starts we ShowProps them and RestoreHealth. As players attack, DamagedEvent tracks progress; when a prop is destroyed, DestroyedEvent awards the destroyer with a message and shows a score popup. Harvesting and depletion are also wired so a renewable grove restocks itself.

using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Colors }

vault_breach_device := class(creative_device):

    # The manipulator covering the breakable vault props.
    @editable
    VaultProps : prop_manipulator_device = prop_manipulator_device{}

    # A separate manipulator covering a renewable resource grove.
    @editable
    ResourceGrove : prop_manipulator_device = prop_manipulator_device{}

    # Tracks how many props have been destroyed this round.
    var Destroyed : int = 0

    # Localized message helper — message params need a localized value, not a raw string.
    Notify<localizes>(S:string):message = "{S}"

    OnBegin<override>()<suspends>:void =
        # Round start: reveal the vault props and make sure they are at full health.
        VaultProps.Enable()
        VaultProps.ShowProps()
        VaultProps.RestoreHealth()

        # Turn on the grove's resource overrides so our custom resource amounts apply.
        ResourceGrove.SetResourceOverridesActive()
        ResourceGrove.RestockResources()

        # React to players interacting with the vault props.
        VaultProps.DamagedEvent.Subscribe(OnVaultDamaged)
        VaultProps.DestroyedEvent.Subscribe(OnVaultDestroyed)

        # React to harvesting / depletion on the grove.
        ResourceGrove.HarvestingEvent.Subscribe(OnHarvested)
        ResourceGrove.ResourceDepletionEvent.Subscribe(OnDepleted)

    # Fired each time an affected vault prop takes damage. Agent = who dealt it.
    OnVaultDamaged(Agent : agent):void =
        if (Player := player[Agent], UI := GetPlayerUI[Player]):
            # Lightweight feedback — a damage tick acknowledgement.
            Print("A player is breaching the vault!")

    # Fired when an affected vault prop is fully destroyed.
    OnVaultDestroyed(Agent : agent):void =
        set Destroyed += 1
        if (Player := player[Agent], UI := GetPlayerUI[Player]):
            Banner := text_block{DefaultText := Notify("Vault breached! Pieces down: {Destroyed}")}
            Banner.SetTextColor(NamedColors.Yellow)
            UI.AddWidget(Banner)
        # When everything is down, restock the grove so the next phase has loot.
        if (Destroyed >= 5):
            ResourceGrove.RestockResources()

    # Fired when a player harvests resources from a grove prop.
    OnHarvested(Agent : agent):void =
        Print("Resources harvested from the grove.")

    # Fired when a grove prop's resource node is completely emptied.
    OnDepleted(Agent : agent):void =
        # Auto-renew: refill the depleted node so the grove never runs dry.
        ResourceGrove.RestockResources()

Line by line:

  • @editable VaultProps : prop_manipulator_device — you MUST declare the device as an editable field inside a class(creative_device); that field is what you wire to a placed manipulator in UEFN. A bare prop_manipulator_device.ShowProps() would fail with Unknown identifier.
  • VaultProps.Enable() / ShowProps() / RestoreHealth() — at round start we make sure the device is active, reveal the props, and reset their durability. ShowProps reveals every prop the manipulator covers in one call.
  • SetResourceOverridesActive() flips the device's Override Resource option to Yes, so the custom resource amounts configured on the device take effect; RestockResources() fills them.
  • The four .Subscribe(...) calls register METHODS of this class as handlers. Each handler receives an agent directly (these events are listenable(agent)).
  • In OnVaultDamaged, player[Agent] narrows the agent to a player, and GetPlayerUI[Player] fails gracefully if there's no UI — both are checked with if (... := ...).
  • OnVaultDestroyed increments a counter, shows a banner using a localized message (built via the Notify<localizes> helper — there is no StringToMessage), and once 5 props are down, restocks the grove.
  • OnDepleted makes the grove self-renewing by calling RestockResources() whenever a node is emptied.

Common patterns

Hide props during a build phase, then reveal them

Use HideProps/ShowProps to gate a set of props behind a game phase. Here a button reveals a hidden supply stash.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

supply_reveal_device := class(creative_device):

    @editable
    Stash : prop_manipulator_device = prop_manipulator_device{}

    @editable
    RevealButton : button_device = button_device{}

    OnBegin<override>()<suspends>:void =
        # Start with the stash props hidden (collisions off too).
        Stash.HideProps()
        RevealButton.InteractedWithEvent.Subscribe(OnReveal)

    OnReveal(Agent : agent):void =
        # Pop the stash into the world for everyone.
        Stash.ShowProps()

Empty and restock a renewable resource grove between rounds

ExhaustResources empties every node; RestockResources refills them. Pair them with a round-settings event for a fresh grove each round.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

grove_reset_device := class(creative_device):

    @editable
    Grove : prop_manipulator_device = prop_manipulator_device{}

    @editable
    NewRoundTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends>:void =
        # Make sure custom resource overrides are honored, then start full.
        Grove.SetResourceOverridesActive()
        Grove.RestockResources()
        NewRoundTrigger.TriggeredEvent.Subscribe(OnNewRound)

    OnNewRound(MaybeAgent : ?agent):void =
        # Drain everything left over, then refill for the new round.
        Grove.ExhaustResources()
        Grove.RestockResources()

Disable the manipulator and drop resource overrides

When you no longer want the device controlling its props (e.g. after an objective completes), DisableResourceNodeOverrides returns nodes to their default behavior and Disable stops the device entirely.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

manipulator_shutdown_device := class(creative_device):

    @editable
    Controlled : prop_manipulator_device = prop_manipulator_device{}

    @editable
    ObjectiveDone : trigger_device = trigger_device{}

    OnBegin<override>()<suspends>:void =
        ObjectiveDone.TriggeredEvent.Subscribe(OnObjectiveDone)

    OnObjectiveDone(MaybeAgent : ?agent):void =
        # Hand the props back to their natural resource settings...
        Controlled.DisableResourceNodeOverrides()
        # ...and stop the device from manipulating anything further.
        Controlled.Disable()

Gotchas

  • Declare the device as an @editable field. You cannot call prop_manipulator_device{}.ShowProps() on a literal — you call methods on the editable field that points at a placed device in your level.
  • HideProps disables collisions too. Hidden props won't block players or take damage. If you only want them invisible-but-solid you'll need a different approach — this device's hide is a full hide.
  • Resource overrides must be active for custom amounts to matter. RestockResources/ExhaustResources operate on the configured resource values; call SetResourceOverridesActive() first if you set custom override amounts on the device, and DisableResourceNodeOverrides() to revert.
  • The events are listenable(agent), not listenable(?agent). Handlers receive (Agent : agent) directly — no ? unwrap needed. (Contrast with trigger_device.TriggeredEvent, which IS ?agent and needs if (A := MaybeAgent?):.)
  • Narrow the agent before UI calls. DamagedEvent/DestroyedEvent can be signaled by non-player agents (e.g. AI). Use if (P := player[Agent], UI := GetPlayerUI[P]): so player-only logic fails gracefully.
  • Message params need a localized value. Pass Notify("...") from a <localizes> helper to any message parameter; a raw string won't compile, and there is no StringToMessage.
  • RestoreHealth resets destructible props. If a prop was already destroyed, restoring health on its set effectively makes the breakable props whole again — handy for round resets, surprising if called mid-fight.

Guides & scripts that use prop_manipulator_device

Step-by-step tutorials that put this object to work.

Build your own lesson with prop_manipulator_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 →