Why some players are being given 2-3 weapons

I’m having a problem where some players are being given multiple weapons, instead of just 1

This is what I do to organise the teams

local function putInTeam(player)
	local RedTeamPlayerCount = #Teams.Red:GetPlayers()
	local BlueTeamPlayerCount = #Teams.Blue:GetPlayers()
	
	if BlueTeamPlayerCount < RedTeamPlayerCount then
		player.Team = Teams.Blue
	elseif RedTeamPlayerCount < BlueTeamPlayerCount then
	   	player.Team = Teams.Red
	else
		local CoinFlip = math.random()
		
		if CoinFlip < 0.5 then
			player.Team = Teams.Red
		else
			player.Team = Teams.Blue
		end
	end
	
	table.insert(Settings.ACTIVE_PLAYERS, player)
	
	ClassesManager:GiveClass(player)
	MapManager:ToMap(player)
end

function TeamsManager:OrganizeTeams()
	for _, player in pairs(Players:GetPlayers()) do
		if not player then return end
		
		putInTeam(player)
	end
end

function TeamsManager:NewPlayerTeam(player) -- Fires when a player joins mid round
	if not player then return end
	
	putInTeam(player)
end

And then the class stuff

local function giveWeapon(player, class)
	local User = PlayerData[player.UserId]
	if not User then return end
	
	local EquippedWeapon = User.Classes[class].Equipped.Weapon
	local Weapon = Classes[class].Weapons:FindFirstChild(EquippedWeapon):Clone()
	
	Weapon.Parent = player.Backpack
end

function ClassesManager:GiveClass(player)
	local User = PlayerData[player.UserId]
	if not User then return end

	giveWeapon(player, User.EquippedClass)
end

It seems to always give 1 player multiple weapons. Tested with 2 players, 1 player got the 2 weapons, tested with 3 players, 1 got 2 weapons, etc. So is there something I’m doing wrong in terms of getting their teams?
Upon further testing, I added print(player) at the end of the putInTeams function, and this is what I got with 3 players
Player2

Player3

Player1

Player2

Player3

So for some reason, Player2 an Player3 are going thru twice??

EDIT I believe the problem occurs if a player joins mid game. So looking at this in particular

local function putInTeam(player)
	local RedTeamPlayerCount = #Teams.Red:GetPlayers()
	local BlueTeamPlayerCount = #Teams.Blue:GetPlayers()
	
	if BlueTeamPlayerCount < RedTeamPlayerCount then
		player.Team = Teams.Blue
	elseif RedTeamPlayerCount < BlueTeamPlayerCount then
	   	player.Team = Teams.Red
	else
		local CoinFlip = math.random()
		
		if CoinFlip < 0.5 then
			player.Team = Teams.Red
		else
			player.Team = Teams.Blue
		end
	end
	
	table.insert(Settings.ACTIVE_PLAYERS, player)
	
	ClassesManager:GiveClass(player)
print('Given player team', player, player.Team)
	MapManager:ToMap(player)
end

function TeamsManager:NewPlayerTeam(player) -- Fires when a player joins mid round
	if not player then return end
	print('New player joined', player)
	putInTeam(player)
end

MORE EDITS A new problem
Given player team Player2 Blue

New player joined Player1

Given player team Player1 Red

New player joined Player2

Given player team Player2 Red

It’s putting player2 in blue, player1 in red, then putting player2 in red?? New player joined Player2 should NOT be firing, as they have already been added into the game, so why is it redoing them?

1 Like

I haven’t taken too close of a look, but if you’re in need of a band-aid fix you can do a quick check to see if the tool already exists in their backpack, and if so don’t give it.

I still would get another issue of players switching

Mentioned just at the end of my post

From what I understand is that P2 is already in the game, P1 joins and P2 is immediately re-assigned to the red team (when P2 was originally on blue). Looking at your putInTeam function, seems it goes to the else statement since Blue/Red would both be even at 1 player (and that would be the only way P2 is re-assigned to red, due to chance). Out of curiosity, are you invoking TeamsManager:NewPlayerTeam… multiple times per player join? For example, Player X joins and it will not just call that for Player X, but for all other players in the game.

local function playerAdded(player)
	if Settings.GAME_RUNNING then
        print(player, 'has joined mid game'
		repeat wait() until player.Character
		
		TeamsManager:NewPlayerTeam(player)
	end
end

The print prints for both Player1 and Player2. The thing is tho,

TeamsManager:OrganizeTeams()
Settings.GAME_RUNNING = true

GAME_RUNNING isn’t set to true until the teams have been organized, so when they both join it SHOUDLN’T be running the function inside the playerAdded, as they should already be put on their teams before the setting has ever been set to true

I see, are you organizing the teams just once (ex when the server starts up when the first player joins)?

Can’t tell if that snippet is on its own or part of something else

The snippet is from a function that basically puts everything together to start the round.

function GameManager:StartRound()
	local Map = MapManager:RandomMap()
	Gamemode = GamemodeManager()
	
	Settings.GAMEMODE = Gamemode.Name
	DisplayManager:SetStatus('Starting game!', false)
	DisplayManager:SetMap(Map.Name, Map.Builder.Value, Map.Image.Value, Gamemode.Name)

	Map.Name = 'Map'
	
	if Gamemode.Name ~= 'King of the Hill' then 
		if Map:FindFirstChild('KingFlag') then
			Map.KingFlag:Destroy()
		end
	end
	
	if Gamemode.Name ~= 'Capture the Flag' then 
		if Map.BlueCastle:FindFirstChild('Flag') then
			Map.BlueCastle.Flag:Destroy()
		end
		
		if Map.RedCastle:FindFirstChild('Flag') then
			Map.RedCastle.Flag:Destroy()
		end
	end
	
	wait(4)
	
	TeamsManager:OrganizeTeams()
	Settings.GAME_RUNNING = true
	DisplayManager:SetHUD(Settings.GAME_RUNNING)
end

The idea is, every player in the server should be placed on a team via this code. The playerAdded function

local function playerAdded(player)
	if Settings.GAME_RUNNING then
        print(player, 'has joined mid game'
		repeat wait() until player.Character
		
		TeamsManager:NewPlayerTeam(player)
	end
end

Should only be fired if a player joins like midway thru a game (so they don’t have to wait for the next round)

Alright thanks, I’m a little puzzled too. I’m assuming Settings.GAME_RUNNING is properly reset back to false and starts as false. The only way I can see the situation happening in the bottom of your original post where already assigned players are re-assigned mid-round is OrganizeTeams being invoked somewhere else, since that affects all players already in the game with the loop. Hopefully somebody else can shed some light!

You shouldn’t use repeat wait() until player.Character. There is a much more efficient method.

  if not player.Character then
    player.CharacterAdded:Wait()
  end

Or more concisely

... = player.Character or player.CharacterAdded:Wait()

But this topic is a bit old and I don’t think that pertains to OP’s issue.

1 Like