When you finished Lesson 6, your UEFN experience could already react to basic events using Verse—spawns, eliminations, and device triggers. In this lesson, you will turn that event plumbing into real game rules: score, rounds, and visible win conditions.
The goal is not to build a full esports ruleset. The goal is to ship a simple, understandable gameplay loop where:
- Players can see how to win
- The game tracks progress correctly
- Matches end cleanly and can be restarted without weird leftovers
1. Decide One Clear Win Condition for This Prototype
Before touching Verse, lock one sentence:
- Examples:
- “First team to reach 50 eliminations wins.”
- “First player to hold the hill for 120 total seconds wins.”
- “Team with the highest score after 5 minutes wins.”
Pick exactly one primary win condition for this lesson.
Write it at the top of your design doc and inside your map somewhere (e.g., on a sign or in the lobby) so playtesters are never guessing.
You will need:
- What you are counting (elims, time on hill, objectives captured)
- The target value (50 kills, 120 seconds, 3 captures, etc.)
- Whether there is a time limit or not
2. Place and Configure Scoreboard/Tracker Devices in UEFN
UEFN already ships with devices that expose scores, timers, and UI. You will lean on them instead of rebuilding UI in Verse.
Common choices:
- Scoreboard / Round-based devices
- Objective/Tracker devices (e.g., Capture Item, Control Point)
- Timer devices for round length
In your map:
- Add a Score Manager / Scoreboard‑style device appropriate for your mode.
- Configure:
- Which team or player scoring mode you want (team‑based vs free‑for‑all).
- Whether the score is shown on screen, in round summary, or both.
- Add any Timer devices if you use a hard time limit.
Name devices clearly:
Scoreboard_MainRoundTimer_MainObjectiveTracker_HillA
You will reference these from Verse using @editable variables.
3. Create a New Verse File Focused on Game Rules
Do not drop all your game logic into one huge script. Instead, create a dedicated rules script.
In your Verse content browser:
- Create a new file, for example
GameRules.verse. - Define a class to own your match logic:
using { /Fortnite.com/Game, /Verse.org/Simulation }
game_rules := class(creative_device):
@editable Scoreboard : scoreboard_device = scoreboard_device{}
@editable RoundTimer : timer_device = timer_device{}
var TargetScore : int = 50
OnBegin<override>()<suspends> :
# logic will go here
return
Attach this Verse class to a single device in your map (e.g., a simple creative device placed in your level) and wire the Scoreboard and RoundTimer references in the Details panel.
4. Listen to Elimination or Objective Events in Verse
Your rules class needs to know when to add score.
You can choose one or combine both:
- Elimination based:
- Subscribe to elimination events (per player or per team).
- Objective based:
- Subscribe to control point captures or item deliveries.
Pseudocode structure in Verse (shape only, not exact API):
OnBegin<override>()<suspends> :
# Subscribe to relevant game events
RegisterForEliminationEvents()
RegisterForRoundTimer()
return
RegisterForEliminationEvents() : void =
# Hook into your elimination device / event bus here
# When an elimination happens, call AddScoreForElim(...)
return
AddScoreForElim(eliminatingPlayer : player) : void =
# Identify team
# Increment that team’s score on the Scoreboard device
# CheckWinCondition()
return
Use the official UEFN / Verse docs to plug in the real event signatures for elimination or objective devices you already have in your map.
5. Implement a Simple Score and Win Check
Once you can call AddScoreForElim or similar from an event, implement the win condition check.
Structure:
AddScoreForTeam(team : int, amount : int) : void =
# 1. Read current score for that team from Scoreboard
# 2. Add amount
# 3. Write new score back to Scoreboard
CheckWinCondition(team)
CheckWinCondition(team : int) : void =
# 1. Read that team’s score
# 2. If >= TargetScore, call EndMatchWithWinner(team)
return
EndMatchWithWinner(team : int) : void =
# Stop further scoring
# Stop round timer (if any)
# Trigger any “Match Ended” devices (e.g., end game, show UI)
return
Your first implementation can be naive:
- No tie breaking
- No overtime
- Just “first to target score wins”
You can always refine in later lessons.
6. Wire Round Timer and Time‑Limit Loss Conditions
If your mode has a time limit:
- Configure the
RoundTimerdevice duration (e.g., 300 seconds). - From Verse, subscribe to its time‑expired event.
In GameRules.verse:
RegisterForRoundTimer() : void =
# Subscribe to the RoundTimer finished event
return
OnRoundTimerExpired() : void =
# Read both teams’ scores from Scoreboard
# Decide winner (higher score), or trigger tie state
# Call EndMatchWithWinner(...) or a separate EndMatchAsTie()
return
This lets you support both:
- “First to score target wins early”
- “If time runs out, highest score wins”
Start with whatever is easier to explain in your one‑sentence mode description.
7. Surface Feedback to Players (Announcements and UI)
Rules that only exist in code feel invisible. Use devices and Verse to tell players what just happened.
Options:
- Use HUD message / announcement devices triggered from Verse:
- “Blue Team scored!”
- “Red Team victory!”
- “2 minutes remaining!”
- Use scoreboard visibility so players can see progress mid‑match.
In your rules class, add helper functions:
AnnounceScore(team : int, newScore : int) : void =
# Trigger a HUD message or announcement device
return
AnnounceTimeWarning(secondsRemaining : int) : void =
# e.g., fire at 120s and 30s remaining via timer callbacks
return
Even a couple of well‑timed text popups dramatically improve match clarity.
8. Reset State Cleanly Between Matches
Messy resets are one of the biggest sources of bugs in custom modes. Make sure your experience can go from Match End → Reset → New Match without:
- Old scores lingering
- Timers not resetting
- Events double‑subscribing
Checklist:
- Create a
ResetMatch()function in your rules class that:- Resets scores for all teams on the Scoreboard device
- Resets any per‑match Verse variables (
hasWinner,currentRound, etc.) - Restarts or resets the
RoundTimer
- Call
ResetMatch():- When players return to the lobby area
- Or after a short post‑match delay before the next round begins
Test by playing multiple matches back‑to‑back in one session.
9. Playtest With Friends and Watch the Rules, Not Just Bugs
Run at least 3 full matches with other players (or bots/second accounts) and focus on:
- Does everyone understand how to win within the first minute?
- Is it always clear which team is ahead?
- Does the end‑of‑match moment feel:
- Abrupt?
- Confusing?
- Or satisfying and clear?
Take quick notes:
- “Players did/did not notice the score UI.”
- “Time‑limit win felt fair/unfair.”
- “We forgot to reset X between matches.”
Turn each note into a tiny task:
- Make score UI more obvious
- Add a pre‑match countdown
- Add a short post‑match summary area
10. Mini Challenge – Variant Rule Set
To cement these ideas, create a second rules variant of your mode:
- Example variants:
- Elimination race → Objective capture race
- First to 50 kills → Team with highest score after 3 minutes
- Single hill control → rotating hill positions
In practice:
- Duplicate your
GameRules.versefile or class and rename for the variant. - Change:
TargetScore- Time limit
- Which events increment score
- Add a simple lobby selector (e.g., buttons or triggers) that enables one rules device or the other.
Now your UEFN project does not just have content—it has a rules engine you can extend in later lessons for ranked play, playlists, or special events.