Random Sequence Player
Random Sequence Player
Plays cinematic sequences in a random order on a randomized cooldown, avoiding immediate repeats — great for non-repetitive ambient events.
Original, compile-verified Verse by Bizanator (Biloxi Studios). Clean-room sample you can drop into a UEFN project and adapt.
# Random Sequence Player — Biloxi Studios Inc.
#
# Plays cinematic sequences in a random order on a randomized cooldown, optionally
# avoiding back-to-back repeats. Useful for ambient set-dressing: idle animations,
# environmental events, background cinematics that should feel non-repetitive.
#
# Teaches: a recursive self-rescheduling <suspends> function, GetRandomInt /
# GetRandomFloat, Mod-based index wrapping to skip the last-played item, and safe
# array indexing inside a failure context.
#
# Setup: fill Sequences with cinematic_sequence_device references.
using { /Fortnite.com/Devices }
using { /Verse.org/Random }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
log_random_sequence_player := class(log_channel){}
random_sequence_player := class<concrete>(creative_device):
Logger : log = log{Channel := log_random_sequence_player}
# The sequences to choose between.
@editable
Sequences : []cinematic_sequence_device = array{}
# Random wait (seconds) before playing each sequence.
@editable
CooldownMin : float = 30.0
@editable
CooldownMax : float = 90.0
# When true and there is more than one sequence, never replay the one that
# just finished.
@editable
AvoidImmediateRepeat : logic = true
OnBegin<override>()<suspends> : void =
if (Sequences.Length <= 0):
Logger.Print("No Sequences configured.", ?Level := log_level.Warning)
return
# Kick off the loop with a random starting sequence.
PlayAfterCooldown(GetRandomInt(0, Sequences.Length - 1))
# Wait a random cooldown, play the sequence at Index, then schedule the next.
PlayAfterCooldown<private>(Index : int)<suspends> : void =
Sleep(GetRandomFloat(CooldownMin, CooldownMax))
if (Sequence := Sequences[Index]):
Sequence.Play()
Logger.Print("Playing sequence {Index}.")
PlayAfterCooldown(NextIndex(Index))
# Decide the next index: a fresh uniform pick, or — when avoiding repeats —
# the current index plus a random non-zero offset, wrapped into range.
NextIndex<private>(LastIndex : int) : int =
if (Sequences.Length > 1 and AvoidImmediateRepeat?):
Offset := GetRandomInt(1, Sequences.Length - 1)
if (Wrapped := Mod[LastIndex + Offset, Sequences.Length]):
return Wrapped
return GetRandomInt(0, Sequences.Length - 1)