Pizza Pursuit: Mastering the Game Loop in Verse
Tutorial beginner compiles

Pizza Pursuit: Mastering the Game Loop in Verse

Updated beginner Code verified

Pizza Pursuit: Mastering the Game Loop in Verse

So, you've got a map. You've got a player. But right now, your island is just a pretty picture that does absolutely nothing when someone touches it. That's because you're missing the heart of any game: the Game Loop.

Think of the Game Loop as the game's central nervous system. It's the code that runs over and over again, checking if the player is moving, if the timer is ticking, or if they just got eliminated by a trap you set. In this tutorial, we're building the engine for a "Pizza Pursuit" time trial. You'll learn how to make your island actively "play" the game, cycling through objectives until the player wins or runs out of time. No more static maps—let's make it move.

What You'll Learn

  • The Game Loop Concept: What it is and why your game needs it to function.
  • State Management: How to track if the game is waiting, playing, or over.
  • The Core Cycle: Writing code that repeats actions (pick up pizza, deliver pizza) until a goal is met.
  • Win/Loss Conditions: Setting up the "Game Over" screens for winning or failing.

How It Works

What is a Game Loop?

In Fortnite, you're probably used to the Battle Bus dropping you into the world, and then the game just runs. It doesn't stop. It constantly checks: Is the storm closing? Did I shoot someone? Did I build a ramp?

In programming, this is called a Game Loop. It's a block of code that repeats itself continuously. Imagine a Storm Timer that never stops counting down until the circle closes. The loop is that timer. It runs, does its job, waits a tiny fraction of a second, and runs again.

If you don't have a loop, your code runs once and then... stops. It's like pressing "Start" on a match, but the match ends immediately because the game forgot to keep playing.

The Loop in Action: Pizza Pursuit

For our Pizza Pursuit game, the loop needs to handle three main states:

  1. Waiting: The player hasn't started yet.
  2. Playing: The player is picking up pizzas and delivering them.
  3. Finished: The player won (delivered enough) or lost (time ran out).

The loop's job is to keep the game in the "Playing" state, cycling through these steps:

  1. Pick a new pizza location.
  2. Wait for the player to pick it up.
  3. Check if the player delivered it.
  4. If yes, add time and pick a new location.
  5. If no, check if time ran out.

In Verse, we use a keyword called loop: to create this repetition. It's like a Respawn Timer that keeps checking if the player is alive. As long as the condition is true, the code keeps running.

Scene Graph & Entities

Before we write code, remember the Scene Graph. This is the hierarchy of everything in your world. Your GameCoordinator is an Entity (like a specific Player Character or a Prop). It holds Components (like a Health Bar or a Timer). The loop lives inside this Entity, acting as the brain that tells the other components what to do.

Let's Build It

We're going to create a basic structure for our Game Loop. This code won't fully work without the rest of your Pizza Pursuit setup (like the pickup zones), but it shows the logic of how the loop controls the flow.

Copy this into your game_coordinator_device.verse file.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

# This is our main Game Coordinator device
# Think of it as the 'Referee' of the match
game_coordinator_device := class(creative_device):

    # A trigger device the player walks into to start the race
    # Wire this up in the UEFN editor to your start-zone trigger
    @editable
    StartTrigger : trigger_device = trigger_device{}

    # A trigger device the player walks into to pick up a pizza
    # Wire this up in the UEFN editor to your pickup-zone trigger
    @editable
    PickupTrigger : trigger_device = trigger_device{}

    # A trigger device the player walks into to deliver a pizza
    # Wire this up in the UEFN editor to your delivery-zone trigger
    @editable
    DeliveryTrigger : trigger_device = trigger_device{}

    # Tracks how many pizzas have been delivered
    var PizzasDelivered : int = 0

    # How many pizzas the player must deliver to win
    PizzasToWin : int = 5

    # Tracks remaining time in seconds
    var TimeRemaining : float = 60.0

    # Whether a delivery was made in the current pickup cycle
    var DeliveryMade : logic = false

    # OnBegin is the real entry point for a creative_device in UEFN
    # It runs automatically when the island session starts
    OnBegin<override>()<suspends> : void =
        # STATE 1: Wait for the player to start the race
        # We pause here until the player enters the Start Zone trigger
        StartTrigger.TriggeredEvent.Await()

        Print("Race started!")

        # STATE 2: The main game loop
        # Runs repeatedly until the player wins or time runs out
        loop:
            # Reset the delivery flag for this round
            set DeliveryMade = false

            Print("New pizza location selected - head to the pickup zone!")

            # Wait here until the player actually picks up the pizza
            # Await pauses the code until the trigger fires,
            # saving CPU power instead of checking every frame
            PickupTrigger.TriggeredEvent.Await()

            Print("Pizza picked up! Now deliver it!")

            # Wait for the player to reach the delivery zone
            DeliveryTrigger.TriggeredEvent.Await()

            # Player reached the delivery zone — count the delivery
            set DeliveryMade = true
            set PizzasDelivered = PizzasDelivered + 1

            Print("Pizza delivered! Total: {PizzasDelivered}")

            # Add more time to the clock (like a heal pack for the timer)
            set TimeRemaining = TimeRemaining + 10.0

            Print("Bonus time! Time remaining: {TimeRemaining}")

            # Check win condition: enough pizzas delivered?
            if (PizzasDelivered >= PizzasToWin):
                Print("You Win! All pizzas delivered!")
                break  # Stop the loop — we won!

            # Check loss condition: did time run out?
            if (TimeRemaining <= 0.0):
                Print("Time's up! Game Over!")
                break  # Stop the loop — we lost!

        # STATE 3: Game Over
        # This runs once after the loop breaks
        ShowGameOverScreen()

    # Displays the final result to all players
    # Print() writes to the UEFN output log; swap in a
    # hud_message_device wired in the editor for in-game text
    ShowGameOverScreen() : void =
        if (PizzasDelivered >= PizzasToWin):
            Print("=== YOU WIN! Pizza Pursuit Complete! ===")
        else:
            Print("=== GAME OVER! Better luck next time! ===")

Walkthrough: What Just Happened?

  1. OnBegin<override>()<suspends>: This is the entry point. When your island loads, this function runs automatically — it replaces the placeholder Initialize() from pseudocode because creative_device exposes OnBegin as its real startup hook.
  2. loop:: The first thing we do is wait for the start trigger. It's like the Battle Bus phase—you're waiting for players to jump out.
  3. Inner loop:: This is the core gameplay. It repeats: Wait for Pickup -> Wait for Delivery -> Check Result.
  4. break: This is crucial. It's like the Victory Fanfare or Elimination Screen. It tells the loop, "Stop repeating! The match is over." Without break, your game would loop forever even after the player wins.
  5. Await(): Notice how we call .Await() on each trigger's TriggeredEvent? This pauses the code until an event happens (like a player touching a zone). It's more efficient than checking every frame if the player is there.

Try It Yourself

You've got the skeleton! Now, let's add some meat to the bones.

Challenge: Add a Time Limit to your game. Currently, the loop only ends if the player wins or if time expires (which isn't coded yet).

  1. Create a variable called TimeRemaining and set it to 60.
  2. Inside the main loop:, add a check: if (TimeRemaining <= 0.0): break.
  3. Use a Timer Device or a simple loop: TimeRemaining -= 1; Sleep(1.0) to countdown the seconds.

Hint: Think about where the countdown should happen. Should it run inside the pickup loop, or should it run in parallel? In Verse, you can use sync or race expressions to run things at the same time, but for now, try putting the time check inside your main loop: to see if the game ends when the timer hits zero.

Recap

  • The Game Loop is the heartbeat of your game, repeating code to keep the game active.
  • Use loop: to create repetition, and break to exit when the game is over.
  • State management (Waiting, Playing, Finished) keeps your game organized.
  • Always anchor your code to player actions (pickups, deliveries) to make the game feel responsive.

Now go make that pizza delivery system run smoother than a pro's edit. 🍕🏎️

References

  • https://dev.epicgames.com/documentation/en-us/fortnite/pizza-pursuit-3-creating-the-game-loop-for-time-trial-in-verse
  • https://dev.epicgames.com/documentation/en-us/uefn/time-trial-pizza-pursuit-in-verse
  • https://dev.epicgames.com/documentation/en-us/fortnite/time-trial-pizza-pursuit-in-verse
  • https://dev.epicgames.com/documentation/en-us/fortnite/create-your-own-device-in-verse
  • https://dev.epicgames.com/documentation/en-us/fortnite/pizza-pursuit-5-improving-feedback-and-player-experience-for-time-trial-in-verse

Verse source files

Turn this into a guided course

Add pizza-pursuit-3-creating-the-game-loop-for-time-trial-in-verse 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