Tutorial 01 · Live events

How to build a live concert in Fortnite

A countdown runs to an announced date and time. When it hits zero, the whole audience is moved to a venue for a cue-driven show with lighting, audio, post-process looks and a camera flythrough, then returned to the world afterwards. This is the order to build it in, taken from a show that ran in front of a real audience.

Wide shot of the finished venue mid-show: stage, lights, crowd
10steps, in build order
8device types used
2+testers needed to verify
3live concerts Indie Island has run

Before step one

  • New to UEFN? Do tutorial 00: setup first. It covers the software, your Epic developer account and how to add a Verse file.
  • UEFN installed and an island you can push to a private playtest.
  • The rights to the music. Sort this before you build, not the week of the show.
  • At least two testers. Half the traps below only show up with more than one player: late joiners, respawns, mass teleports.
  • A date and a time, including which timezone you announced it in.
  • Audio exported as one file per track, not one long mix.

Download the Verse files

Complete files used in this tutorial; each works on its own. How to add one: setup step 7. Build-check in UEFN pending.

Download all (.zip)
  • .vconcert_manager.verseThe show: cue struct, cue runner, teleport in/out, post-process, spawner swap, marker suppressionDownload
  • .vlive_event_manager.verseCountdown to a wall-clock date and time, timezone offset, fires the show triggerDownload
01

Set the island baseline

players can move around the world the way the show needs them to

Island Settings decides how people move before, during and after the show. Get it right first, because every rehearsal from here on depends on it. The Details panel labels don't always match the underlying property names, which matters the moment you search for a setting.

Fortnite calls stamina Energy internally. Searching for "stamina" finds nothing.

What you wantPropertyNotes
Glider always usablebGliderRedeploy, bGliderRedeployableSet both
Infinite staminabInfiniteLoadedEnergy, bInfiniteReserveEnergy"Energy", not "stamina"
Player-vs-player damagebAllowFriendlyFireOn a single-team island, this is PvP
Fall damagebFallDamage, fallDamageMultiplierOff is kinder to a crowd

What to place

  • Select the Island Settings device in the Outliner.
  • Set glider redeploy, energy and fall damage for the show you want.
  • Leave teamDamageFilter alone unless you mean structures (see trap).
Island Settings Details panel filtered on "energy", with infinite reserve and loaded energy switched on
Trap

teamDamageFilter looks like a PvP setting. It isn't: it controls which structures players can damage, based on who built them.

Done when

In a playtest you can jump off a ledge, redeploy your glider mid-air and land without taking damage.

02

Count down to a real date and time

the show starts at the minute you announced, not an hour either side

The show is triggered by a countdown to a wall-clock time. GetSecondsSinceEpoch() gives you UTC, and converting your local announced time into it is your job. There is no timezone or daylight-saving support in Verse.

A fixed offset constant is only correct for half the year. Put it at the top of the file, comment it loudly, and put a reminder in your calendar for each clock change.

live_event_manager.verse — timezone offset
# Amsterdam: 1 in winter, 2 during summer time.
# No automatic DST -- this gets flipped by hand at each clock change.
TimeZoneOffsetHours : int = 2
live_event_manager.verseThe complete file, ready to paste into your project. Download full file

What to place

  • A Verse device running live_event_manager.
  • A Billboard or HUD element for the countdown text. Billboards take a message, not a string, so keep a small StringToMessage helper.
  • The trigger the countdown fires when it hits zero (it starts step 7's show).
The countdown to show time in the player HUD
Trap

Wrong offset, and the show fires exactly one hour off the time you typed. This happened to this project once, publicly.

Done when

You set the target five minutes ahead, launch a playtest, and the trigger fires on the minute your phone's clock says it should.

03

Build the venue and give it its own spawner

players respawn at the venue during the show, and nowhere near it otherwise

Every enabled Player Spawner is a candidate for both initial spawn and respawn. The moment you place a second one anywhere in the level, it starts catching ordinary spawns. And a newly placed spawner is enabled by default.

The pattern: give the show a dedicated spawner, Disable() it in OnBegin, and swap enabled state on both sides when the show starts and ends. World spawners off and venue spawner on at show start; the reverse at the end.

What to place

  • The venue itself, away from the main world.
  • One Player Spawner inside the venue, reserved for the show.
  • In your show device, an @editable field for that spawner, and for each world spawner.
  • Wire each field to its actor in the Details panel. This is the step people skip.
The empty venue from above; the ring marks where the venue spawner sits
Show device Details panel with the spawner field wired (not empty)
Trap

A Disable() call does nothing until the @editable field is actually wired to that actor. An empty field silently no-ops, the spawner stays on, and players start appearing at your half-built venue.

Done when

Outside show time, you die ten times and never respawn at the venue. During a rehearsal, you die on purpose and respawn at the venue.

04

Add the audio, synced, one device per track

anyone who arrives, reconnects or respawns mid-song hears the song at the right point

Use one Audio Player device per track rather than one long mix, so cues can start and stop individual songs. Then turn on the one setting that matters: syncPlayerAudio. It is off by default.

Without it, a track started at minute two is simply not playing for anyone who arrives at minute three. They don't get a late start, they get silence for the rest of the song. That covers latecomers, reconnects and anyone who respawns, which is how it usually gets discovered: someone dies during a show and the music is gone for them.

PropertySet toWhy
syncPlayerAudioOnKeeps every player on the same point in the track
loopAudioOffThe cue list decides when a song ends
limitAudioDistanceYour callOff = heard everywhere; on = falls off by audioDistance

What to place

  • One Audio Player per track, named after the track.
  • On each: enable Sync Player Audio.
  • Decide distance limiting once and apply it to all of them.
Audio Player Details panel with
Trap

Leaving sync off works perfectly in a solo test. It only breaks for the second person, and only after they die.

Done when

With two testers, one dies thirty seconds into a song, respawns, and still hears it at the same point as the other.

05

Place the lights and name them properly

you can find any light in a cue list by reading its name

Show lighting is Customizable Light devices, switched with TurnOn() and TurnOff(). You will drag dozens of them into cue arrays by hand in step 7, and naming is the difference between twenty minutes and an afternoon.

Name them by position and subject: Key_Left_Vocalist, not Light12.

What to place

  • Customizable Lights around the stage, grouped by what they light.
  • Rename each in the Outliner: Role_Position_Subject.
  • Optional: VFX Spawners for effects (see note).
Outliner showing lights named by position and subject
Note

The VFX Spawner's effect defaults to DiscoBalls, which is easy to miss. A custom Niagara system assigned through customVisualEffect never rendered in this project, and the cause is still unknown. A coloured Point Light was used instead and worked. Don't count on custom Niagara for show day.

Done when

Someone else can look at the Outliner and tell you which light hits the vocalist from the left.

06

Make the post-process looks, and test them fast

each colour look can be previewed in a playtest in seconds

A Post Process device per look (BlendInForAll(), BlendOutForAll() from Verse). Tuning looks by running the whole show each time is painfully slow. Instead, wire a spare Button's interact event straight to the device's Enable For All and Blend In For All in the Details panel. Walk up, press it, see the look.

What to place

  • One Post Process device per look. Set blendInDuration and blendOutDuration.
  • A temporary Button per look. Wire it from the Post Process side: under User Options - Functions, add an element to Enable for All and Blend in for All, pick the Button and choose On Interact.
  • Remove or hide the test buttons before you publish.
Button device event wired to the Post Process device
The venue with one post-process look applied
Trap

Blend the previous look out before blending the next one in, and track which one is active. Otherwise looks stack on top of each other.

Done when

In one playtest you press every test button in turn and each look replaces the last cleanly.

07

Write the show as a cue timeline

the whole show is authored in the Details panel, and it ends when the music ends

Model the show as an array of <concrete> cue structs. Each holds a timestamp plus everything that fires at it: tracks to start, lights to switch, the look to blend in. One loop sleeps the gap between cues. People who don't write code can then author the whole show in the Details panel.

Keep the end of the show as its own field. The last cue firing and the performance finishing are different moments.

concert_manager.verse — show end
# After the last cue: wait out the rest of the show,
# measured from ShowDurationSeconds -- NOT from the cue list.
RemainingSeconds := ShowDurationSeconds - ElapsedSeconds
if (RemainingSeconds > 0.0):
    Sleep(RemainingSeconds)
OnShowEnd()
concert_manager.verseThe complete file, ready to paste into your project. Download full file

What to place

  • The Verse device running concert_manager.
  • Fill the cue array in the Details panel, one entry per moment.
  • Set ShowDurationSeconds to the real length of the set.
Details panel with the cue array expanded: timestamps, tracks, lights
Note

Struct arrays can only be filled by hand. Every field in the cue struct is a manual drag, multiplied by every cue. Keep the field count deliberate.

Trap

Tying the ending to the last cue cut a live show off mid-song in this project.

Done when

In a full rehearsal, the show-end fires after the last song has finished, not when the last cue fires.

08

Teleport everyone in, and back out

the whole audience arrives at the venue at show start and returns afterwards

Place a prop as a marker where people should land, then move every player to its transform. Do the same in reverse at the end, with a marker in the world.

concert_manager.verse — teleport
TeleportEveryoneTo(Marker : creative_prop) : void =
    Where := Marker.GetTransform()
    for (Player : GetPlayspace().GetPlayers()):
        # Fails silently for anyone mid-respawn or with a network blip.
        if (Char := Player.GetFortCharacter[]):
            if (Char.TeleportTo[Position := Where.Translation, Rotation := Where.Rotation]) {}

What to place

  • A prop at the venue landing spot, and one at the return spot.
  • Wire both to @editable fields on the show device.
  • Call teleport-in at show start, after the spawner swap from step 3.
Landing marker prop at the venue, selected in the editor
Trap

GetFortCharacter[] fails for anyone mid-respawn, and that player is skipped with no error. A mass teleport can look like it hit "some players but not others". It isn't a selection, it's timing. The venue spawner from step 3 is what catches them.

Done when

With every tester in the world, all of them arrive at the venue at show start, including one who died a second before, and all of them are back in the world after the show-end.

09

Hide world markers during the show

no HUD beacons pull attention away from the stage, and they come back afterwards

If the world has Beacons (for resource nodes, for example), they will be pointing players out of the venue mid-show. Hide them. But a background loop that manages them will re-enable them a few seconds later, and the bug looks random. A flag checked inside the loop beats trying to kill the loop.

In the downloads this is already done: plain beacons go in concert_manager's HideBeacons list, and dropper_manager (tutorial 03) hides its own beacons when its HideMarkersTrigger fires. This is the pattern inside it:

dropper_manager.verse — marker suppression
var SuppressMarkers : logic = false

SetMarkersHidden(Hidden : logic) : void =
    set SuppressMarkers = Hidden
    if (Hidden = true):
        for (Node : Nodes):
            Node.Beacon.Disable()
    else:
        for (Idx -> Node : Nodes):
            if (IsActive(Idx) = true):
                Node.Beacon.Enable()

# ...and inside the rotation loop:
if (SuppressMarkers = false):
    Node.Beacon.Enable()

What to place

  • Plain beacons: add them to HideBeacons on the concert device.
  • Node beacons: on dropper_manager, set HideMarkersTrigger to the same trigger as ShowStartTrigger, and ShowMarkersTrigger to ConcertEndTrigger.
Player HUD during the show with no beacon markers visible
Trap

Note the explicit = true / = false. A bare logic in an if doesn't compile: "Expected an expression that can fail".

Done when

Through a full rehearsal no beacon appears on the HUD, and within a few seconds of show-end they're back where they should be.

10

Add a camera flythrough that actually shows the world

the flythrough shows buildings and props, even far from where players are standing

A Cinematic Sequence device plays the flythrough (Play(), then StoppedEvent.Await() to continue after it). The fix nobody finds alone: World Partition streams the world in around the player pawn, not around the camera. A camera that flies away from the audience shows empty terrain, because nothing asked those cells to load.

Add a WorldPartitionStreamingSourceComponent to the Cine Camera Actor:

PropertyValue used
bStreamingSourceEnabledtrue
priorityHighest
targetStateActivated
shapesone shape, bUseGridLoadingRange: false, radius: 15000
Trap

It looks fine when you test near the camera path. Missing buildings only show in the areas furthest from any player, which is where your audience isn't.

Done when

With all testers standing at the venue, the flythrough over the far side of the map shows every building and prop.

Show day

The day-of checklist

Every line here is something that really went wrong.