You made it to the bottom of the map. Every zone on the archipelago built one game; The Deeps builds the one they were all training for. The dive round from lesson 8, the relic component and prefab from lessons 10-13, the swimming-relic animation from lesson 12, the sequencer and data-layer reveal from lessons 17-18, the Warden NPC and its control rig from lessons 19-20 — today they fuse into Athenaeum Depths, the shippable island that AweShucks Town's matchmaking portal points at. No mascot hand-holding down here; just you, the checklist, and the deep.
What you will build
The complete Athenaeum Depths minigame — a two-phase loop:
Phase 1 — the Sunken Dive Round (device-driven, lesson 8): players press DIVE, drop past the water line into first-person, and race their air supply to claim every relic in the flooded vault while the Warden patrols. Every claim writes to the persistent ledger.
Phase 2 — the Athenaeum payoff (scene-graph + cinematics, lessons 9-20): each banked relic swims to its pedestal socket. When the last pedestal fills, the vault-reveal sequence plays — camera cuts, the kraken's control-rig tentacle sweep, and the data-layer activation that materializes the hidden wing — then the portal home to AweShucks Town opens.
The round loop: LOBBY → DIVING → REVEAL → VICTORY → back to LOBBY, replayable forever. Lose the air race and you surface empty-handed — but your lifetime RelicsBanked total keeps every relic you banked before drowning, because persistence doesn't care about your round.
Architecture at a glance
One athenaeum_depths_game device conducts everything; one module supplies the strings; one persistable class outlives the session:
| Piece | Built in | Job in the capstone |
|---|---|---|
deeps_kit module |
south-shores lesson 9 pattern | All HUD messages + UpdateRelicHud — imported with using |
dive_phase enum |
south-shores phase machine | Gates every handler: LOBBY / DIVING / REVEAL / VICTORY |
race {} air timer |
west-coves async toolkit | The air supply races the banking run; first task done cancels the other |
RelicBankedEvent : event(int) |
north-jungle verse-events-custom | Plates Signal, the round loop Awaits — the event bus, zero polling |
athenaeum_progress + weak_map |
east-volcano persistable module | RelicsBanked survives across sessions, per player |
relic_plate_sensor fan-in |
north-jungle Mod Rally checkpoint sensor | One class instance per plate remembers WHICH pedestal it feeds |
SpawnProp + Dispose |
south-shores runtime props | Relics spawn at round start, vanish at round end |
MoveTo swim |
lesson 12 animate-to-targets | Banked relics rise and settle onto their pedestal sockets |
mutator_zone_device + first-person cam |
lesson 7 | First-person below the water line, third-person above |
cinematic_sequence_device |
lessons 17-18 | The reveal cutscene whose tracks flip the hidden wing's data layer |
npc_spawner_device |
lessons 19-20 | Spawns the Warden with your patrol/chase npc_behavior |
matchmaking_portal_device |
center-village hub | Disabled until victory; then the way home to AweShucks Town |
Walkthrough
Stage the island first: the flooded vault sits below a mutator_zone_device water line; each relic pedestal gets a trigger_device pressure plate beside it and a creative_prop pedestal marker; the hidden wing lives on a data layer that only the reveal sequence activates (lesson 18 — no Verse API needed, the sequencer track does it); the Warden's npc_character_definition carries the patrol/chase behavior you wrote in lesson 19, and the reveal sequence contains the control-rig tentacle-sweep keyframes from lesson 20.
Then place the conductor device and paste this in. Read it top to bottom — it is the round loop:
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Playspaces }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
# ─── deeps_kit: the shared-message module — the same ShellHuntKit pattern ───
# you built on south-shores (lesson 9 there), rebuilt for the deep. Every
# string a player reads lives here; the game device only calls helpers.
deeps_kit := module:
WelcomeMsg<public><localizes>:message = "The Athenaeum sleeps below. Press DIVE when your crew is ready."
RelicMsg<public><localizes>(Count:int, Total:int):message = "Relics banked: {Count}/{Total}"
AirMsg<public><localizes>(Seconds:int):message = "AIR: {Seconds}s - bank faster!"
RevealMsg<public><localizes>:message = "The final relic settles... the hidden wing awakens."
VictoryMsg<public><localizes>(Lifetime:int):message = "THE ATHENAEUM IS OPEN! Lifetime relics banked: {Lifetime}"
DrownedMsg<public><localizes>:message = "The air ran out. The Deeps keep their secrets... this round."
WardenMsg<public><localizes>:message = "Something vast just uncoiled in the dark."
# One call sets the text AND shows it — the kit helper shape from lesson 9.
UpdateRelicHud<public>(Hud:hud_message_device, Count:int, Total:int):void =
Hud.SetText(RelicMsg(Count, Total))
Hud.Show()
# Import our own module — the cross-file habit every capstone shares.
using { deeps_kit }
# ── The phase machine (south-shores enum pattern, one state deeper). ──
dive_phase := enum{Lobby, Diving, Reveal, Victory}
# ── east-volcano's persistable module: RelicsBanked survives across sessions. ──
# <persistable> classes are versioned, final, and stored per-player in a
# module-scoped weak_map — the engine saves and reloads them automatically.
athenaeum_progress := class<final><persistable>:
Version:int = 1
RelicsBanked:int = 0
MakeAthenaeumProgress<constructor>(Src:athenaeum_progress)<transacts> := athenaeum_progress:
Version := Src.Version
RelicsBanked := Src.RelicsBanked
var AthenaeumProgressMap:weak_map(player, athenaeum_progress) = map{}
# One sensor per vault plate: Subscribe only hands us the ?agent payload,
# so the sensor remembers WHICH pedestal-plate fired and forwards both.
# (The exact checkpoint-sensor shape from north-jungle's Mod Rally.)
relic_plate_sensor := class:
Game : athenaeum_depths_game
Index : int
OnTriggered(MaybeAgent : ?agent):void =
if (Diver := MaybeAgent?):
Game.OnRelicClaimed(Index, Diver)
# ─── The capstone device: one conductor for the whole two-phase minigame. ───
athenaeum_depths_game := class(creative_device):
# ── Phase 1 devices: the Sunken Dive Round (lesson 8) ──
@editable
DiveButton : button_device = button_device{} # arms the round
@editable
DiveHud : hud_message_device = hud_message_device{} # counter + air + story beats
@editable
RelicPlates : []trigger_device = array{} # vault pressure plates (lesson 4)
@editable
WaterLine : mutator_zone_device = mutator_zone_device{} # the dive threshold
@editable
DiveCam : gameplay_camera_first_person_device = gameplay_camera_first_person_device{} # lesson 7
# ── Phase 2 devices: the relic economy + the reveal (lessons 9-20) ──
@editable
Pedestals : []creative_prop = array{} # banked relics swim here (lessons 11-12)
@editable
RelicAsset : creative_prop_asset = DefaultCreativePropAsset # the relic prefab's stand-in (lesson 13)
@editable
VaultRevealSequence : cinematic_sequence_device = cinematic_sequence_device{} # lessons 17-18
@editable
KrakenSpawner : npc_spawner_device = npc_spawner_device{} # the Warden (lessons 19-20)
@editable
ReturnPortal : matchmaking_portal_device = matchmaking_portal_device{} # home to AweShucks Town
@editable
AirSeconds : int = 90 # the air-supply race timeout
# The galleon airlock players surface to between rounds.
# X=forward, Y=right, Z=up, in Unreal centimetres — match your island.
HomePosition : vector3 = vector3{X := 0.0, Y := 0.0, Z := 500.0}
# ── Round state ──
var Phase : dive_phase = dive_phase.Lobby
var RelicsThisRound : int = 0
var SpawnedRelics : []creative_prop = array{}
# ── The event bus (north-jungle verse-events-custom): plates Signal it,
# the round loop Awaits it. Neither knows the other exists. ──
RelicBankedEvent : event(int) = event(int){}
OnBegin<override>()<suspends>:void =
ReturnPortal.Disable() # the way home opens only on victory
DiveButton.InteractedWithEvent.Subscribe(OnDivePressed)
WaterLine.AgentEntersEvent.Subscribe(OnEnterWater)
WaterLine.AgentExitsEvent.Subscribe(OnExitWater)
KrakenSpawner.SpawnedEvent.Subscribe(OnKrakenSpawned)
# One sensor per plate, each remembering its pedestal index.
for (Index -> Plate : RelicPlates):
Sensor := relic_plate_sensor{Game := Self, Index := Index}
Plate.TriggeredEvent.Subscribe(Sensor.OnTriggered)
DiveHud.SetText(WelcomeMsg)
DiveHud.Show()
# ── Lobby -> Diving: the phase gate stops mid-round re-arms. ──
OnDivePressed(Presser : agent):void =
if (Phase = dive_phase.Lobby):
spawn { RunDiveRound() }
RunDiveRound()<suspends>:void =
set Phase = dive_phase.Diving
set RelicsThisRound = 0
for (Plate : RelicPlates):
Plate.Reset()
Plate.Enable()
SpawnRelicProps()
KrakenSpawner.Enable()
KrakenSpawner.Spawn() # the Warden begins its patrol
UpdateRelicHud(DiveHud, 0, RelicPlates.Length)
# west-coves async toolkit: the air supply RACES the banking run.
# Whichever task finishes first cancels the other — no polling.
race:
AirSupplyCountdown()
AwaitAllRelicsBanked()
if (RelicsThisRound >= RelicPlates.Length):
RevealHiddenWing() # the Phase 2 payoff
else:
DiveHud.Show(DrownedMsg, ?DisplayTime := 4.0)
EndRound()
AirSupplyCountdown()<suspends>:void =
var Air : int = AirSeconds
loop:
if (Air <= 0):
break
Sleep(1.0)
set Air -= 1
if (Air <= 10):
DiveHud.Show(AirMsg(Air), ?DisplayTime := 1.0)
AwaitAllRelicsBanked()<suspends>:void =
loop:
Banked := RelicBankedEvent.Await()
if (Banked >= RelicPlates.Length):
break
# ── A vault plate fired: bank the relic. ──
OnRelicClaimed(Index : int, Diver : agent):void =
if (Phase = dive_phase.Diving):
if (Plate := RelicPlates[Index]):
Plate.Disable() # each relic banks exactly once
set RelicsThisRound += 1
BankLifetimeRelic(Diver) # the write that outlives the session
UpdateRelicHud(DiveHud, RelicsThisRound, RelicPlates.Length)
spawn { SwimRelicToPedestal(Index) }
RelicBankedEvent.Signal(RelicsThisRound)
# east-volcano persistable write: read the old record, store a bumped copy.
BankLifetimeRelic(Diver : agent):void =
if (DiverPlayer := player[Diver]):
var Lifetime : int = 0
if (Existing := AthenaeumProgressMap[DiverPlayer]):
set Lifetime = Existing.RelicsBanked
if (set AthenaeumProgressMap[DiverPlayer] = athenaeum_progress{Version := 1, RelicsBanked := Lifetime + 1}) {}
# The animate-to-targets moment (lesson 12): the banked relic SWIMS home.
SwimRelicToPedestal(Index : int)<suspends>:void =
if (Relic := SpawnedRelics[Index], Pedestal := Pedestals[Index]):
Target := Pedestal.GetTransform()
Lift := Target.Translation + vector3{X := 0.0, Y := 0.0, Z := 150.0}
Relic.MoveTo(Lift, Target.Rotation, 2.0)
Socket := Target.Translation + vector3{X := 0.0, Y := 0.0, Z := 60.0}
Relic.MoveTo(Socket, Target.Rotation, 1.5)
# ── Phase 2: the sequencer plays; its tracks activate the hidden wing's
# data layer and puppet the kraken's control rig (lessons 17-20). ──
RevealHiddenWing()<suspends>:void =
set Phase = dive_phase.Reveal
DiveHud.Show(RevealMsg, ?DisplayTime := 3.0)
VaultRevealSequence.Play()
VaultRevealSequence.StoppedEvent.Await() # hand control back to gameplay
set Phase = dive_phase.Victory
ReturnPortal.Enable() # the way home to AweShucks Town opens
AnnounceLifetimeTotals()
AnnounceLifetimeTotals():void =
Playspace := GetPlayspace()
for (DiverPlayer : Playspace.GetPlayers()):
if (Profile := AthenaeumProgressMap[DiverPlayer]):
DiveHud.Show(DiverPlayer, VictoryMsg(Profile.RelicsBanked), ?DisplayTime := 5.0)
# ── Cleanup + surface: back to Lobby, ready to re-run. ──
EndRound()<suspends>:void =
Sleep(4.0) # let the last relic finish its swim
for (Relic : SpawnedRelics):
Relic.Dispose()
set SpawnedRelics = array{}
KrakenSpawner.Disable()
Playspace := GetPlayspace()
for (DiverPlayer : Playspace.GetPlayers(), FC := DiverPlayer.GetFortCharacter[]):
DiveCam.RemoveFrom(DiverPlayer)
if (FC.TeleportTo[HomePosition, IdentityRotation()]) {}
set Phase = dive_phase.Lobby
DiveHud.SetText(WelcomeMsg)
DiveHud.Show()
# Runtime relics (south-shores SpawnProp): one above each vault plate.
SpawnRelicProps():void =
for (Plate : RelicPlates):
SpawnSpot := Plate.GetTransform().Translation + vector3{X := 0.0, Y := 0.0, Z := 50.0}
SpawnResult := SpawnProp(RelicAsset, SpawnSpot, IdentityRotation())
if (Relic := SpawnResult(0)?):
set SpawnedRelics += array{Relic}
# ── The dive threshold: first-person below, third-person above (lesson 7). ──
OnEnterWater(Diver : agent):void =
DiveCam.AddTo(Diver)
OnExitWater(Diver : agent):void =
DiveCam.RemoveFrom(Diver)
OnKrakenSpawned(Kraken : agent):void =
DiveHud.Show(WardenMsg, ?DisplayTime := 3.0)
Reading the listing
| Section | What to notice |
|---|---|
deeps_kit module |
The game device never builds a HUD string. Same kit discipline as every zone capstone — and the using { deeps_kit } line works identically when the module moves to its own file. |
athenaeum_progress<persistable> |
Versioned, <final>, defaults on every field. The engine snapshots one record per player in AthenaeumProgressMap and reloads it next session — that is the whole persistence system. |
relic_plate_sensor |
TriggeredEvent only hands you ?agent. The sensor object carries the missing WHICH — index in, pedestal out. |
race: |
Two suspending tasks enter, one leaves. Air out → the banking await is cancelled mid-Await; last relic banked → the countdown dies with seconds on the clock. No flags, no polling. |
RelicBankedEvent.Signal / .Await |
The plate handler doesn't know the round loop exists; the round loop doesn't know what a plate is. That decoupling is why you can bolt on a scoreboard later without touching either. |
SwimRelicToPedestal |
Two chained MoveTo calls — rise, then settle. MoveTo is <suspends>, so the settle waits for the rise. That's lesson 12's whole thesis in two lines. |
RevealHiddenWing |
Verse plays the sequence and Awaits StoppedEvent. The sequence's own tracks activate the hidden-wing data layer and drive the kraken rig — the cutscene owns the spectacle, Verse owns the timing. |
EndRound |
Disposal, camera pops, teleport home, phase reset. The leave-cleanup discipline from lesson 5 means a mid-round quitter never strands a relic. |
Device wiring checklist
In the Details panel of athenaeum_depths_game:
- DiveButton → the button on the galleon airlock deck.
- DiveHud → one
hud_message_device, default tracking (all players). - RelicPlates → every vault pressure plate, in the same order as
Pedestals(index N banks to pedestal N — the sensor pattern depends on it). - Pedestals → the pedestal marker props, same count and order as the plates.
- WaterLine → the
mutator_zone_devicevolume at the dive threshold; zone shape covers the whole water surface. - DiveCam → the
gameplay_camera_first_person_device. - RelicAsset → your relic prefab's prop asset (lesson 13).
- VaultRevealSequence → the
cinematic_sequence_deviceholding the reveal Level Sequence; confirm its tracks include the hidden-wing data layer activation (lesson 18) and the kraken control-rig keyframes (lesson 20). Playback set to everyone. - KrakenSpawner → the
npc_spawner_devicewhose character definition uses your lesson-19npc_behavior. - ReturnPortal → the
matchmaking_portal_devicetargeting the AweShucks Town hub island. - AirSeconds → 90 is honest; 60 is cruel; 120 is a guided tour.
- Island settings: enable Use Persistent Storage so the
<persistable>weak_map actually saves.
What this capstone imports
The whole archipelago surfaces here — every line below names the lesson that built it:
- sunken-dive-round (lesson 8): the entire Phase 1 skeleton — plates + loadout teams + first-person cam + air race, now driving Phase 2.
- relic prefab stack (lessons 10-13):
relic_componenton every relic entity, the pedestal parenting from lesson 11, the prefab this device spawns viaRelicAsset. - animate-to-targets (lesson 12): the swim-to-pedestal
MoveTochain. - sequencer + data layers (lessons 17-18): the reveal cutscene and the hidden wing it materializes.
- NPC + control rig (lessons 19-20): the Warden's patrol brain and its cinematic tentacle sweep.
- west-coves async toolkit: the
race {}air-supply timeout and the cancel-safety reasoning behind it. - center-village round logic + teams: the LOBBY→…→LOBBY loop discipline and the Divers/Wardens
team_settings_and_inventory_devicesetup from lesson 6. - east-volcano persistable module:
athenaeum_progress, the versioned copy-constructor, theweak_map(player, …)store. - south-shores SpawnProp + phase enum: runtime relic props and the
dive_phasegate on every handler. - north-jungle event-bus module:
RelicBankedEvent—Signalin the handler,Awaitin the loop.
Common patterns
Pattern 1 — the scene-graph relic_component (lesson 10, capstone edition)
In the full build, each relic in the prefab carries this component; the device's SpawnProp stand-in above keeps the main listing one-paste compilable. The component pulses the relic's glow until it is banked — pure scene-graph, no devices:
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
# The relic_component from lesson 10, trimmed to its capstone role: it rides
# on every relic entity in the prefab and pulses the mesh while un-banked.
relic_component := class<final_super>(component):
var IsBanked : logic = false
Bank():void =
set IsBanked = true
# OnSimulate is the component's async lifetime (runs after OnBeginSimulation).
OnSimulate<override>()<suspends>:void =
loop:
if (IsBanked?):
break
# Pulse the glow: toggle the sibling mesh_component on the entity.
if (Mesh := Entity.GetComponent[mesh_component]):
Mesh.Disable()
Sleep(0.15)
Mesh.Enable()
Sleep(1.2)
OnSimulate is the component's own async lifetime — it starts after OnBeginSimulation and is cancelled automatically when the entity leaves the scene, so the pulse loop can never outlive its relic.
Pattern 2 — the portal gate that reads your lifetime ledger
using { /Verse.org/Simulation }
# The gate Professor AweShucks' portal booth imports: succeeds only when the
# player's PERSISTED lifetime total clears the bar — same <decides> shape as
# west-coves' option-safe lookups and east-volcano's badge checks.
HasBankedRelics<public>(DiverPlayer:player, Needed:int)<decides><transacts>:void =
Profile := AthenaeumProgressMap[DiverPlayer]
Profile.RelicsBanked >= Needed
Because AthenaeumProgressMap is module-scoped and persistable, any device on any future island in the project can import this check — the hub's trophy hall, a New-Game-Plus dive, or the badge wall in AweShucks Town.
The final playtest rubric
Ship-day is a checklist, not a feeling. Run a full session with a friend and tick every line:
- [ ] Dive round completes — DIVE arms only in LOBBY; air countdown shows under 10s; drowning surfaces everyone with the consolation message.
- [ ] Relics animate to pedestals — every plate claim lifts its relic and settles it on the matching pedestal (order check: plate N → pedestal N).
- [ ] Hidden wing reveals — the data layer activates during the sequence, never before it.
- [ ] Cutscene plays — for all players, and
StoppedEventhands control back (no soft-lock in REVEAL). - [ ] Kraken patrols — the Warden spawns on round start, chases carriers per your lesson-19 behavior, despawns at round end.
- [ ] RelicsBanked persists — bank relics, end the session, rejoin: the victory banner shows the old total plus the new.
Six green boxes and the island is real.
Where this goes next
Nowhere — and that's the point. Athenaeum Depths is the terminal capstone: publish it, wire AweShucks Town's matchmaking portal at the booth to its island code, and the archipelago's loop closes — players wash ashore on South Shores with Coral, race Barnaby's jungle, survive Cinder's volcano, debug Inkbeard's coves, and finish here, in the dark, banking relics under a control-rigged kraken. The HasBankedRelics gate and the AthenaeumProgressMap ledger stay importable for whatever you build after the curriculum — your next island starts with a save file your players already earned.