1 v Multiple Team System

SNIPPET TITLE: 1 v Multiple Team System
SKILL LEVEL: Medium
Many thanks to JCtapuk and tennisace387 for their help in spotting bugs and areas for optimization of this code.

I've seen a few people ask on the Core Discord how to set up a 1 v multiple team system so I thought it would be a great learning opportunity to post the example I wrote for them here.

WHAT DOES IT DO?:
This script handles the functionality for a team system in which one player is placed on a different team from the rest of the players

EXAMPLE USE CASES:
A horror game where one player is the monster and the rest of the players have to hide from the monster player. Hiding players should be able to damage the monster but not each other.

SETUP
To set this script up you will need to place it within a Server Context or enable networking for it so that it has the permission to modify player teams. Also, you would run into many more issues with timing if this was running on a client. I also would also suggest that you remove any pre-existing code you have that modifies player teams.

BASE SNIPPET

local soloPlayer = nil
local otherPlayers = {}

local SOLO_TEAM = 1
local EVERYONE_ELSE_TEAM = 2


function OnPlayerJoined(player)
    print("player joined: " .. player.name)
    -- Load server variables
    if(soloPlayer == nil) then
        --Assign the player to the solo team
        player.team = SOLO_TEAM
        --Update the "soloPlayer" variable with the new player on the SOLO team
        soloPlayer = player
      else
        --Assign the player to the non-solo player team
        player.team = EVERYONE_ELSE_TEAM  
        --add this player to the "otherPlayers" list
        otherPlayers[player.id] = player
    end
end
function ScramblePlayers()
    --Get list of players in game
    local playerList = Game.GetPlayers()
    --Choose a random index in this list that will be the solo player
    local randIndex = math.random(1, #playerList)
    --Update the teams of all players
    for index, player in ipairs(playerList) do
      --If the index is equal to the "randIndex" set the player to the solo team
      if(index == randIndex) then
        player.team = SOLO_TEAM
      --Set the teams of the others players to the "EVERYONE_ELSE_TEAM"
      else
         player.team = EVERYONE_ELSE_TEAM 
      end
    end
end
function OnPlayerLeft(player)
    print("player left: " .. player.name)
     --Check if the solo player left
     if(player == soloPlayer) then
       --Reset the "soloPlayer" to nil so that, if necessary, it can be assigned when the next player joins
        soloPlayer = nil
       --Get the first player in the "otherPlayers" list and set their team to the SOLO team
        for key, value in pairs(otherPlayers) do
          --This if statement confirms that the player stored in "value" is still valid and is
         --not trying to leave game currently
              if( Object.IsValid(value) ) then
                  value.team = SOLO_TEAM
                  soloPlayer = value
                  --Remove this player from the "otherPlayers" list

                 otherPlayers[value.id] = nil

                  break
             end
        end
      else
        --Remove this player from the "otherPlayers" list
        otherPlayers[player.id] = nil
      end
end
-- on player joined/left functions need to be defined before calling event:Connect()
Game.playerJoinedEvent:Connect(OnPlayerJoined)
Game.playerLeftEvent:Connect(OnPlayerLeft)

FEEDBACK
Please comment if you have any ideas about optimizations and or features that could be added to this script (for example, changing the solo player's team when they die).

VERSION
1.0.0
First Version

1.1.0
Added a ScramblePlayers() function that randomizes player teams upon execution.

3 Likes