How to assign spawned players to a random team with no two people in the same team each round

Context:
I am trying to create a map, where upon spawning a player is assigned to a random team. Team size should be set to one and no two players should be on the same team during a round. After the round, the players should all respawn (hopefully) in a new team.

I am very new to Fortnite Game Creation and only recently started learning Verse. Therefore, I am sure my Code will have mistakes. I tried randomizing the assigned team by using a stack, where the teams are shuffled, then pushed onto the stack. Then the Event, when a player spawns, should pop a team from the stack and assign it to the agent.

Two issues:
AddToTeam throws this error and I don’t know what to do about it:
This function parameter expects a value of type tuple(agent,team), but this argument is an incompatible value of type tuple(agent,type{_():tuple(stack(team),team)}).(3509)

RandomTeam:type{_():tuple(stack(team),team)}

And I would like to move the part where the stack is initialized with the random teams to the onBegin block, because otherwise I think it will fill the stack with values each time a player spawns, which is not its purpose. Moving the block to the onBegin function threw a Unknown identifier error. I tried moving them to before the onBegin function and set its domain value, but that threw a different error.

Any help is appreciated.

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

# Tags on spawner devices in map
spawner := class(tag){}

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

    # The amount of team settings devices in the map
    AmountOfTeamSettings : int = 3
    
    OnBegin<override>()<suspends>:void=
        Spawners := GetCreativeObjectsWithTag(spawner{})
        for (Obj : Spawners):
            if (Spawner := player_spawner_device[Obj]):
                Spawner.SpawnedEvent.Subscribe(OnPlayerSpawned)
    
    OnPlayerSpawned(Agent : agent):void=
        TeamCollection:= GetPlayspace().GetTeamCollection()
        AllTeams := TeamCollection.GetTeams()
        
        # Create Stack that will hold all the teams
        var TeamStack:stack(team) = stack(team){}

        # Randomize Teams
        RandomTeams := Shuffle(AllTeams)

        # Push the randomized teams onto the stack
        for (Index := 0..AmountOfTeamSettings-1):
            if(TeamStack.Push(RandomTeams[Index])):

                # Get the first team in the stack and assign to spawned player
                RandomTeam := TeamStack.Pop
                if(TeamCollection.AddToTeam[Agent, RandomTeam]):
                    Print("Player Spawned")
    

# Stack that supports any type.
stack<public>(t:type) := class<computes>:
    Items<public>:[]t = array{}
     
    Push<public>(Item:t)<computes>:stack(t)=
        stack(t){ Items := Items + array{Item} }
     
    Pop<public>()<decides><computes>:tuple(stack(t), t)=
        Ret:t = Items[Items.Length - 1]
        (stack(t){ Items := Items.RemoveElement[Items.Length - 1] }, Ret)

For your first issue:
If I understand your code right your TeamStack.Pop should be returning tuple(stack(team), team) which means on the next line where you try to add the agent to team your arguments are (agent, (stack(team), team)) instead of (agent, team). you need to parse out your tuple to get your stack and your team, then call AddToTeam with your agent and team.

This is one of the down fall of being to reliant on using inferred typing with ‘:=’ instead of choosing the type yourself with ‘: =’ you may not be getting what you think you are.

For your second issue:
I’m less sure about this one, but… Yes, you probably need your TeamStack to be initializing in OnBegin() and make it a field in your game_manager class so it has persistence throughout the game.

Honestly, thank you for the reply. In the end I chose the easy way and just used the custom rng device code in the repository. I tried to write the code in verse, because the rng device was very inconsistent for me

For anyone wondering if this is possible. I finished the code and submitted it to the code repository. Waiting for it to be reviewed

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.