Reference Devices compiles

CAPSTONE: Athenaeum Depths — Ship the Island

This is the final capstone of the whole archipelago. Phase 1 is the Sunken Dive Round you built in lesson 8 — plates, teams, first-person dive cam, and an air-supply race{} timeout. Phase 2 is everything The Deeps taught after it: banked relics that swim to their pedestals, a sequencer-driven reveal that flips the hidden wing's data layer, the control-rig kraken in the victory cutscene, and a persistable RelicsBanked ledger that greets returning players by name. One conductor device fuses both phases into a replayable LOBBY → DIVING → REVEAL → VICTORY loop, and the matchmaking portal home to AweShucks Town only opens when the Athenaeum does.

Updated Examples verified on the live UEFN compiler

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:

  1. DiveButton → the button on the galleon airlock deck.
  2. DiveHud → one hud_message_device, default tracking (all players).
  3. RelicPlates → every vault pressure plate, in the same order as Pedestals (index N banks to pedestal N — the sensor pattern depends on it).
  4. Pedestals → the pedestal marker props, same count and order as the plates.
  5. WaterLine → the mutator_zone_device volume at the dive threshold; zone shape covers the whole water surface.
  6. DiveCam → the gameplay_camera_first_person_device.
  7. RelicAsset → your relic prefab's prop asset (lesson 13).
  8. VaultRevealSequence → the cinematic_sequence_device holding 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.
  9. KrakenSpawner → the npc_spawner_device whose character definition uses your lesson-19 npc_behavior.
  10. ReturnPortal → the matchmaking_portal_device targeting the AweShucks Town hub island.
  11. AirSeconds → 90 is honest; 60 is cruel; 120 is a guided tour.
  12. 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_component on every relic entity, the pedestal parenting from lesson 11, the prefab this device spawns via RelicAsset.
  • animate-to-targets (lesson 12): the swim-to-pedestal MoveTo chain.
  • 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_device setup from lesson 6.
  • east-volcano persistable module: athenaeum_progress, the versioned copy-constructor, the weak_map(player, …) store.
  • south-shores SpawnProp + phase enum: runtime relic props and the dive_phase gate on every handler.
  • north-jungle event-bus module: RelicBankedEventSignal in the handler, Await in 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 StoppedEvent hands 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.

Build your own lesson with athenaeum_depths_game

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →