A Creative Device forged on Verse Island
Regatta Zone Control HUD
forged by BizaNator ✓ compiles
◈ Forged at Professor AweShucks' Tinker Lab
III
✓
Compiles
Regatta Zone Control HUD
Combines the Vehicle Spawner Boat Device · Combines the Trigger Device
3 devices
professor-aweshucks says“Here's your Regatta Zone Control rig, sailor! Pull the Start Trigger to kick off a heat - the boat spawner comes alive and the capture zone opens up for grabs. Race your boat to the zone, and whoever's holding it earns points every couple seconds on their very own scoreboard tucked in the corner of their screen, while the Announcer barks out big messages to everyone whenever the zone gets contested, flips hands, or goes quiet. First racer to hit the victory score wins the heat and locks everything down until you pull the trigger again for a fresh race - so keep fighting for that zone!”
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Game }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /Verse.org/Colors }
# Professor AweShucks' Regatta Zone Control HUD
# A co-op/competitive water race: pull the switch to launch the heat, hop in a boat,
# and race to the capture zone. Whoever holds the zone racks up score every couple
# seconds on their own personal HUD scoreboard, while the whole island hears live
# announcements when the zone is contested, captured, or cleared. First racer to
# reach the victory score wins the heat, and pulling the trigger again launches a fresh one.
regatta_zone_control_device := class(creative_device):
# The boat spawner that puts players on the water once the heat begins
@editable
BoatSpawner : vehicle_spawner_boat_device = vehicle_spawner_boat_device{}
# Pull this to launch (or relaunch) a heat
@editable
StartTrigger : trigger_device = trigger_device{}
# The zone racers fight to hold
@editable
ZoneCapture : capture_area_device = capture_area_device{}
# Broadcasts big island-wide announcements (mastered device)
@editable
Announcer : hud_message_device = hud_message_device{}
# Score needed to win a heat
@editable
VictoryScore : int = 30
# Points awarded to the current zone holder on each tick
@editable
HoldPointsPerTick : int = 2
# How often (seconds) the zone holder scores points
@editable
HoldTickInterval : float = 2.0
# --- Shared heat state ---
var RaceActive : logic = false
var RaceGeneration : int = 0
var ZoneHolder : ?agent = false
var Scores : [agent]int = map{}
# --- Per-player scoreboard widgets ---
var PlayerWidgets : [player]?text_block = map{}
# --- HUD message builders (message != string, per the lab rules) ---
RaceStartMsg<localizes>() : message = "Heat launched! Board a boat and race for the zone!"
ZoneContestedMsg<localizes>() : message = "Racers are fighting over the zone!"
ZoneClearMsg<localizes>() : message = "The zone is clear again."
ZoneCapturedMsg<localizes>() : message = "The zone changed hands!"
VictoryMsg<localizes>() : message = "We have a winner! Pull the switch to start a new heat!"
ScoreboardMsg<localizes>(Score:int) : message = "Zone Score: {Score}"
OnBegin<override>()<suspends> : void =
# Wire up every device's real events
StartTrigger.TriggeredEvent.Subscribe(OnRaceStart)
BoatSpawner.AgentEntersVehicleEvent.Subscribe(OnBoatBoarded)
ZoneCapture.FirstAgentEntersEvent.Subscribe(OnZoneApproached)
ZoneCapture.LastAgentExitsEvent.Subscribe(OnZoneCleared)
ZoneCapture.ControlChangeEvent.Subscribe(OnZoneControlChanged)
ZoneCapture.NeutralizeEvent.Subscribe(OnZoneNeutralized)
# Lock everything down until the first pull of the switch
BoatSpawner.Disable()
ZoneCapture.DisallowCapture()
# Launches (or relaunches) a fresh heat
OnRaceStart(MaybeAgent : ?agent) : void =
set RaceGeneration = RaceGeneration + 1
ThisGeneration : int = RaceGeneration
set RaceActive = true
set Scores = map{}
set ZoneHolder = false
BoatSpawner.Enable()
BoatSpawner.RespawnVehicle()
ZoneCapture.Enable()
ZoneCapture.AllowCapture()
ZoneCapture.Neutralize()
Announcer.Show(RaceStartMsg())
spawn{ GameLoop(ThisGeneration) }
# Ticks while a heat is live, feeding points to whoever holds the zone
GameLoop(Generation : int)<suspends> : void =
loop:
Sleep(HoldTickInterval)
if (Generation <> RaceGeneration):
return
if (RaceActive? = false):
return
if (Holder := ZoneHolder?):
AddScore(Holder, HoldPointsPerTick)
UpdateScoreboard(Holder)
CheckVictory(Holder)
# A player climbed into a boat - give them their scoreboard right away
OnBoatBoarded(Agent : agent) : void =
EnsureScoreEntry(Agent)
UpdateScoreboard(Agent)
OnZoneApproached(Agent : agent) : void =
Announcer.Show(ZoneContestedMsg())
OnZoneCleared(Agent : agent) : void =
Announcer.Show(ZoneClearMsg())
OnZoneControlChanged(Agent : agent) : void =
set ZoneHolder = option{Agent}
EnsureScoreEntry(Agent)
UpdateScoreboard(Agent)
Announcer.Show(ZoneCapturedMsg())
OnZoneNeutralized(MaybeAgent : ?agent) : void =
set ZoneHolder = false
# Adds Points to Agent's running score (creating the entry if it's their first score)
AddScore(Agent : agent, Points : int) : void =
NewScore : int = if (Old := Scores[Agent]) then Old + Points else Points
if (set Scores[Agent] = NewScore) {}
# Makes sure Agent has a score entry so their HUD never shows a blank
EnsureScoreEntry(Agent : agent) : void =
if (Scores[Agent]):
return
if (set Scores[Agent] = 0) {}
# Ends the heat and declares Agent victorious
CheckVictory(Agent : agent) : void =
if (Score := Scores[Agent], Score >= VictoryScore):
set RaceActive = false
ZoneCapture.DisallowCapture()
BoatSpawner.Disable()
Announcer.Show(VictoryMsg())
# Creates or refreshes Agent's personal scoreboard widget in the corner of their screen
UpdateScoreboard(Agent : agent) : void =
if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer], Score := Scores[Agent]):
Msg := ScoreboardMsg(Score)
if (ExistingWidget := PlayerWidgets[InPlayer]?):
ExistingWidget.SetText(Msg)
else:
NewWidget := text_block{DefaultText := Msg}
NewCanvas := canvas:
Slots := array:
canvas_slot:
Anchors := anchors{Minimum := vector2{X := 0.02, Y := 0.05}, Maximum := vector2{X := 0.02, Y := 0.05}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.0, Y := 0.0}
SizeToContent := true
Widget := NewWidget
PlayerUI.AddWidget(NewCanvas)
if (set PlayerWidgets[InPlayer] = option{NewWidget}) {}
🌴 Forge your own free at verseisland.com — code U37ZN5F, credits for us both
🧭 Join with U37ZN5F — you both earn starter coconuts
🌴 Forged on Verse Island — free UEFN/Verse learning + a keeper’s Combine Lab.