Adding Players Mid-Game Without Weapons and Elimination Rewards in Gun Game Device

Hi everyone,

I’m working on a Gun Game feature using the Verse framework in UEFN (Fortnite). The system works well for players who start at the beginning, but I’m running into issues when new players join an ongoing game.

Here’s the problem:

  • New players that join after the game has started don’t receive weapons.
  • If they are eliminated, the player who eliminates them doesn’t get rewarded with a new weapon, as per the Gun Game rules.

I’m using a PlayerMap to track the weapon tiers and a loop to initialize players when the game begins (InitPlayers function). However, I’m not sure how to properly handle players joining mid-game and ensuring they are integrated into the system with the correct starting weapon.

Has anyone encountered something similar or have ideas on how to:

  1. Properly initialize new players with weapons when they join a game in progress?
  2. Ensure eliminations of late-joining players still grant rewards to the eliminator?

Here’s a snippet of the relevant code for context:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Teams }
using { /Fortnite.com/Game }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/Diagnostics }

This code is a UEFN Fortnite “Device” for managing a Gun Game feature

where players fight online and get a new weapon after each elimination

A Verse-authored creative device that can be placed in a level

game_manager := class(creative_device):

# Map data structure that stores players as the key
# and current WeaponTier as the value
var PlayerMap : [player]int = map{}

# Item granters stored in an array so we can give the player
# new weapons
@editable
var WeaponGranters : []item_granter_device = array{}

# Array of bots for beating up and testing
@editable
var Sentries : []sentry_device = array{}

# This is how we end the game later
@editable
EndGameDevice : end_game_device = end_game_device{}

# Needed to let the game know when to end
var ElimsToEndGame : int = 0

# Runs when the device is started in a running game
OnBegin<override>()<suspends>:void=
    set ElimsToEndGame = WeaponGranters.Length;
    InitPlayers()
    InitTestMode()

InitPlayers() : void=
    AllPlayers := GetPlayspace().GetPlayers()
    for (Player : AllPlayers, FortCharacter := Player.GetFortCharacter[]):
        if (set PlayerMap[Player] = 0, WeaponTier := PlayerMap[Player]):
            FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated)
            GrantWeapon(Player, WeaponTier)

GrantWeapon(Player : player, WeaponTier: int) : void=
    Print("Attempting to grant weapon")
    if (ItemGranter := WeaponGranters[WeaponTier]):
        Print("Granted item to player")
        ItemGranter.GrantItem(Player)

OnPlayerEliminated(Result : elimination_result) : void=
    Eliminator := Result.EliminatingCharacter
    if (FortCharacter := Eliminator?, EliminatingAgent := FortCharacter.GetAgent[]):
        Print("We need to promote player")

PromotePlayer(Agent : agent) : void=
    var WeaponTier : int = 0
    if (Player := player[Agent], PlayerWeaponTier := PlayerMap[Player]):
        set WeaponTier = PlayerWeaponTier + 1
        CheckEndGame(Agent, WeaponTier)

    if (Player := player[Agent], set PlayerMap[Player] = WeaponTier):
        GrantWeapon(Player, WeaponTier)


InitTestMode() : void=
    for (Sentry : Sentries):
        Sentry.EliminatedEvent.Subscribe(TestPlayerElimination)

TestPlayerElimination(Agent : ?agent) : void=
    Print("Sentry eliminated!")
    if (Player := Agent?):
        PromotePlayer(Player)


CheckEndGame(Player : agent, WeaponTier : int) : void=
    if (WeaponTier >= ElimsToEndGame):
        EndGameDevice.Activate(Player)

I appreciate any tips or solutions!

Thanks in advance!

did you ever manage to find the solution for it?

Your InitPlayers method is what handles a majority of the initialization for the gun game associations to a player. It seems you only call it OnBegin, thus it only applies to players who were in the pregame lobby before the game started. You will need to bind that method to players joining in progress.

In your OnBegin add the following line of code anywhere

    GetPlayspace().PlayerAddedEvent().Subscribe(InitPlayersJIP)

Now we are going to duplicate your entire InitPlayers method, and rename it to InitPlayerJIP.
The only difference here is we will be passing the specific player that joins the game in progress, instead of iterating all the players in the playspace. This will be achieved my modifying the parameter of the function to contain Player type. The player is passed by the PlayerAddedEvent automatically.

InitPlayersJIP(Player : player) : void=
        if (set PlayerMap[Player] = 0, WeaponTier := PlayerMap[Player]):
            FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated)
            GrantWeapon(Player, WeaponTier)

This will resolve your join in progress issues. Although it may crop up edge cases where if player leaves a game, and then rejoins the same session, youll run into same issue that you are experiencing now. To avoid that from occurring, you must handle the player leaving the session as well, and remove them from your PlayerMap data structure. This will ensure that they will be reinitialized again appropriately when rejoining previously joined sessions.