How to divide players in 2 teams?

So i will try to make an FPS gamemode and will have 2 teams, the problem is i dont know how to divide players in 2 teams, and those players are selected in a table:

_G.PlayersPlaying = {}

I want to divide PlayersPlaying players in 2 teams, not all players. And i would like that if you could help me, thanks :slight_smile:

1 Like

Well simply get half the player count in the server, and btw don’t use _G.

local player_list = game:GetService("Players"):GetPlayers()
local playing = { }

for i = 1, math.floor(#player_list/2) do
    table.insert(playing, player_list[i])

And then do something with the other half.


This is getting a half of the players in the “playing” table?
I just want to get the players in the “PlayersPlaying” table that are already selected in my script in a team, and the other in other team.
And why i shouldn’t use _G.

Then get half of the player count from that team. :GetPlayers is a method of the Team class still.

_G is an anti-pattern. If you really need to share data across scripts, look into ModuleScripts.

:GetPlayers will select all players in the server, and as i said, i want to select some certain players which are selected in a script and get inserted in a table.

How do you even select them? You said you wanted to get it from a team? Can you stick to one goal please?

Its better if theres an BoolValue inside the player so you can easily divide it to 2 teams

PlayersPlaying are the total of players which has a value called “Playing”, now i want to know how do i get 2 teams and divide those players in 2 teams, :GetPlayers is getting all the players in the server. I already selected the players with the table that i said. And i want to divide in 2 teams those players.

1 Like

How is that, i mean, why i should insert a BoolValue?

Don’t use a BoolValue. It is not needed here.

Then get half the length of that table


1 Like

Here try this:

local team1 = false

for i, v in pairs(game.Players:GetChildren()) do
    if v.Team == game.Teams.PlayersPlaying then
        if team1 == false then
            v.Team = game.Teams.(Insert Team1 here)
            team1 = true
        elseif team1 == true then
            v.Team = game.Teams.(Insert Team2 here)
            team1 = false

Just turn this into a function so you can use it on demand, and it will run through the player list and place every player in the PlayersPlaying team onto one of the two teams. Keep in mind that this isn’t randomizing which players are being put on each team.

Edit: This is checking if the player is set to a team named PlayersPlaying, you can easily replace that check with one checking that they’re in the table.


_G isn’t necessarily an anti-pattern, it’s just a global variable that points to a table. Non-Roblox/Lua globals have little to no utility and with the availability of ModuleScripts, you can just require those instead of putting things in _G.

The thing with _G is that if you aren’t watching carefully what you’re doing, scripts can end up interfering with each other and fighting for a certain key in _G - suppose, two scripts placing and getting items from the index Settings. Both of them use _G.Settings without considering that another chunk may be using it and that leads to unintended issues.

Some items nowadays still use _G effectively by allocating a space under _G and then adding everything to that table instead of just the first layer of _G. Take Aero for example - it does this so that scripts outside the framework can interface with Aero API. Private games can also use this.

The trap with _G is that _G itself is a global and developers tend to forget to assign items they want from _G to a local variable, or they end up misusing it and complain about avoidable issues. Otherwise, _G is not an anti-pattern - it’s just something you probably aren’t meaning to use.

If anything, in the context of this code specifically, it’s a code smell. If physical teams objects aren’t being used, the script can expose methods to fetch the teams tables or it can be a ModuleScript containing a getter method which is loaded by an external script.


Would probably agree, I referred to it as such because of the bad habits it can cause, and plus you might have to worry about it not being ready in another script which can introduce polling and that makes things even uglier:

until _G.Thing ~= nil

There might be a more optimal way of doing it, but that’s what most people stick to

1 Like

The problem of using randomizer is that there might be a little chance of 7/8 players get in a team, and one player will be alone. I thought already about that and will give disvantage to the people.

This method doesn’t necessarily randomize as it’s based off of the order the GetChildren() returns the list as. But it does ensure that the teams are split as evenly as possible, because it goes through that list, puts one player in team 1, then the next in team 2, so the teams will always have an even amount of players.

The first parenthesis [ “(” ]:

v.Team = game.Teams.(Insert Team1 here)

Is marked as red. Showing that at is expected an identifier.

Remove the brackets the entire “(Insert Team1 here)” and replace it with the team name.