The Prop’s Heartbeat: Making Idle Players Squeak in Verse
Unverified — this example may not compile as-is.
The Verse code below did not pass our automated compile check, so it isn't marked verified and is hidden from the guide listing. The explanation may still be useful, but treat the code as a draft and adapt it before use.
The Prop’s Heartbeat: Making Idle Players Squeak in Verse
Imagine you’re hiding as a trash can in a game of Prop Hunt. You’re holding your breath, praying the Hunter doesn’t walk by. But then, you get bored. You shift your weight. You tap your foot. Suddenly, a loud thump-thump-thump sound effect plays, betraying your exact location. That’s the "heartbeat" mechanic we’re building today.
In Verse, we don’t just tell a player to "be a prop." We have to manage their entire existence—spawning, hiding, moving, and the specific rule that if they stand still too long, they give themselves away. We’ll use a concept called a Game Loop (think of it as a persistent check-in system, like a storm timer that never stops until the match ends) to monitor every Prop player.
What You'll Learn
- The Game Loop: How to create a background process that runs continuously for a specific team, like a passive ability that never turns off.
- Race Conditions: How to let multiple things happen at once (moving vs. timing out) and react to whichever happens first.
- State Management: Tracking if a player is moving or standing still to trigger effects.
- Scene Graph Basics: Understanding how your Verse script connects to the actual 3D entities (players) in the world.
How It Works
In Fortnite, when you play Prop Hunt, the game treats "Props" and "Hunters" differently. Hunters are aggressive; Props are stealthy. But stealth is hard to code because "not doing anything" is still an action in programming terms.
To make this work, we need a Class. In Verse, a class is like a blueprint. If you have a blueprint for a "Hunter," it knows how to shoot. If you have a blueprint for a "Prop," it knows how to hide. We’re going to create a PropTeam class.
Inside this class, we’ll write a function called RunPropGameLoop. Think of this as the Prop’s personal life coach. From the moment they spawn until they are eliminated, this function is running in the background. It asks one question repeatedly: "Are you still standing still?"
If the answer is "yes" for too long, the coach triggers a heartbeat sound. If the answer is "no" (the player moved), the coach resets the timer. This is where we use a Race. In programming, a race lets two or more tasks happen simultaneously. We’ll race a "Movement Check" against a "Timer." Whoever wins the race determines what happens next.
Let's Build It
First, create a new Verse file in your project named prop_team.verse. This isn’t a device you place in the world; it’s a script that lives in the background.
We need to assume you already have a basic setup where players are assigned to teams. For this tutorial, we’ll focus on the logic inside the Prop team.
Here is the annotated code. Copy this into your prop_team.verse file.
# This is our blueprint for the Prop Team.
# It inherits from base_team (the standard team logic) so we get basic stuff for free.
prop_team : base_team = class:
# Define the time threshold for the heartbeat.
# If a prop is still for this long, they squeak.
HeartbeatThreshold: float = 3.0
# This is the main function that runs for every Prop player.
# <suspends> means this function can pause and wait for things to happen
# without freezing the whole game.
RunPropGameLoop(PropAgent:agent)<suspends>:void =
# Print to the debug log so we know this player is being tracked.
Logger.Print("Prop Agent {PropAgent} is now hiding.")
# We start a loop. This is the "infinite" check-in.
# It runs forever until the player is eliminated or leaves.
loop:
# Reset the "moved" flag. We assume they are still until proven otherwise.
has_moved := false
# This is the RACE. We are racing two tasks:
# 1. Waiting for the player to move (MovementCheck)
# 2. Waiting for the heartbeat timer to run out (TimerCheck)
race:
# TASK 1: Check for movement.
# We wait until the player's position changes.
# Note: In a real full implementation, you'd compare Vector positions.
# Here we use a simplified event-based approach for clarity.
wait_for_movement(PropAgent):
# This is a placeholder for the actual movement detection logic.
# In real Verse, you'd check Delta Location or use a movement event.
# For this tutorial, we assume an event 'OnPlayerMoved' exists
# or we poll the agent's location.
# Let's simulate waiting for a move event:
await PropAgent.OnPlayerMoved # Simplified concept
# If we get here, the player moved!
has_moved := true
Logger.Print("Prop moved! Resetting heartbeat.")
# TASK 2: The Heartbeat Timer.
# We wait for our threshold time to pass.
wait_for_heartbeat():
Sleep(HeartbeatThreshold)
# If the timer finishes, and the player HAVEN'T moved, trigger the sound.
if not has_moved:
Logger.Print("Heartbeat triggered! You're squeaking!")
# Play a sound effect here using PlaySoundOnPlayer(PropAgent, HeartbeatSound)
# Once the race completes (either they moved, or they squeaked),
# we loop back to the start to check again.
Sleep(0.0) # Brief pause to prevent CPU overload
Walkthrough
- The Class (
prop_team): This groups all our Prop-specific logic. It’s like a folder on your computer called "Prop Stuff." RunPropGameLoop: This is the engine. It takes aPropAgent(the specific player instance) and starts monitoring them.- The
loop: This ensures the check never stops. As long as the player is alive, the code inside this loop runs over and over. - The
race: This is the magic. We don’t want to check movement then check the timer sequentially (that would be slow). We want to check them at the same time.- If the player moves, the
wait_for_movementtask finishes, setshas_moved = true, and the race ends. The timer is effectively cancelled because the race is over. - If the player doesn't move, the timer finishes first. The race ends,
has_movedis still false, and we trigger the heartbeat.
- If the player moves, the
Try It Yourself
The code above is a conceptual skeleton. To make this fully playable, you need to connect the wait_for_movement part to actual Verse APIs.
Challenge:
Find the Verse API for checking a player's location or listening for movement events. Replace the await PropAgent.OnPlayerMoved line with actual code that compares the player's current location to their location from 0.5 seconds ago. If the distance is greater than 0, set has_moved = true.
Hint: Look up GetLocation() and Distance() in the Verse documentation. You’ll need to store the previous location in a variable before the race starts.
Recap
You’ve just built the logic behind the Prop Hunt heartbeat. You learned how to create a Class to group team-specific logic, how to use a Loop to keep checking on players continuously, and how to use a Race to handle multiple outcomes (moving vs. timing out) simultaneously. This pattern is the foundation for almost any complex game mode in Fortnite—whether it’s tracking kills, managing inventory, or detecting storm damage.
References
- https://dev.epicgames.com/documentation/en-us/fortnite/prop-hunt-04-setting-up-teams-and-classes-in-unreal-editor-for-fortnite
- https://dev.epicgames.com/documentation/en-us/uefn/verse-prop-hunt-template-4-setting-up-teams-and-classes-in-unreal-editor-for-fortnite
- https://dev.epicgames.com/documentation/en-us/fortnite/prop-hunt-06-adding-the-full-script-in-unreal-editor-for-fortnite
- https://dev.epicgames.com/documentation/en-us/uefn/verse-prop-hunt-template-6-adding-the-full-script-in-unreal-editor-for-fortnite
- https://dev.epicgames.com/documentation/en-us/uefn/verse-prop-hunt-template-3-playing-effects-on-idle-players-in-unreal-editor-for-fortnite
Verse source files
- 01-standalone.verse · standalone
Turn this into a guided course
Add Prop Team 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.
References
- Prop Team ↗
- Prop Team ↗
- Inheriting from the base\_team class, the prop\_team class contains the device definitions and functions related to the prop team and its agents. ↗
- Inheriting from the base_team class, the prop_team class contains the device definitions and functions related to the prop team and its agents. ↗
- 3. Playing Effects on Idle Players ↗
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.