Effects: The "Undo" Button for Your Island’s Logic
Tutorial beginner

Effects: The "Undo" Button for Your Island’s Logic

Updated beginner

Effects: The "Undo" Button for Your Island’s Logic

So you’ve written some Verse code. You’ve changed a variable, spawned an item, or dealt damage. But what happens if something goes wrong? What if a player triggers a trap that accidentally deletes the map because you forgot to check their health first?

In Verse, Effects are the safety nets, the rollback buttons, and the logic gates that keep your island from turning into a glitchy mess. They tell the engine how a piece of code behaves when things go right, and more importantly, when they go wrong. Without understanding Effects, your code might compile, but it will likely break your game in ways you didn’t intend.

What You'll Learn

  • What Effects are in Verse (and why they aren’t just particle systems).
  • The difference between no_rollback (permanent actions) and transacts (undoable actions).
  • How to use transacts to protect your island’s state using a "Time Travel" analogy.
  • How to build a simple "Revenge Trap" that cleans up after itself if it fails.

How It Works

Let’s strip away the jargon. In programming, an Effect is a tag you put on a function (a block of code that does something) to describe its behavioral consequences.

Think of Effects like the rules of engagement in Fortnite:

  1. no_rollback (The Default): This is like shooting an arrow. Once it leaves the bow, it’s gone. You can’t "un-shoot" it. In Verse, if you don’t specify an effect, your code assumes it’s permanent. If your code changes a variable or spawns an item, the engine assumes you really want that to happen, forever.
  2. transacts (The Save/Load Point): This is like reloading a checkpoint. If you perform an action marked as transacts, the engine remembers the state before the action. If the action fails (throws an error, or returns a failure result), the engine can "roll back" the changes, as if they never happened. This is crucial for things like health checks, inventory management, or complex traps where you don’t want partial states lingering.

Why Do You Care?

Imagine you’re building a trap. You want to:

  1. Check if the enemy is in the "Critical Health" zone (low HP).
  2. If yes, explode them.
  3. If no, do nothing.

If you don’t use transacts correctly, and your check fails in a weird way, you might end up with an explosion that didn’t happen, but the trap is now broken, or a variable stuck in a weird state. transacts ensures that if the "Critical Health" check fails, the game state remains exactly as it was before you even looked at the enemy’s health.

The "Failure Context"

This is the fancy term for "where you can use rollback." Only functions marked with transacts can be used in a Failure Context. A failure context is any place where your code might fail and needs to be undone. If you try to use a transacts function inside a no_rollback block, Verse will yell at you. It’s like trying to use a save point in a level that doesn’t allow saving.

Let's Build It

We’re going to build a "Regret Trap."

When a player steps on this trap, the island will try to deal damage to them. But, we want to ensure that if the damage calculation fails (for whatever reason—maybe the player is invincible, or the math goes weird), the trap doesn’t leave behind a half-executed mess. We’ll use transacts to make the damage attempt "undoable."

The Setup

  1. Place a Trigger Volume in your island.
  2. Place a Prop Mover or just use the Trigger’s output to call a Verse script.
  3. Create a new Verse script named RegretTrap.

The Code

Here is the core logic. Notice the <transacts> tag on the function signature.

# RegretTrap.verse

using { /Fortnite.com/Devices }
using { /Fortnite.com/Components/Interaction }

# This is our custom function. 
# The <transacts> tag means: "If this function fails, undo any changes it made."
# Think of it as: "Try to damage, but if you can't, pretend we never tried."
DamagePlayer(Player : Player)<transacts> : void = 
(
    # We attempt to deal damage. 
    # If this line fails (e.g., Player is invalid, or damage is blocked),
    # the entire function "rolls back" to the state before it was called.
    Player.Damage(50.0) 
)

# This is the event that runs when someone interacts with the trigger
OnInteracted(Trigger : Trigger, Player : Player) : void = 
(
    # We call our damage function. Because it has <transacts>, 
    # it’s safe to call here. If it fails, the game state is clean.
    DamagePlayer(Player)
)

Walkthrough

  1. DamagePlayer(Player : Player)<transacts> : void:

    • This defines a function named DamagePlayer.
    • It takes a Player as input.
    • <transacts>: This is the key. It tells the Verse compiler, "Hey, this function might change state, but if it fails, I want you to roll it back."
    • : void: It doesn’t return a value (like a health number); it just does something.
  2. Player.Damage(50.0):

    • This is the action. It tries to deal 50 damage.
    • If this succeeds, great. The player takes damage.
    • If this fails (e.g., the player is in a safe zone, or the function is called incorrectly), the transacts effect kicks in. The engine says, "Oh, that failed? Okay, I’ll revert any side effects from this call." Since Damage is the only thing happening, the "revert" is just... nothing happened. The player is safe.
  3. OnInteracted(...):

    • This is the event handler. When the trigger is activated, it calls DamagePlayer.
    • Because DamagePlayer is marked transacts, we can safely call it here. If the damage logic is complex and fails halfway through, the transacts effect ensures the island doesn’t get corrupted.

Why Not Just Use no_rollback?

If you removed <transacts>, the function would default to no_rollback. This means if Player.Damage threw an error after partially executing some internal logic (which is rare but possible in complex systems), the island could be left in a broken state. transacts is your insurance policy.

Try It Yourself

Challenge: Modify the RegretTrap to include a health check.

Create a new function CheckAndDamage that:

  1. Takes a Player.
  2. Checks if the player’s health is above 0 (they are alive).
  3. If alive, calls DamagePlayer (from the previous example).
  4. If not alive, does nothing.

Hint: You’ll need to use a conditional (if) inside your transacts function. Remember, if the entire function is transacts, the rollback applies to the whole block. If the player is dead, the function should just "succeed" without doing anything, leaving the game state unchanged.

Hint 2: You can access health via Player.GetHealth().

Recap

  • Effects define how a function behaves when it fails.
  • no_rollback (default) means actions are permanent.
  • transacts means actions can be undone (rolled back) if the function fails.
  • Use transacts for critical logic like damage, inventory changes, or state updates where you don’t want partial failures corrupting your island.

References

  • https://dev.epicgames.com/documentation/en-us/uefn/verse-glossary
  • https://dev.epicgames.com/documentation/fortnite/verse-glossary
  • https://dev.epicgames.com/documentation/fortnite/verse-api/fortnitedotcom/itemization/fort_item_pickup_interactable_component/oninteractionsucceeded
  • https://dev.epicgames.com/documentation/fortnite/verse-api/fortnitedotcom/devices/service_station_device/damage
  • https://dev.epicgames.com/documentation/fortnite/verse-api/fortnitedotcom/devices/roly_poly/damage

Verse source files

Turn this into a guided course

Add Effects 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