How to make Team Balanced?

  1. What do you want to achieve?
    When a countdown is finished, a script will assign players to 2 teams, Orange and purple but the teams are fair and even.

  2. What is the issue?
    I dont know how to make the teams even

  3. What solutions have you tried so far?
    the script (only randomizes, doesn’t even out the teams):

local players = game:GetService("Players")


while wait() do
	if #players:GetPlayers() > 0 then-- if there are more than 0 players then begin the match (for testing purposes)
		wait(15)
		local number = math.random(1)
		if number == 1 then-- going to be used for map selection
			print("Round Started.")


			local teams = game:GetService("Teams")

			local Orange = game.ServerStorage.Orange:Clone()
			Orange.Parent = game.Teams
			local Purple = game.ServerStorage.Purple:Clone()
			Purple.Parent = game.Teams

			local players = game.Players:GetPlayers()
			local PurplePlayers = Purple:GetPlayers()
			local OrangePlayers = Orange:GetPlayers()

			local teams = game:GetService("Teams"):GetTeams()
--the problem-------------------------------------------------------------------------
			for i, players in pairs(players) do
				local random = math.random(1,2)
				if random == 1 then
					players.TeamColor = BrickColor.new("Deep orange")
					wait(1)

				else if random == 2 then
						players.TeamColor = BrickColor.new("Royal purple")
						wait(1)

					end
				end	
			end
			
			
			
			
			
--------------------------------------------------------------------------------			
			wait(30)-- End of round
			print("Round Ended")
			Purple:Destroy()
			Orange:Destroy()
			for i, players in pairs(players) do
				players.TeamColor = BrickColor.new("Black")
			end
	end
	end
	end





			
			
			
			
			
			
2 Likes

Here’s some pseudo-code. If you can’t figure out what it’s doing let me know. Let’s assume there’s a lobby team.

local LobbyTeam = game.Teams.Lobby
local Teams = {
    game.Teams.Red,
    game.Teams.Blue,
}

local Player

function balanceTeams()
    local Players = game:GetService('Players'):GetChildren()
    local PlayerCount = (#Players)
    
    --favors red in the event of an uneven amount of players
    local RedCount = math.floor((PlayerCount/2) + 0.5)     
    local BlueCount = math.floor(PlayerCount/2)

    repeat
        repeat
            Player = game:GetService('Players')[math.random(1, PlayerCount)
        until Player.Team ~= game.Teams.Lobby

        Player.Team = Teams[1]
    until #(Teams[1]:GetPlayers()) == RedCount

    repeat
        repeat
            Player = game:GetService('Players')[math.random(1, PlayerCount)
        until Player.Team ~= game.Teams.Lobby
        Player.Team = Teams[2]
   until #(Teams[2]:GetPlayers()) == RedCount
end

Do note that this is untested and I’m not sure if it’ll work, but you likely get the point. Also not super optimized.

Alternatively, check this out. Implementing Teams | Documentation - Roblox Creator Hub

2 Likes

Yeah if you use this code @DybalaplaysYT You will definitely want to optimize it.

how would I add the countdown to this?
(complete script from Implementing Teams | Documentation - Roblox Creator Hub)



    local TeamsService = game:GetService("Teams")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
     
    local balanceTeamsEvent = Instance.new("BindableEvent")
    balanceTeamsEvent.Name = "BalanceTeamsEvent"
    balanceTeamsEvent.Parent = ReplicatedStorage
     
    local friendGroups = {}
     
    -- Merge all mutual friend groups into one
    local function mergeGroups(groups)
    	-- Add other group members to the first group
    	for i = 2, #groups do
    		for _, user in pairs(friendGroups[groups[i]]) do
    			table.insert(friendGroups[groups[1]], user)
    		end
    		-- Remove leftover groups that were merged
    		table.remove(friendGroups, groups[i])
    	end
     
    	return groups[1]
    end
     
    -- When players join the game, determine the correct team to join
    local function assignInitialTeam(player, group)
    	-- Check if the player belongs in a group and the group isn't larger than a fair team size
    	if group and #group < game.Players.MaxPlayers / 2 then
    		player.Team = group[1].Team
    	else
    		local teams = TeamsService:GetTeams()
    		table.sort(teams, function(a, b) return #a:GetPlayers() < #b:GetPlayers() end)
    		player.Team = teams[1]
    	end
    end
     
    -- Group friends to keep them on the same team
    local function groupFriends(player)
    	local mutualGroups = {}
     
    	-- Iterate through friend groups
    	for groupIndex, group in ipairs(friendGroups) do
    		-- Iterate through friends found in groups
    		for _, user in ipairs(group) do
    			-- Group mutual friends together
    			if player:IsFriendsWith(user.UserId) then
    				if (mutualGroups[group] == nil) then
    					table.insert(mutualGroups, groupIndex)
    				end
    			end
    		end
    	end
     
    	if #mutualGroups > 0 then
    		local groupIndex = mutualGroups[1]
     
    		-- If the player has multiple groups of friends playing, merge into one group
    		if #mutualGroups > 1 then
    			groupIndex = mergeGroups(mutualGroups)
    		end
     
    		table.insert(friendGroups[groupIndex], player)
    		assignInitialTeam(player, friendGroups[groupIndex])
    	else
    		table.insert(friendGroups, {player})
    		assignInitialTeam(player)
    	end
    end
     
    -- Clean up groups when a player leaves the game
    local function removeFromGroup(player)
    	-- Loop through the friend groups to find the player
    	for groupIndex, group in ipairs(friendGroups) do
    		for userIndex, user in ipairs(group) do
    			if user.Name == player.Name then
    				-- Remove them from whatever group they exist in
    				friendGroups[groupIndex][userIndex] = nil
    				-- If the group is empty, remove it
    				if #friendGroups[groupIndex] == 0 then
    					friendGroups[groupIndex] = nil
    				end
    			end
    		end
    	end
    end
     
    local function balanceTeams()
    	local teams = TeamsService:GetTeams()
     
    	-- Sort the groups so that larger groups are first
    	table.sort(friendGroups, function(a, b) return #a > #b end)
     
    	-- Iterate through friend groups (already sorted from largest to smallest)
    	for i = 1, #friendGroups do
    		-- If the group is too big, split them into both teams
    		if (#friendGroups[i] > game.Players.MaxPlayers / 2) then
    			for _, player in pairs(friendGroups[i]) do
    				table.sort(teams, function(a, b) return #a:GetPlayers() < #b:GetPlayers() end)
    				player.Team = teams[1]
    			end
    		else
    			-- Sort the list of teams to have the smallest team first
    			table.sort(teams, function(a, b) return #a:GetPlayers() < #b:GetPlayers() end)
    			local groupTeam = teams[1]
     
    			-- Place everyone in the group on the same team
    			for _, player in pairs(friendGroups[i]) do
    				player.Team = groupTeam
    			end
    		end
    	end
    end
     
    -- Connect "PlayerRemoving" event to the "removeFromGroup()" function
    game.Players.PlayerRemoving:Connect(removeFromGroup)
     
    -- Connect "PlayerAdded" events to the "groupFriends()" function
    game.Players.PlayerAdded:Connect(groupFriends)
     
    balanceTeamsEvent.Event:Connect(balanceTeams)