Ballistic : Hide & Seek, a unique game with the rift point device

In this post, i will summarize and explain everything to know about Ballistic : Hide & seek, my brand new uefn game.

Play now : 4794-3777-7251


Thumbnail made by me

The game

  • Ballistic : hide & seek is a game using the rift point device (the ballistic bomb) in a very different way.
  • Instead of placing the bomb at A or B like in any S&D games, here, you can place the bomb anywhere in the map.

Game rules

Players select the gamemode they want to play by voting, there are 2 gamemodes, each with 2 variations (see Game modes).

When the game starts, a player is selected as hider and gets 1:30 to hide the bomb.

  • If they don’t hide the bomb :
    • They receive a score penalty of -1
    • A new hider is randomly selected (can’t be the same twice)

When the bomb is placed, the hider is sent to spectator mode to watch the seekers searching for the bomb.
The seekers have 2:30 to find the bomb before the explosion.

  • If the time is up :
    • A cinematic plays, showing the bomb exploding.
    • The hider scores 1 point (no one found the bomb).
    • A new hider is selected (can’t be the same twice).

  • If a seeker finds the bomb :
    • The finder scores 1 point from finding the bomb.
    • The finder is selected as hider for the next round.

Game modes

  • Score gamemode
  • The first player to reach the score objective wins and the game ends.
    • 3 points to win.
    • 5 points to win.

  • Rounds gamemode
  • A selected number of rounds, most points wins.
    • 5 rounds.
    • 10 rounds.

Game development

After some experimentation with the rift point volume devices, this game idea came to my mind, here is an overview of how i made it


The first step was to create the main verse code, i called it the “round manager”.
At first, this device was just a gameplay loop. The game would just never end.
This first version of the code is the core gameplay of the game, this is the code managing who gets to hide the bomb each rounds and responsible of starting the hiding and seeking phases.


A game that never ends would not be fun, so i added wins conditions.
Since i had different ideas in mind for the game conditions, why not implement all of them with a voting system to choose the gamemodes?
And that’s why i created the “gamemode vote” verse device :

disclaimer, this code is specifically built for my map, but can easily be remixed for any kind of voting system
This code also requires a Wrapper Agent function

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Random }
using { /UnrealEngine.com/Temporary/Diagnostics }

# See https://dev.epicgames.com/documentation/en-us/uefn/create-your-own-device-in-verse for how to create a verse device.
ToMessage<public><localizes>(Integer:int)<varies>:message = "{Integer} votes"
ToMessageButSingleVote<public><localizes>(Integer:int)<varies>:message = "{Integer} vote"

# A Verse-authored creative device that can be placed in a level
gamemode_vote_device := class(creative_device):

    @editable   GamemodeVoteButtons : []button_device = array{}
    @editable   VotesBillboards : []billboard_device = array{}
    @editable   VotedAudio : audio_player_device = audio_player_device{}
    
    var PlayerVoted : [player]int = map{}
    var TotalVotes : []int = array{}
    var MostVoted : []int = array{}

    var ScoreGamemode : logic = false
    var RoundsGamemode : logic = false
    var ScoreObjective : int = 3
    var RoundsNumber : int = 5
    # Runs when the device is started in a running game

    OnBegin<override>()<suspends>:void=
        for(Index-> VoteButton : GamemodeVoteButtons):
            VoteButton.InteractedWithEvent.SubscribeAgent(PlayerVote, Index)
        for(VotesBillboard : VotesBillboards):
            VotesBillboard.SetText(ToMessage(0))

    BeginVote(PlayersInVote : []player) : void =
        set PlayerVoted = map{}
        set TotalVotes = array{0, 0, 0, 0}
        set ScoreGamemode = false
        set RoundsGamemode = false
        for(Player : PlayersInVote):
            if(set PlayerVoted[Player] = -1) {Print("added a player in")}
        for(VotesBillboard : VotesBillboards):
            VotesBillboard.SetText(ToMessage(0))
        for(VoteButton : GamemodeVoteButtons):
            VoteButton.Enable()

    CalculateVotes() : void =
        for(VoteButton : GamemodeVoteButtons):
            VoteButton.Disable()
        set MostVoted = array{}
        var TempBestVote : int = 0
        for(id -> Vote : TotalVotes):
            if(Vote > TempBestVote):
                set MostVoted = array{id}
                set TempBestVote = Vote
            else if(Vote = TempBestVote):
                set MostVoted = MostVoted + array{id}
                set TempBestVote = Vote
        if(FinalResult := MostVoted[GetRandomInt(0, MostVoted.Length-1)]):
            if(FinalResult = 0):
                set RoundsGamemode = true
                set RoundsNumber = 5
            if(FinalResult = 1):
                set RoundsGamemode = true
                set RoundsNumber = 10
            if(FinalResult = 2):
                set ScoreGamemode = true
                set ScoreObjective = 3
            if(FinalResult = 3):
                set ScoreGamemode = true
                set ScoreObjective = 5

            Print("{FinalResult}")
    
    PlayerVote(Agent : agent, Option : int) : void =
        VotedAudio.Play(Agent)
        if(Player := player[Agent]):
            if(PreviousPlayerVote := PlayerVoted[Player]):
                if(set TotalVotes[PreviousPlayerVote] -= 1) {}
            if(set PlayerVoted[Player] = Option):
                if(set TotalVotes[Option] += 1) {}
            UpdateBillboards()

    UpdateBillboards() : void =
        for(id -> Billboard : VotesBillboards):
            if(VoteNumber := TotalVotes[id]):
                if(VoteNumber = 1):
                    Billboard.SetText(ToMessageButSingleVote(VoteNumber))
                else:
                    Billboard.SetText(ToMessage(VoteNumber))

This code is a “global function” verse code, those functions can be used by every single verse device in the world.
The voting device uses the SusbcribeAgent global function.

using { /Verse.org/Simulation }

(Listenable : listenable(agent)).SubscribeAgent(OutputFunc : tuple(agent, t)->void, ExtraData : t where t:type) : cancelable =
    Wrapper := wrapper_agent(t){ExtraData := ExtraData, OutputFunc := OutputFunc}
    Listenable.Subscribe(Wrapper.InputFunc)
 
wrapper_agent(t : type) := class():
    ExtraData : t;
    OutputFunc : tuple(agent, t) -> void
    InputFunc(Agent : agent):void = OutputFunc(Agent, ExtraData)

(Listenable : listenable(?agent)).SubscribeMaybeAgent(OutputFunc : tuple(?agent, t)->void, ExtraData : t where t:type) : cancelable =
    Wrapper := wrapper_maybe_agent(t){ExtraData := ExtraData, OutputFunc := OutputFunc}
    Listenable.Subscribe(Wrapper.InputFunc)
 
wrapper_maybe_agent(t : type) := class():
    ExtraData : t;
    OutputFunc : tuple(?agent, t) -> void
    InputFunc(Agent : ?agent):void = OutputFunc(Agent, ExtraData)
 
(Listenable : listenable(tuple())).SubscribeEmpty(OutputFunc : t -> void, ExtraData : t where t:type) : cancelable =
    Wrapper := wrapper_empty(t) {ExtraData := ExtraData, OutputFunc := OutputFunc}
    Listenable.Subscribe(Wrapper.InputFunc)
 
wrapper_empty(t : type) := class():
    ExtraData : t;
    OutputFunc : t -> void
    InputFunc():void = OutputFunc(ExtraData)

I worked a lot on the user interface. including a score board you can open anytime during gameplay, timers, round winner, final winner, final leaderboard and more.



This game contains multiple maps to play on. A city and a cube map (might not be able to add more maps as i exceeded 75-80% of island memory).
The maps are randomly selected each round by the main verse device.



If the bomb is not found, a little cinematic will play to show where the bomb was hidden.
This is done by using a cinematic camera parented to an invisible prop. This prop is teleported to the hider location when the bomb is planted, saving the localisation of the bomb to know exactly where to play the cinematic.


Fututre of the game

The major change already planned for this game is to upgrade the spectator mode. Including more than just spectating players searching for the bomb.
I want to add the ability to spectate the bomb itself and be able to see players getting close to it.


Bonus facts

The city map contains a secret environmental storytelling, can you find it ? (Hint : clothes stores) :eyes:
The city map contains a prefab that I have rebuilt mirrored, with a missing floor.



The entire game was made by me, and just me. Verse code, maps, UI, cinematics and thumbnails are all done by a team of 1.


I hope you enjoy the game, leave a feedback or ask me anything you want to know about the game, and thx for reading!