Welcome to your UEFN adventure! In this learning path, you'll discover how to build a complete playable island in Fortnite using Verse, a powerful scripting language. From spawning players to tracking scores and deciding who wins, you'll learn the core skills that make games fun and fairโall by writing code that brings your creative vision to life!
Imagine you're building a Fortnite island with devices โ things like triggers, timers, and item granters. Devices are awesome! But they only connect in certain ways. It's like a box of LEGO bricks where every brick has a fixed shape. You can build a lot, but some cool ideas just don't fit.
Verse is Epic Games' special programming language for Fortnite islands (and will also power Unreal Engine 6 โ the future of game-making!). Think of Verse as a magic set of LEGO instructions that lets you invent your own brick shapes. If no device can do what you want, you write Verse code to make it happen yourself.
๐ก Programming language โ a way to give the computer a list of instructions it can follow, like a recipe for a game.
UEFN stands for Unreal Editor for Fortnite. It's the free app you use to build custom Fortnite islands on your computer. Think of it as your game-building workshop. You place devices, design the map, and write Verse code โ all in one place.
Here's a quick list of super-powers Verse gives you:
A Verse device is a special object you make with code. Once you build it, it shows up in your Content Browser just like any other Fortnite device. You drag it onto your island, hit Launch Session, and your code runs when players start the game!
Think of it like baking a cake ๐:
| Word | What it means |
|---|---|
| Verse | Epic's programming language for Fortnite islands |
| UEFN | The app (Unreal Editor for Fortnite) where you build islands |
| Device | A pre-built game object you can place on your island |
| Verse device | A custom device you build with Verse code |
| Compile | Turning your code into something the game can run (like baking the recipe) |
| Playtest | Running your island to test it, like a rehearsal |
Follow these steps inside UEFN:
welcome_device.โ Great job โ you just created your first Verse file! Give yourself a high-five. ๐
Before you can use your device in the game, you have to compile it. Compiling means the editor reads your code and turns it into something the game understands.
Your code is now running on your island. ๐
When UEFN creates a new Verse Device, it gives you a starter template. Here's what that code looks like, with friendly explanations for every line:
# This line says: "Use the UEFN game tools in this file."
using { /fortnite.com/devices }
# This line says: "Use general Verse tools (math, text, etc.)."
using { /verse.org/simulation }
# Here we DEFINE our device.
# "my_device" is its name. "creative_device" means it works as a Fortnite island device.
my_device := class(creative_device):
# OnBegin is a special function that runs ONCE when the game starts.
# Think of it like the starting pistol at a race โ BANG, code goes!
OnBegin<override>()<suspends>:void=
# This line prints a message to the game log.
# It's how you check "did my code run?"
Print("Hello, island! My first device is working!")
| Line | What's happening |
|---|---|
using { /fortnite.com/devices } |
Loads all the Fortnite device tools we need |
using { /verse.org/simulation } |
Loads core Verse tools |
my_device := class(creative_device): |
Creates our new device type and names it my_device |
OnBegin<override>()<suspends>:void= |
This is a function โ a named set of instructions. OnBegin runs at the very start of the game. |
Print("Hello, island! ...") |
Shows a message in the log so you know the code ran |
๐ฏ Function โ a named set of instructions. Like a move in a dance routine: "do the spin" means the same steps every time you say it.
๐ฏ OnBegin โ a special built-in function in UEFN that fires once when the round starts. Every Verse device has one.
After you compile and drag this device onto your island, launch a session. Check the Output Log (Window > Output Log in UEFN) and you'll see your message pop up when the game starts! ๐
You've seen the starter code. Now make it your own!
Your mission:
welcome_device Verse file in Visual Studio Code.Print(...) to say something about your island. For example:
"Welcome to my awesome ninja course!""Get ready โ this island is going to be wild!"๐ Bonus challenge: Can you add a second Print(...) line right below the first one with a different message? Try it!
๐ก Hint: Each
" "quote marks.
๐ค Stuck? Check that your quotes are straight (
") not curly (""), and that each line insideOnBeginstarts with the same spacing (indentation) as the example.
Verse is Epic Games' programming language that lets you create custom rules and devices for your Fortnite island โ things no normal device can do on its own. You use UEFN (Unreal Editor for Fortnite) to write Verse code, compile it (bake it!), and drag your new device into your level. Every Verse device has an OnBegin function that runs your code the moment the game starts. You're officially a Verse coder now โ keep building! ๐
Imagine your island is a party. ๐ Every time a friend walks through the door, you want to say "Hey, welcome!" And when someone leaves, you want to say "See you later!"
In Verse, you can do exactly that โ with something called events.
An event is something that happens during the game that your code can listen for and react to.
Think of it like a doorbell. ๐
Two super important events in UEFN are:
| Event | When it fires |
|---|---|
PlayerAddedEvent |
A player joins your island |
PlayerRemovedEvent |
A player leaves your island |
These come from the game session โ think of the game session as the referee who keeps track of everyone playing.
In Verse, every person playing your game is a player โ that's the word Verse uses for a real human in the game.
When an event fires, Verse hands your code that player like a backstage pass ๐ชช. You can use it to do things to or for that specific person.
GetPlayspace?Your island in UEFN has a playspace. A playspace is like the stage where the whole game happens. It knows about every player on the island.
You call GetPlayspace() to get access to that stage. Once you have it, you can subscribe to (meaning: start listening to) the join and leave events.
Subscribing to an event means telling Verse: "Hey, when this thing happens, please run my function."
It's like signing up for text alerts. ๐ฑ Once you subscribe, every time the event fires, your function automatically runs!
In a UEFN Verse device, there is a special function called OnBegin. It runs once, right when the game starts โ like pressing the START button.
This is the perfect place to subscribe to events, because you want to start listening right away!
player_spawner_device?A Player Spawner is a device you place on your island in UEFN. It marks a spot where players appear when they join. Think of it like a respawn pad. ๐ข
You can reference it in your Verse script using player_spawner_device. But for basic joining/leaving detection, the events do all the heavy lifting โ the spawner just controls where players pop in.
Here's the big picture of what your script will do:
OnBegin runs.That's it! You're writing code that reacts to real players in real time. How cool is that? ๐
Let's build a simple script. It will say hello when someone joins and goodbye when someone leaves.
Step 1 โ In UEFN, create a new Verse device file called player_greeter. Add a Player Spawner device to your island and place it somewhere flat.
Step 2 โ Here is the full Verse code:
# This tells Verse we are making a device (like a prop that has code inside it).
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# We define our device โ think of it like a recipe card for our gadget.
player_greeter := class(creative_device):
# OnBegin runs once when the game starts โ like pressing START.
OnBegin<override>()<suspends> : void =
# GetPlayspace() gives us access to the whole game stage.
Playspace := GetPlayspace()
# Subscribe means "hey, call my function when this event fires."
# PlayerAddedEvent fires every time a new player joins.
Playspace.PlayerAddedEvent().Subscribe(OnPlayerJoined)
# PlayerRemovedEvent fires every time a player leaves.
Playspace.PlayerRemovedEvent().Subscribe(OnPlayerLeft)
# This function runs automatically when a player JOINS.
# Verse passes us the player who just joined โ we call them NewPlayer.
OnPlayerJoined(NewPlayer : player) : void =
# Print sends a message to the Output Log so you can see it.
Print("A new player just joined the island! ๐")
# This function runs automatically when a player LEAVES.
# Verse passes us the player who just left โ we call them LeavingPlayer.
OnPlayerLeft(LeavingPlayer : player) : void =
Print("A player left the island. ๐ See you next time!")
| What the code says | What it means in plain English |
|---|---|
using { /Fortnite.com/Devices } |
"I want to use UEFN devices in my script." |
player_greeter := class(creative_device) |
"My gadget is a creative device โ it lives on the island." |
OnBegin<override>()<suspends> : void |
"This runs once at the start of the game." |
GetPlayspace() |
"Give me the game stage so I can listen to events." |
PlayerAddedEvent().Subscribe(OnPlayerJoined) |
"Every time someone joins, call my OnPlayerJoined function." |
PlayerRemovedEvent().Subscribe(OnPlayerLeft) |
"Every time someone leaves, call my OnPlayerLeft function." |
OnPlayerJoined(NewPlayer : player) : void |
"This is my welcome function. It receives the player who joined." |
Print(...) |
"Show this message in the Output Log." |
player_greeter device onto the island.๐ก Pro Tip: In a real multiplayer session, every player who joins will trigger
OnPlayerJoined. Each player is handled separately โ Verse keeps track of them one by one!
You just learned how to detect players joining and leaving. Now level it up!
Your Challenge:
Right now the script prints the same message for every player. Your job is to count how many players are on the island and print the count each time someone joins.
Here are some hints to guide you:
Hint 1: You need a variable to keep track of the count. Remember โ a variable is something that changes during the game. In Verse, you can write a mutable (changeable) variable like this inside your class:
var PlayerCount : int = 0
int means a whole number (like 1, 2, 3).
Hint 2: Inside OnPlayerJoined, you can increase the count by 1 like this:
set PlayerCount += 1
Hint 3: You can print the count inside a message. Try building a string with ToString():
Print("Players on island: {PlayerCount}")
Hint 4: Don't forget โ when a player leaves, you should decrease the count by 1 too! Use set PlayerCount -= 1 inside OnPlayerLeft.
Bonus Challenge ๐: Can you also print a special message when PlayerCount reaches 3? (Hint: use an if statement โ if (PlayerCount = 3):)
Give it a try! You've got everything you need. You're doing amazing! ๐ช
Today you learned that events are like doorbells โ they fire when something happens, and your code reacts. You used PlayerAddedEvent and PlayerRemovedEvent to detect players joining and leaving your island. You put your setup code inside OnBegin so it runs the moment the game starts. Now your island can actually know when players arrive and say goodbye โ that's the foundation of almost every multiplayer game! ๐ฎ
Imagine you are playing a Fall Guys obstacle course. Every time you finish a checkpoint, your score goes up. How does the game remember your score? That is exactly what we are going to learn today!
A variable is like a scoreboard in a gym. It holds a number (or other information), and that number can change while the game is running.
Think of it like this: imagine a whiteboard that says "Player Score: 0". When you tag a checkpoint, someone erases the 0 and writes 10. Then 20. That whiteboard is your variable!
PlayerScore).๐ก Variable = a named box that holds information and can be updated while the game runs.
A constant is like a painted wall in your island. You pick the color before the game starts, and it never changes during the game. Constants are set once and stay the same forever.
For example, the number of points each checkpoint gives you might always be 10. That never changes, so it can be a constant!
๐ก Constant = a named box whose value is locked and never changes.
Here is the plan for our mini-game:
This is like a scoreboard that automatically updates every time something exciting happens in your game.
| Device | What It Does |
|---|---|
| Trigger Device | Fires an event when a player walks into it |
| HUD Message Device | Shows a message (like a score) on screen |
Both of these devices exist in UEFN's Creative device list. Place them on your island before writing code!
In Verse, we can reference (point to) a device we placed on our island. Think of it like naming a toy in your room. Once it has a name in your code, you can tell it what to do!
We use a special tag called @editable to connect a device in our code to a real device on the island. It is like labeling a box so you know exactly which toy is inside.
Here is a complete Verse script. Read the comments (the lines starting with #) โ they explain every important line!
# We are creating a new "game manager" that runs on our island.
# Think of it like the referee of our Fall Guys game!
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
score_tracker := class(creative_device):
# @editable means we can connect this to a REAL device on our island.
# This is our Trigger device โ the "checkpoint" the player walks through.
@editable
CheckpointTrigger : trigger_device = trigger_device{}
# @editable connects to our HUD Message device so we can show the score.
@editable
ScoreDisplay : hud_message_device = hud_message_device{}
# This is our VARIABLE. It starts at 0 and will go UP as players score.
# "var" means it can change โ just like our scoreboard whiteboard!
var PlayerScore : int = 0
# This is a CONSTANT. It is always 10 โ the points per checkpoint.
# "PointsPerCheckpoint" never changes during the game.
PointsPerCheckpoint : int = 10
# OnBegin runs automatically when the island starts โ like pressing Play!
OnBegin<override>()<suspends> : void =
# We tell the trigger: "When someone walks in, call AddPoints."
# This is called SUBSCRIBING to an event.
CheckpointTrigger.TriggeredEvent.Subscribe(OnCheckpointTriggered)
# This function runs every time the trigger fires.
# A FUNCTION is a set of instructions with a name โ like a recipe step.
OnCheckpointTriggered(TriggeringAgent : ?agent) : void =
# Add PointsPerCheckpoint to our PlayerScore variable.
# "set" is how we UPDATE a variable in Verse.
set PlayerScore = PlayerScore + PointsPerCheckpoint
# Show a message on screen so the player sees their new score.
ScoreDisplay.Show()
# Print to the output log so we can debug (check) our work.
Print("Score is now: {PlayerScore}")
Step 1 โ Set up devices on your island:
Step 2 โ Create the Verse file:
Step 3 โ Connect the devices:
score_tracker actor in the Outliner.CheckpointTrigger and ScoreDisplay.CheckpointTrigger and your HUD Message device into ScoreDisplay.Step 4 โ Play and test!
โ You did it! Every time you walk through the trigger,
PlayerScoregrows. The variable is doing its job โ remembering and updating the score!
You have the basic score tracker working. Now let's make it more exciting!
Your challenge: Add a second trigger that gives the player 25 points instead of 10 โ like a special bonus checkpoint!
Here is what you need to do:
@editable variable in your Verse class to reference this new trigger. You could call it BonusTrigger.TriggeredEvent inside OnBegin, just like you did for the first trigger.OnBonusTriggered that adds 25 points to PlayerScore and calls ScoreDisplay.Show().๐ก Hint: Your new function will look almost exactly like
OnCheckpointTriggered. The only things that change are the function name and the number of points added! Try using a new constant calledBonusPoints : int = 25.
๐ Bonus challenge: Can you make the score reset back to 0 if the player falls off the map? Think about where you might add
set PlayerScore = 0in your code!
Today you built a real score tracking system for a Fortnite island! You learned that a variable is like a scoreboard that updates during the game, while a constant is a locked-in value that never changes. You used a Trigger device to fire events and Verse code to listen for those events and add points. Now every time a player hits your checkpoint, the score goes up โ and your island feels like a real game! Keep building! ๐ฎ
Imagine you are playing a racing board game. After each lap, you write down who finished first, second, and third. Then the next lap starts โ and whoever won gets to start ahead of everyone else. That's round logic!
In Fortnite islands, rounds work the same way. The game needs to remember:
We use Verse code to track all of this โ and that's exactly what this lesson is about! ๐
A class is like a lunchbox. It holds several pieces of information together in one neat container. For example, a player_circuit_info class (circuit = racing track) holds:
Persistable means the data sticks around between rounds โ like writing something in permanent marker instead of dry-erase marker. If something is not persistable, it gets erased when a new round starts.
We use <persistable> to tell Verse: "Don't erase this data when the round resets!"
A weak_map is like a hall of lockers at school. Each locker belongs to one player. Inside the locker you store that player's info. When you need to check someone's round info, you look up their locker.
In Verse, a weak_map(player, player_circuit_info) maps (connects) every player to their own player_circuit_info lunchbox.
-1 Mean?When a player first joins, they haven't finished any round yet. We set their finish order and round number to -1 as a placeholder โ like an empty locker. It means "no real data yet." When the player finishes a round, we replace -1 with a real number.
A constructor is a helper function that builds a new copy of a class. Think of it like a photocopier for lunchboxes โ it copies all the contents, and you can swap out just one item before sealing the new copy. This is handy when you want to update only one field (like finish order) without losing everything else.
Here is the big picture, step by step:
RecordPlayerFinishOrder to save each player's place in their locker.In Verse and Unreal Engine, everything on your island is part of a scene graph โ a giant family tree of objects. Each device (like a Trigger or a Checkpoint) is a node (a dot on the tree). When you attach a script to a device, that script becomes a component of that node.
Your round-logic script sits at the top of this tree โ it watches over ALL the checkpoints and players like a game referee. When a player hits a checkpoint (a child node), it reports up to your script (the parent node), which updates the player's locker in the weak map. This parent-child flow is the scene graph in action! ๐ฒ
Here is a complete, real Verse script you can use in UEFN. Read the comments (lines starting with #) โ they explain every important line!
# This file goes on a Verse device in your UEFN project.
# It tracks which round each player finished, and in what order.
using { /Fortnite.com/Game }
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# -------------------------------------------------------
# STEP 1: Define our "lunchbox" class.
# <persistable> means this data survives between rounds.
# <final> means nobody can remix this class into a new one.
# -------------------------------------------------------
player_circuit_info<public> := class<final><persistable>:
Version : int = 0 # helps manage saved data versions
LastRoundFinishOrder<public> : int = -1 # -1 = "not set yet"
LastCompletedRound<public> : int = -1 # -1 = "not set yet"
# -------------------------------------------------------
# STEP 2: A constructor โ our "photocopier for lunchboxes."
# It copies an old player_circuit_info so we can change just one field.
# <transacts> means: if something goes wrong, undo all changes safely.
# -------------------------------------------------------
MakePlayerCircuitInfo<constructor>(Old : player_circuit_info)<transacts> := player_circuit_info:
Version := Old.Version # copy the version
LastRoundFinishOrder := Old.LastRoundFinishOrder # copy the finish order
LastCompletedRound := Old.LastCompletedRound # copy the round number
# -------------------------------------------------------
# STEP 3: Our main round-manager device class.
# -------------------------------------------------------
round_manager<public> := class(creative_device):
# The hall of lockers โ one locker per player.
# weak_map means: if a player leaves, their locker is automatically cleaned up.
var CircuitInfo<public> : weak_map(player, player_circuit_info) = map{}
# How many rounds total in this game session?
TotalRounds<public> : int = 3
# Which round are we on right now? Starts at 1.
var CurrentRound<public> : int = 1
# ---------------------------------------------------
# STEP 4: Record a player's finish position for this round.
# Agent = the player who crossed the finish line.
# FinishOrder = 1 for 1st place, 2 for 2nd place, etc.
# <decides> means this function can "fail" safely if the player isn't found.
# ---------------------------------------------------
RecordPlayerFinishOrder<public>(Agent : agent, FinishOrder : int)<decides><transacts> : void =
# Try to get the player from the agent โ agents include NPCs, players share this type
Player := player[Agent]
# Make sure the player is still in the game (not disconnected)
Player.IsActive[]
# Look up the player's existing lunchbox, or make a fresh empty one
PlayerCircuitInfo : player_circuit_info =
if (Info := CircuitInfo[Player]):
Info # player already has a lunchbox โ use it
else:
player_circuit_info{} # brand new empty lunchbox
# Use the photocopier (constructor) to make a new lunchbox
# but swap in the new FinishOrder value
UpdatedInfo := MakePlayerCircuitInfo(PlayerCircuitInfo)
set CircuitInfo[Player] = player_circuit_info:
Version := UpdatedInfo.Version
LastRoundFinishOrder := FinishOrder # update ONLY the finish order
LastCompletedRound := CurrentRound # also record which round this was
# ---------------------------------------------------
# STEP 5: Move to the next round, or end the game.
# ---------------------------------------------------
AdvanceRound<public>() : void =
if (CurrentRound < TotalRounds):
set CurrentRound = CurrentRound + 1 # go to the next round
Print("Starting round {CurrentRound}!")
else:
Print("All rounds done! Game over!")
# Here you would trigger your end-game logic
# ---------------------------------------------------
# STEP 6: Reset a player's round info (e.g., when they leave or game ends).
# ---------------------------------------------------
ResetPlayerInfo<public>(Agent : agent)<decides><transacts> : void =
Player := player[Agent]
Player.IsActive[]
# Overwrite their locker with a fresh, empty lunchbox
set CircuitInfo[Player] = player_circuit_info{}```
---
### ๐ Walkthrough
| Step | What it does | Real-world analogy |
|---|---|---|
| `player_circuit_info` class | Defines the lunchbox shape | Designing what goes in a locker |
| `weak_map` | Hall of lockers, one per player | Each student has their own locker |
| `MakePlayerCircuitInfo` constructor | Photocopies the lunchbox with one change | Update one item without emptying everything |
| `RecordPlayerFinishOrder` | Saves a player's place at race end | Writing their finish time on a scorecard |
| `AdvanceRound` | Moves the game to the next round | Flipping to the next page of the scorebook |
| `ResetPlayerInfo` | Clears a player's data | Emptying and cleaning their locker |
Now it's time to build something you can actually play! Follow these steps:
A simple 2-round race where:
In UEFN, create a new island and place 2 Checkpoint devices and 1 End Zone device on a simple track.
Add a Verse device to your island and paste the round_manager code from the worked example above.
Wire up the End Zone โ when a player enters it, call RecordPlayerFinishOrder with that player and the current finish count (1st person in = order 1, 2nd person = order 2, etc.).
After all players finish, call AdvanceRound() to move to round 2.
Set TotalRounds to 2 in your device settings.
Play your island! Watch the Print messages appear in the top-left of your screen.
Can you add a Print statement inside RecordPlayerFinishOrder that says:
"Player finished in place [FinishOrder] during round [CurrentRound]!"
Hint: In Verse, you print text like this:
Print("Player finished in place {FinishOrder} during round {CurrentRound}!")
Place it right after the set CircuitInfo[Player] = ... line. You've got this! ๐ช
You built a real round management system for a Fortnite race island! You learned that a weak_map is like a hall of lockers โ one per player โ and a persistable class keeps data safe between rounds, like writing in permanent marker. A constructor lets you update just one field without losing all the other data, like swapping one item in a lunchbox. Put it all together and you have a system that tracks finish order, advances rounds, and resets player data โ the backbone of any great multi-round Fortnite experience! ๐๐
Every game has a moment when someone wins. In checkers, you win when you take all your opponent's pieces. In a race, you win when you cross the finish line first.
In Fortnite, your island needs the same thing โ a rule that says "You did it! Game over!"
That rule is called a win condition. It's just an if-then idea:
If something happens enough times โ then end the game and celebrate the winner!
Think of building this like a LEGO set. We need three pieces:
| Piece | What It Does |
|---|---|
| EliminatedEvent | Tells our code every time a player is eliminated |
| A counter (variable) | Keeps score โ it counts up each elimination |
| End Game Device | The magic button that actually ends the round |
A variable is like a scoreboard that changes during the game.
Imagine a whiteboard in gym class. You erase the old score and write a new one every time a team scores. That whiteboard is a variable โ it changes!
In Verse, we write var in front of a variable name to say "hey, this number is allowed to change."
var EliminationCount : int = 0 # starts at zero, like a fresh scoreboard
int just means the value is a whole number (like 0, 1, 2, 3 โ not 1.5).
Imagine you sign up for text alerts from a pizza place. Every time a new deal drops, you get a message automatically โ you don't have to keep checking!
Subscribing to an event works the same way. We tell Verse:
"Hey, every time a player gets eliminated, automatically run my special function!"
That special function is called an event handler. It's the code that runs when the event happens.
We subscribe like this:
FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated)
This says: "When this character is eliminated, call my function named OnPlayerEliminated."
The End Game Device is a real UEFN device you place on your island. When your Verse code tells it to Activate, it ends the round โ just like a referee blowing the final whistle!
We call it like this:
EndGameDevice.Activate(Player)
Player is who triggered the win โ so Fortnite knows who to celebrate! ๐
Here is the big picture in plain English:
That's it! Let's see it in real Verse code.
Before you write code, place these devices on your island in UEFN:
Now create a new Verse device script and copy the code below.
# These lines "import" tools we need โ like opening your toolbox
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Game }
using { /Verse.org/Simulation }
# Our device is a class โ think of it like a blueprint for a machine
win_condition_device := class(creative_device):
# @editable lets us drag the End Game Device in from the UEFN editor
@editable
EndGameDevice : end_game_device = end_game_device{}
# This is our scoreboard โ starts at 0, changes during the game
var EliminationCount : int = 0
# This is the winning number โ first player to 3 eliminations wins!
EliminationsToWin : int = 3
# OnBegin runs automatically when the island starts โ like pressing Play
OnBegin<override>()<suspends> : void =
# Get a list of everyone playing on the island
AllPlayers := GetPlayspace().GetPlayers()
# Loop through every player โ like checking each name on a list
for (Player : AllPlayers):
# Try to get the player's Fortnite character body
if (FortCharacter := Player.GetFortCharacter[]):
# Sign up for alerts: "text me every time THIS character is eliminated"
FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated)
# This function runs automatically each time ANY player is eliminated
# The "eliminating_character" is the person who got the kill
OnPlayerEliminated(Result : elimination_result) : void =
# EliminatingCharacter is the player who scored the elimination
if (EliminatingCharacter := Result.EliminatingCharacter[]):
# Add 1 to the scoreboard โ like making a tally mark
set EliminationCount = EliminationCount + 1
# Now CHECK: did someone reach the winning number?
if (EliminationCount >= EliminationsToWin):
# YES! End the game and crown the winner
# We cast the character back to an agent so the device accepts it
if (WinningPlayer := EliminatingCharacter.GetAgent[]):
EndGameDevice.Activate(WinningPlayer)
| Part | What's happening |
|---|---|
@editable EndGameDevice |
Lets you drag your End Game Device into the script from the editor panel |
var EliminationCount : int = 0 |
Our scoreboard โ starts at zero |
EliminationsToWin : int = 3 |
The finish line โ 3 eliminations to win |
OnBegin |
Runs at game start; loops through players and signs up for elimination alerts |
FortCharacter.EliminatedEvent().Subscribe(...) |
"Text me every time this character is eliminated!" |
OnPlayerEliminated |
Runs automatically each time someone is eliminated |
set EliminationCount = EliminationCount + 1 |
Adds 1 to the scoreboard (erases old number, writes new one) |
if (EliminationCount >= EliminationsToWin) |
Checks: did we hit the winning number yet? |
EndGameDevice.Activate(WinningPlayer) |
Blows the final whistle โ game over, we have a winner! |
๐ก Pro Tip: After writing the code, go to your Verse device in the UEFN editor. In the Details panel, drag your End Game Device into the
EndGameDeviceslot. If you skip this step, the game won't know which device to activate!
You just built a working win condition. Now let's make it your own!
Challenge: Change the game so a player needs 5 eliminations to win instead of 3. Then add a Print() statement inside OnPlayerEliminated that shows the current score in the output log every time someone gets an elimination.
The Print() function works like this:
Print("Current eliminations: {EliminationCount}")
The curly braces {} around EliminationCount automatically drop the number into the message โ like a fill-in-the-blank!
Steps to try:
EliminationsToWin : int = 3 and change 3 to 5.OnPlayerEliminated, right after you add 1 to the count, add a Print() line.๐ Bonus challenge: Can you make the
EliminationsToWinnumber@editabletoo, so you can change it right from the UEFN editor panel without touching the code?
Hint: Look at how EndGameDevice uses @editable above it. The same trick works for numbers!
Today you created a real win condition for a Fortnite island. You learned that a variable is like a scoreboard that changes during the game, and an event subscription is like signing up for automatic alerts. Your Verse code now listens for every elimination, adds to a counter, and โ when the counter hits the winning number โ activates the End Game Device to end the round and crown a winner. That's a complete game loop, and you built it yourself! ๐
You've learned variables. You've learned devices. You've learned events. Now it's time to put it all together โ like snapping the last LEGO piece into place!
By the end of this lesson, your island will have:
Imagine a board game. It has rules printed in the box. Those rules say:
Your Verse code is the rulebook. The devices are the game pieces. Verse tells the pieces what to do and when.
Here are the devices for your island. Think of each one as a tool in a toolbox:
| Device | What It Does | Real-Life Analogy |
|---|---|---|
| Player Spawn Pad | Where players appear at the start | The "Start" square on a board game |
| Item Granter | Gives players a weapon or item | A vending machine that gives free stuff |
| Timer | Counts down the clock | A sand timer for a game round |
| Score Manager | Tracks each player's points | The scoreboard at a basketball game |
| End Game | Ends the round and picks a winner | The buzzer at the end of a game show |
| Verse Device | YOUR custom code โ the brain! | The game master who runs everything |
@editable?In Verse, you can write code that connects to a real device you placed on your island.
You do this with a special label called @editable.
Think of @editable like a plug socket in your code.
You leave the socket empty in the code, then in UEFN you plug in whichever device you want.
This is super powerful! You can swap devices without rewriting your code. ๐
@editable
MyTimer : timer_device = timer_device{} # This is an empty socket for a Timer device
The line above says: "I have a Timer. I'll plug in the real one later in UEFN."
A round is one play-through of a game before it resets. Think of rounds like innings in baseball โ when one inning ends, a new one starts.
In UEFN, the Island Settings device controls how many rounds you play and how the winner is chosen. You set this up once, like writing the rules on the box lid.
Here's the big picture. Your Verse code is the hub in the middle:
Player Spawns โ Verse Device โ Starts Timer
Player Scores โ Score Manager โ Verse Device checks score
Timer Ends โ Verse Device โ Triggers End Game Device
End Game โ Shows winner โ New Round Begins
Each arrow is an event. An event is something that happens in the game โ like a player scoring or the timer hitting zero.
Your Verse code listens for these events and reacts to them. It's like a referee watching the field and blowing the whistle at the right moment. ๐บ
Before writing code, set up your Island Settings device:
Most Scores WinScoreSpawnThis tells Fortnite: "The player with the most points wins!"
island_manager_device.@editable slots.Here is a short, complete Verse device. It:
Read the comments (the lines starting with #) โ they explain every single line!
# These lines let us use Fortnite devices in our code.
# Think of them like opening the right toolbox drawer.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# This is our custom device โ the "brain" of our island.
# It extends creative_device, which means it IS a Verse device in UEFN.
island_manager_device := class(creative_device):
# @editable means we can plug in a real Timer device from UEFN.
# It's like leaving an empty socket and plugging in the wire later!
@editable
RoundTimer : timer_device = timer_device{}
# @editable for the End Game device โ triggers when time is up.
@editable
RoundEnder : end_game_device = end_game_device{}
# OnBegin runs automatically when the game starts.
# Think of it as the "Game Start" button being pressed.
OnBegin<override>()<suspends> : void =
# Start the countdown timer so players can see it ticking.
RoundTimer.Start()
# WaitForTimerEnd is a helper function (defined below).
# We WAIT here until the timer is done before moving on.
WaitForTimerEnd()
# Time's up! Now we tell the End Game device to end the round.
# Activate() is like pressing the "End Round" button on the device.
RoundEnder.Activate()
# This function waits until the Timer sends a "Success" event.
# An event is a signal โ like a doorbell ringing when someone arrives.
WaitForTimerEnd()<suspends> : void =
# Await means "pause here and wait for this event to happen."
# SuccessEvent fires when the Timer counts all the way down to zero.
RoundTimer.SuccessEvent.Await()
| Step | What Happens | Which Line Does It |
|---|---|---|
| Game starts | OnBegin runs automatically |
OnBegin<override>() |
| Timer starts ticking | RoundTimer.Start() is called |
RoundTimer.Start() |
| Code waits for timer | Await() pauses until time is up |
RoundTimer.SuccessEvent.Await() |
| Timer hits zero | SuccessEvent fires |
RoundTimer.SuccessEvent.Await() |
| Round ends | RoundEnder.Activate() fires |
RoundEnder.Activate() |
| Winner shown | End Game device shows the winner | Handled by the device! |
After building your code:
Right now, the island starts the timer and ends the round. Your job: Make the game also give each player a weapon when the game begins!
Here are the steps:
@editable variable for the Item Granter โ just like RoundTimer and RoundEnder.OnBegin, before RoundTimer.Start(), call the Item Granter's grant method to give the item to all players.๐ก Hint: The Item Granter device in Verse is called item_granter_device.
To grant an item to all players, you can use GrantToAllPlayers() on the device.
Here's the skeleton to fill in:
# Add this with your other @editable variables:
@editable
StarterWeapon : item_granter_device = item_granter_device{}
# Add this inside OnBegin, BEFORE RoundTimer.Start():
StarterWeapon.GrantToAllPlayers()
๐ Bonus Challenge: Can you add a second Item Granter that gives players a healing item too?
Playtest your island! You should spawn in, receive your weapon, see the timer count down, and then see the round end with a winner. If all of that happens โ YOU DID IT! ๐
You connected spawning, scoring, a timer, and a win condition all in one island.
The secret glue was your Verse device โ it listened for events and told other devices what to do.
@editable variables let you wire real devices to your code right from the UEFN Details panel.
Now you have every piece to keep building bigger and more exciting Fortnite islands! ๐