A Creative Device forged on Verse Island
Ember Watch HUD
forged by RinEllaSky ✓ compiles
◈ Forged at Professor AweShucks' Tinker Lab
II
✓
Compiles
Ember Watch HUD
Combines the Trigger Device · Combines the Campfire Device
professor-aweshucks says“Hey there! This forges a personal heads-up dashboard for your Ember Watch trial: pull the Start trigger and your own on-screen readout appears, telling you to tend the sacred campfire. Stand near the fire while it's lit and every pulse of warmth adds to a shared score everyone can see - but if the flame goes dark, you've got a shrinking window to relight it before the trial fails, and each blackout survived makes the next one worth more points and harder to save. Keep the fire burning long enough to hit the victory score and your HUD flashes gold - then just trigger the switch again to run the gauntlet once more.”
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' Ember Watch HUD
# A personal on-screen dashboard that turns a Campfire into a co-op survival trial.
# Trigger the switch to start, then stand near the fire and keep it lit - every pulse of
# warmth scores points. If the fire goes out you get a shrinking window to relight it before
# the trial fails. Survive escalating blackouts to reach Victory, then trigger again to replay.
ember_watch_hud_device := class(creative_device):
# Mastered switch - starts (or restarts) the trial for whoever pulls it
@editable
StartTrigger : trigger_device = trigger_device{}
# The campfire at the heart of the trial
@editable
SacredCampfire : campfire_device = campfire_device{}
# Score needed to win the trial
@editable
VictoryScore : int = 30
# --- Per-player HUD widgets ---
var PlayerWidgets : [player]?text_block = map{}
# --- Shared trial state (co-op: everyone near the fire feeds the same score) ---
var TrialActive : logic = false
var IsLit : logic = false
var Score : int = 0
var DangerLevel : int = 0
var WatchId : int = 0
OnBegin<override>()<suspends>:void=
StartTrigger.SetMaxTriggerCount(0)
StartTrigger.Enable()
StartTrigger.TriggeredEvent.Subscribe(OnStartTriggered)
SacredCampfire.LitEvent.Subscribe(OnFireLit)
SacredCampfire.ExtinguishedEvent.Subscribe(OnFireExtinguished)
SacredCampfire.AgentPulsedEvent.Subscribe(OnAgentPulsed)
SacredCampfire.AgentEntersEffectAreaEvent.Subscribe(OnAgentEnters)
SacredCampfire.AgentExitsEffectAreaEvent.Subscribe(OnAgentExits)
# Fires when a player uses the Start switch. Builds their HUD if needed and (re)starts the trial.
OnStartTriggered(MaybeAgent:?agent):void=
if (Agent := MaybeAgent?):
EnsureWidgetFor(Agent)
if (not TrialActive?):
set TrialActive = true
set Score = 0
set DangerLevel = 0
set IsLit = false
SacredCampfire.Enable()
BroadcastStatus(TrialStartedMessage(), NamedColors.White)
# Builds a personal HUD widget for a player the first time they interact.
EnsureWidgetFor(Agent:agent):void=
if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer], not PlayerWidgets[InPlayer]?):
NewText := text_block{DefaultText := WelcomeMessage(), DefaultTextColor := NamedColors.White}
Canvas := canvas:
Slots := array:
canvas_slot:
Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.05}, Maximum := vector2{X := 0.5, Y := 0.05}}
Offsets := margin{Left := -260.0, Top := 0.0, Right := 260.0, Bottom := 90.0}
Alignment := vector2{X := 0.5, Y := 0.0}
SizeToContent := true
Widget := NewText
PlayerUI.AddWidget(Canvas)
if (set PlayerWidgets[InPlayer] = option{NewText}) {}
# The flame catches - scoring resumes.
OnFireLit(Agent:agent):void=
if (TrialActive?):
set IsLit = true
BroadcastStatus(FireLitMessage(), NamedColors.Green)
# The flame dies - start a shrinking relight countdown. Fail the trial if nobody saves it in time.
OnFireExtinguished(Agent:agent):void=
if (TrialActive?):
set IsLit = false
set DangerLevel += 1
set WatchId += 1
MyWatch := WatchId
Window := ComputeWindowSeconds(DangerLevel)
BroadcastStatus(FireOutMessage(Window), NamedColors.DarkOrange)
spawn{WatchForRelight(MyWatch, Window)}
# Shrinks the safe relight window each time the fire goes out - the escalation!
ComputeWindowSeconds(Danger:int):int=
Candidate := 12 - Danger
if (Candidate < 4):
4
else:
Candidate
# Waits out the relight window; fails the trial if the fire is still dark and no newer watch replaced this one.
WatchForRelight(MyWatch:int, WindowSeconds:int)<suspends>:void=
Sleep(WindowSeconds * 1.0)
if (MyWatch = WatchId, TrialActive?, not IsLit?):
FailTrial()
# Every pulse near a lit fire scores points - more points the more danger you've survived.
OnAgentPulsed(Agent:agent):void=
if (TrialActive?, IsLit?):
set Score += 1 + DangerLevel
if (Score >= VictoryScore):
Victory()
else:
BroadcastStatus(ScoreMessage(Score, DangerLevel), NamedColors.White)
# A little personal flavor text when stepping in/out of the fire's warmth.
OnAgentEnters(Agent:agent):void=
if (TrialActive?, InPlayer := player[Agent], TextBlock := PlayerWidgets[InPlayer]?):
TextBlock.SetText(EnterMessage())
OnAgentExits(Agent:agent):void=
if (TrialActive?, InPlayer := player[Agent], TextBlock := PlayerWidgets[InPlayer]?):
TextBlock.SetText(ExitMessage())
Victory():void=
BroadcastStatus(VictoryMessage(Score), NamedColors.Gold)
set TrialActive = false
set Score = 0
set DangerLevel = 0
FailTrial():void=
BroadcastStatus(FailedMessage(), NamedColors.Red)
set TrialActive = false
set Score = 0
set DangerLevel = 0
# Pushes a status update (text + color) to every registered player's HUD.
BroadcastStatus(Msg:message, Color:color):void=
for (Player -> MaybeText : PlayerWidgets):
if (TextBlock := MaybeText?):
TextBlock.SetText(Msg)
TextBlock.SetTextColor(Color)
# --- Localized HUD text ---
WelcomeMessage<localizes>():message = "🔥 Ember Watch\nTrigger the switch to start the trial!"
TrialStartedMessage<localizes>():message = "🔥 Trial started! Keep the campfire lit and stand close to score!"
FireLitMessage<localizes>():message = "🔥 The flame roars back to life! Scoring resumes."
FireOutMessage<localizes>(Seconds:int):message = "⚠️ The fire went out! Relight it in {Seconds}s or the trial fails!"
ScoreMessage<localizes>(ScoreVal:int, Danger:int):message = "🔥 Score: {ScoreVal} | Danger: {Danger}\nKeep tending the flame!"
VictoryMessage<localizes>(FinalScore:int):message = "🏆 Victory! Final Score: {FinalScore}\nTrigger the switch to play again!"
FailedMessage<localizes>():message = "💀 The fire went dark... Trial failed.\nTrigger the switch to try again!"
EnterMessage<localizes>():message = "🔥 You feel the warmth grow..."
ExitMessage<localizes>():message = "🥶 You stepped away from the flame."
🌴 Forge your own free at verseisland.com — code G4EFENS, credits for us both
🧭 Join with G4EFENS — you both earn starter coconuts
🌴 Forged on Verse Island — free UEFN/Verse learning + a keeper’s Combine Lab.