How to Sort Players into teams

As the title says, I am trying to figure out a way to Sort Players into Teams.

So I have teams, but it changes, There is always a Spectators Team, but it varies on what the other teams are, it might be just a single FFA team, or it might be a Team vs Team so I’d have 2 teams, or Team v Team v Team so I’d have 3 other teams (you get the idea)…But I don’t know how to evenly sort players into the teams.

Any help on how to evenly sort teams would be much appreciated! :slight_smile:

4 Likes

Can’t you just loop thru the teams and whichever team has the least amount of members gets the new player?

Probably, which leads me to my second question…How would I do so?

If you aren’t using TeamService (which would handle all of this for you), I assume you are keeping track of each team and it’s players, probably in a table like this

local teams = {
    Red = {
        Players = {}--list of current players
    },
    Blue= {
        Players = {}--list of current players
    },
}

Since you would update team.Players whenever a player is added or removed, you can just loop thru each team’s player table and count.

local function GetTeam()
	local team
	local least = Teams.MAX_TEAM_MEMBERS + 1
	for team_name, team in pairs(team) do
		if #team.Players < least then
			team = team
			least = #team.Players
		end		
	end
	return team or teams.Blue -- (a default team, or a fallback function)
end
5 Likes

Typed these two up. The first one isn’t as random as the second.

function RandomizeTeams(players, ...)
    if #players > 0 then
        
      local teams = { ... };
      local currentTeamIndex = 1; -- lua tables start at 1 =(

      for _, player in pairs (players) do
        player.TeamColor = team[currentTeamIndex].TeamColor;
        currentTeamIndex += 1;

        if currentTeamIndex > #teams then
          currentTeamIndex = 1;
        end;
      end;
    end;
end;

Here’s what the completely random one should look like:

function CloneTable(table)
  local table2 = { }
  for key, value in pairs (table) do
    table2[key] = value;
  end;

  return table2;
end;

function RandomizeTeams(players, ...)
    if #players > 0 then
        
      local teams = { ... };
      local currentTeamIndex = 1; -- lua tables start at 1 =(
      local playersCopy = CloneTable(players);

      while #playersCopy > 0 do
        
        local targetPlayer = math.random(1, #playersCopy);
        playersCopy[targetPlayer].TeamColor = team[currentTeamIndex].TeamColor;
        currentTeamIndex += 1;

        if currentTeamIndex > #teams then
          currentTeamIndex = 1;
        end;

        table.remove(playersCopy, targetPlayer);
      end;
    end;
end;

Usage:

-- GetReadyPlayers() - some function to get players that have a status of ready
RandomizeTeams( GetReadyPlayers(), game.Teams.Green, game.Teams.Blue )

The first argument can be practically any table that contains Player objects. You can have as many teams as you want after the 1st argument so you can have “team1 vs team2” or “team1 vs team2 vs team3”.

1 Like
-- (Was) Untested, should work regardless of the teams before the shuffle
-- Well, had some errors, fixed/updated a few years later :')

local PlayersService = game:GetService("Players")
local TeamsService = game:GetService("Teams")

local rng = Random.new()

local function shuffleTeams()
	
	local playerPool = PlayersService:GetPlayers()
	local teams = TeamsService:GetTeams()
	
	-- Storing the counts seperately, so it works with players on teams
	local count = table.create(#teams, 0)
	local maxCount = math.ceil(#playerPool/#teams)
	
	for _, player in pairs(playerPool) do
		
		local num = rng:NextInteger(1, #teams)
		
		player.Team = teams[num]
		count[num] += 1
		
		if (count[num] == maxCount) then
			table.remove(teams, num)
			table.remove(count, num)
		end
		
	end
end
4 Likes

You could use the modulo to initially assign players into teams fairly and evenly, but compare team sizes if you want players to join mid-round.

One option is to iterate through each player and add them into a table/array, assign a number to each team regardless of name (team1, team2, team3, etc), and add them to the team if their array position % the number of teams equals zero. For example, if there’s 4 teams, the player at position 4 would be assigned to team 4, whereas player 5 would be added to team 1.

This would evenly split the teams, but you can randomly shuffle the table of players each round to prevent the same players from being assigned to the same teams unless the list of players in game changes.

I hope this is useful! :slightly_smiling_face:

1 Like

Solved it! Thanks to all who sent help. :slight_smile:

2 Likes