Players randomly disappearing out of list

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    First, I’d like to say I am relatively new to scripting so I am sorry if any of the code you see is unorganized. I have a round system for starting rounds in my badminton/tennis-like game. To start a round, you have to go to these boxes, and once all the boxes are filled, the players are entered into a round through a module script.
    (You can see the white boxes here)


    When someone serves, scores a point, or wins, text will pop up. Once the round ends, players are teleported back. Therefore, I need to store the player objects somewhere so I can send remote events to them and also teleport their characters to a point. I store them in these lists in the module scripts. Every round is stored as a list in the round module script with a different ID.

  2. What is the issue? Include screenshots / videos if possible!
    The issue arises when players try to start a round using the boxes I mentioned earlier. I mentioned earlier how these players are stored in the list. The problem is that they randomly disappear out of the list less than a second after the round starts.


    This is the same list being printed out multiple times, but as you see, the bottom one is empty, which means the players got removed from it. I’d like to mention that this bug does not occur if I start a round outside of the touch pads and just grab the players from the player service through a script like this.
    image
    This only happens if I start a round using the touch pads, but I haven’t changed anything about the touch pads since Wednesday, and on Wednesday the game was working perfectly fine, players were not removed from the list. I am really confused as to why this is happening, since I don’t think I attempt to remove players from this list anywhere in the module script.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried repeatedly printing out the list to find out where the bug occurs and the players get removed from the list. I have found out that they do not seem to get removed through the module script, as it happens at different times each time. At first, I thought it was linked to the serve function, since it kept happening there, but when I put a task.wait() before the serve, the players were still removed from the list. This makes me think that the problem is linked to another script. However, the only script that runs before this round script tries to start the round is the touch pad queue script. As I mentioned above, this script has received little to no change since Wednesday, when the game worked fine. The script that changed the most was the round module, so I don’t know why they’re disappearing like this. I’ve attached both the round module script and the touch pad script.

Round ModuleScript

local Round = {}
local StarBall = require(script.Parent.StarBallModule)
Round.Rounds = {}
Round.Connections = {}

local metatable = {
	
}

Round.RoundEnum = {
	Team = {
		Team1 = "Team1",
		Team2 = "Team2"
	},
	Status = {
		Starting = "Starting",
		Rallying = "Rallying",
		Point = "Point",
	}
}

Round.BallEnum = {
	Status = {
		Serve = "Serve"
	}
}


local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Assets = ReplicatedStorage.Assets
local ServerStarBall = ReplicatedStorage.Assets.ServerStarBall

local RemoteEvents = ReplicatedStorage.RemoteEvents

local BallEvents = RemoteEvents.BallEvents
local SpawnEvent = BallEvents.SpawnEvent
local UpdateEvent = BallEvents.UpdateEvent
local DeleteEvent = BallEvents.DeleteEvent
local HideServerEvent = BallEvents.HideServerEvent
local StatusEvent = BallEvents.StatusEvent

local ScoreEvents = RemoteEvents.ScoreEvents
local ShowPointsEvent = ScoreEvents.ShowPoints
local UpdatePointsEvent = ScoreEvents.UpdatePoints

local TextEvents = RemoteEvents.TextEvents
local UpdateTextEvent = TextEvents.UpdateTextEvent

local GREEN = Color3.fromRGB(30, 255, 100)
local RED = Color3.fromRGB(255, 40, 90)
local WHITE = Color3.fromRGB(255, 255, 255)

local GameSettings = workspace.GameSettings
local BallGravity = GameSettings:GetAttribute("BallGravity")

local function teleport(player, cFrame)
	local character = player.Character or player.CharacterAdded:Wait()

	if not character then return end

	local humanoidRoot = character:WaitForChild("HumanoidRootPart", 2)

	if not humanoidRoot then return end

	humanoidRoot.CFrame = cFrame
end

function Round.remove(CourtObject: Folder, winningTeam: string)
	print(winningTeam)
	local allPlayers = Round.GetPlayers(CourtObject)
	
	for _, player in allPlayers do
		task.spawn(function()
			UpdateTextEvent:FireClient(player, `{winningTeam} won the round!`, WHITE, 3)
		end)
	end
	
	task.wait(3)
	
	local id = CourtObject:GetAttribute("Id")
	local selectedRound = Round.Rounds[id]
	
	local team1 = selectedRound.Team1
	local team2 = selectedRound.Team2
	
	for index, player in allPlayers do
		task.spawn(function()
			ShowPointsEvent:FireClient(player, false)
			teleport(player, CourtObject.CourtModel.Positions.FinishSpawn.CFrame)
		end)
	end
	
	CourtObject:SetAttribute("Id", nil)
	Round.Rounds[id] = nil
	CourtObject.QueueParts:SetAttribute("Active", true)
end

function Round.GivePoint(CourtObject: Folder, Team: string)
	local id = CourtObject:GetAttribute("Id")
	local selectedRound = Round.Rounds[id]
	
	local scoringTeam = selectedRound[Team]
	
	scoringTeam.Score += 1
	print(scoringTeam.Score)
	print(selectedRound.Team1.Players)
	print(selectedRound.Team1.Players)
	
	local team1 = selectedRound.Team1
	local team2 = selectedRound.Team2
	
	local allPlayers = Round.GetPlayers(CourtObject)
	
	for index, player in allPlayers do
		UpdatePointsEvent:FireClient(player, {
			Team1 = team1.Score,
			Team2 = team2.Score
		})
	end
	
	
	if scoringTeam.Score < selectedRound.Win then return end
	
	Round.remove(CourtObject, Team)
end

function Round.Serve(CourtObject: Folder, Team: string)
	print("serving")
	local StarBallFolder = CourtObject:WaitForChild("StarBallFolder")

	local CourtModel = CourtObject:WaitForChild("CourtModel")
	local CanCollide = CourtModel:WaitForChild("CanCollide")
	local Positions = CourtModel:WaitForChild("Positions")
	local ServePosition = Positions:WaitForChild(`{Team}Serve`).Position

	local newBall = ServerStarBall:Clone()
	newBall.Parent = StarBallFolder
	newBall.Position = ServePosition
	
	local id = CourtObject:GetAttribute("Id")
	local selectedRound = Round.Rounds[id]
	
	local TeamNum = nil
	
	--otherTeam
	local otherTeam = nil
	local otherTeamNum = 0

	if Team == "Team1" then
		otherTeam = "Team2"
		otherTeamNum = 2
		TeamNum = 1
	else
		otherTeam = "Team1"
		otherTeamNum = 1
		TeamNum = 2
	end
	
	local otherServePosition = Positions:WaitForChild(`{otherTeam}Serve`).Position
	newBall:SetAttribute("TouchedTeam", otherTeamNum)
	newBall:SetAttribute("TeamTouches", 2)
	
	newBall:GetAttributeChangedSignal("RallyWinner"):Once(function()
		local rallyWinner = newBall:GetAttribute("RallyWinner")
		
		if rallyWinner == nil then return end
		
		local rallyWinnerNum = 0
		
		if rallyWinner == "Team1" then
			rallyWinnerNum = 1
		elseif rallyWinner == "Team2" then
			rallyWinnerNum = 2
		end
		
		local allPlayers = Round.GetPlayers(CourtObject)
		
		task.spawn(function()
			local scorer = newBall:GetAttribute("LastTouched")
			local playerList = Players:GetPlayers()
			local scorerPlayer = nil
			
			for _, player in playerList do
				if player.Name == scorer then
					scorerPlayer = player
				end
			end

			if not scorerPlayer then return end

			local ownScore = false
			local color = nil
			local text

			if scorerPlayer:GetAttribute("Team") ~= rallyWinnerNum then
				ownScore = true
				color = RED
				text = `{scorer} scored on themself!`
			else
				color = GREEN
				text = `{scorer} scored a point!`
			end

			for _, player in allPlayers do
				task.spawn(function()
					UpdateTextEvent:FireClient(player, text, color, 3)
				end)

			end
		end)
		
		if rallyWinner == "None" then
			local num = math.random(1, 2)
			local chosenTeam = Round.RoundEnum.Team[`Team{num}`]
			Round.Serve(CourtObject, chosenTeam)
			
			for _, player in allPlayers do
				task.spawn(function()
					UpdateTextEvent:FireClient(player, `Team{num} is serving!`, WHITE, 2)
				end)
				
			end
		end
		
		Round.GivePoint(CourtObject, rallyWinner)
		newBall:SetAttribute("RallyWinner", nil)
		
		if selectedRound[rallyWinner].Score >= selectedRound.Win then return end
		
		task.wait(2)
		Round.Serve(CourtObject, rallyWinner)
		
		for _, player in allPlayers do
			task.spawn(function()
				UpdateTextEvent:FireClient(player, `{rallyWinner} is serving!`, WHITE, 2)
			end)

		end
	end)
	
	newBall:GetAttributeChangedSignal("LastTouched"):Connect(function()
		local allPlayers = Round.GetPlayers(CourtObject)
		
		for _, player in allPlayers do
			--temporary solution
			task.spawn(function()
				local valid = true
				local ballId = newBall:GetAttribute("Id")
				
				local lastTouched = newBall:GetAttribute("LastTouched")
				local touchedTeam = newBall:GetAttribute("TouchedTeam")
				local teamTouches = newBall:GetAttribute("TeamTouches")

				if not lastTouched or not touchedTeam or not teamTouches then
					valid = true
				end

				if lastTouched == player.Name then
					valid = false
				end

				if touchedTeam == player:GetAttribute("Team") and teamTouches > 1 then
					valid = false
				end

				if ballId and not valid then
					StatusEvent:FireClient(player, ballId, "Unhittable")
				elseif ballId and valid then
					StatusEvent:FireClient(player, ballId, "Active")
				end
			end)

		end
	end)
	
	task.wait(0.5)
	StarBall.ApplyGravity(newBall, CanCollide, {Gravity = BallGravity})
	
	task.spawn(function()
		task.wait(8)
		if newBall:GetAttribute("Status") == "Serve" then
			local direction = (otherServePosition - ServePosition).Unit + Vector3.new(0, 0.75, 0)
			
			newBall:SetAttribute("LastTouched", "Game")
			newBall:SetAttribute("TouchedTeam", TeamNum)
			newBall:SetAttribute("TeamTouches", 2)
			StarBall.ApplyLinearVelocity(newBall, direction, 85)
		end
	end)
end

function Round.new(CourtObject: Folder, Team1: Array, Team2: Array, Params: Dictionary)
	local id = time()
	local params = Params or {}
	local serve = params.Serve
	
	local newRound = setmetatable({}, metatable)
	newRound.Id = id
	Round.Rounds[id] = newRound
	newRound.Court = CourtObject
	newRound.Team1 = {
		Players = Team1,
		Score = params.Team1Score or 0
	}
	newRound.Team2 = {
		Players = Team2,
		Score = params.Team2Score or 0
	}
	newRound.Spectators = {}
	newRound.Status = Round.RoundEnum.Status.Starting
	
	newRound.Win = params.Win or 11
	
	CourtObject:SetAttribute("Id", newRound.Id)
	
	for _, player in Team1 do
		player:SetAttribute("Team", 1)
		player:SetAttribute("Round", id)
		
		task.spawn(function()
			teleport(player, CourtObject.CourtModel.Positions.Team1Serve.CFrame)
			ShowPointsEvent:FireClient(player, true)
			UpdatePointsEvent:FireClient(player, {
				Team1 = newRound.Team1.Score,
				Team2 = newRound.Team2.Score
			})
		end)
		
	end
	
	for _, player in Team2 do
		player:SetAttribute("Team", 2)
		player:SetAttribute("Round", id)
		
		task.spawn(function()
			teleport(player, CourtObject.CourtModel.Positions.Team2Serve.CFrame)
			ShowPointsEvent:FireClient(player, true)
			UpdatePointsEvent:FireClient(player, {
				Team1 = newRound.Team1.Score,
				Team2 = newRound.Team2.Score
			})
		end)
		
	end
	
	local serveDecider = math.random(1, 2)
	
	if serve then serveDecider = serve end
	
	local startServe = `Team{serveDecider}`
	
	--here
	Round.Serve(CourtObject, startServe)
	
	local allPlayers = Round.GetPlayers(CourtObject)

	for _, player in allPlayers do
		task.spawn(function()
			UpdateTextEvent:FireClient(player, `{startServe} is serving!`, WHITE, 2)
		end)

	end

	print("Request received to start new round.")
	print(Team1)
	print(Team2)
	print(Round.GetPlayers(CourtObject))
	print(Round.Rounds)
	
	--[[task.spawn(function()
		while true do
			print(Round.GetPlayers(CourtObject))
			task.wait(0.05)
		end
	end)]]
end

function Round.Get(Id: number)
	return Round.Rounds[Id]
end

function Round.GetPlayers(CourtObject: Folder)
	local selected = Round.Get(CourtObject:GetAttribute("Id"))
	
	local allPlayers = table.pack(table.unpack(
		selected.Team1.Players),
		table.unpack(selected.Team2.Players),
		table.unpack(selected.Spectators)
	)
	
	allPlayers["n"] = nil
	
	return allPlayers
end

return Round

Queue script (under a model that has parts)

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ModuleScripts = ReplicatedStorage.ModuleScripts

local Round = require(ModuleScripts.RoundModule)
local CourtObject = script.Parent:FindFirstAncestorWhichIsA("Folder")

local debounce = false
local partCounter = 0

local queued = {
	Team1 = {},
	Team2 = {}
}

local function ResetQueue()
	queued = {
		Team1 = {},
		Team2 = {}
	}
	for _, part in script.Parent:GetChildren() do
		if part:IsA("Part") then
			part.Color = Color3.fromRGB(255, 255, 255)
		end
	end
end

local queueParts = script.Parent:GetChildren()

script.Parent:SetAttribute("Active", true)

for _, part in queueParts do
	if part:IsA("Part") then
		partCounter += 1

		part.Touched:Connect(function(otherPart)
			if script.Parent:GetAttribute("Active") == false then return end

			if debounce then return end

			local character = otherPart.Parent
			local player = Players:GetPlayerFromCharacter(character)

			if Players:GetPlayerFromCharacter(character) then
				player.AncestryChanged:Once(function()
					if player.Parent ~= nil then return end

					local isFound1 = table.find(queued.Team1, player)
					local isFound2 = table.find(queued.Team2, player)

					if isFound1 then
						table.remove(queued.Team1, isFound1)
					elseif isFound2 then
						table.remove(queued.Team2, isFound2)
					end
				end)

				if player.Parent == nil then return end

				local partTeam = part:GetAttribute("Team")
				local allQueued = table.pack(table.unpack(queued.Team1), table.unpack(queued.Team2))

				if table.find(allQueued, player) then return end
				if #queued[`Team{partTeam}`] >= partCounter // 2 then return end

				table.insert(queued[`Team{partTeam}`], player)
				part.Color = Color3.fromRGB(120, 255, 120)

				if #queued.Team1 == partCounter // 2 and #queued.Team2 == partCounter // 2 then
					script.Parent:SetAttribute("Active", false)
					Round.new(CourtObject, queued.Team1, queued.Team2)
					ResetQueue()
				end

				debounce = true
				task.wait(0.15)
				debounce = false
			end
		end)

		part.TouchEnded:Connect(function(otherPart)
			local character = otherPart.Parent
			local player = Players:GetPlayerFromCharacter(character)

			if Players:GetPlayerFromCharacter(character) then
				local partTeam = part:GetAttribute("Team")
				local queuedTeam = queued[`Team{partTeam}`]
				local isFound = table.find(queuedTeam, player)

				if not isFound then return end

				table.remove(queued[`Team{partTeam}`], isFound)
				part.Color = Color3.fromRGB(255, 255, 255)
			end
		end)
	end
end

WEDNESDAY’s Round ModuleScript (worked fine)

local Round = {}
local StarBall = require(script.Parent.StarBallModule)
Round.Rounds = {}
Round.Connections = {}

local metatable = {
	
}

Round.RoundEnum = {
	Team = {
		Team1 = "Team1",
		Team2 = "Team2"
	},
	Status = {
		Starting = "Starting",
		Rallying = "Rallying",
		Point = "Point",
	}
}

Round.BallEnum = {
	Status = {
		Serve = "Serve"
	}
}


local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Assets = ReplicatedStorage.Assets
local ServerStarBall = ReplicatedStorage.Assets.ServerStarBall

local RemoteEvents = ReplicatedStorage.RemoteEvents

local BallEvents = RemoteEvents.BallEvents
local SpawnEvent = BallEvents.SpawnEvent
local UpdateEvent = BallEvents.UpdateEvent
local DeleteEvent = BallEvents.DeleteEvent
local HideServerEvent = BallEvents.HideServerEvent
local StatusEvent = BallEvents.StatusEvent

local ScoreEvents = RemoteEvents.ScoreEvents
local ShowPointsEvent = ScoreEvents.ShowPoints
local UpdatePointsEvent = ScoreEvents.UpdatePoints

local TextEvents = RemoteEvents.TextEvents
local UpdateTextEvent = TextEvents.UpdateTextEvent

local GREEN = Color3.fromRGB(30, 255, 100)
local RED = Color3.fromRGB(255, 40, 90)
local WHITE = Color3.fromRGB(255, 255, 255)

local function teleport(player, cFrame)
	local character = player.Character or player.CharacterAdded:Wait()

	if not character then return end

	local humanoidRoot = character:WaitForChild("HumanoidRootPart", 2)

	if not humanoidRoot then return end

	humanoidRoot.CFrame = cFrame
end

function Round.remove(CourtObject: Folder, winningTeam: string)
	print(winningTeam)
	
	task.wait(3)
	
	local id = CourtObject:GetAttribute("Id")
	local selectedRound = Round.Rounds[id]
	
	local team1 = selectedRound.Team1
	local team2 = selectedRound.Team2
	
	local allPlayers = table.pack(table.unpack(team1.Players), table.unpack(team2.Players))
	
	for index, player in allPlayers do
		if index == "n" then continue end

		ShowPointsEvent:FireClient(player, false)
		teleport(player, CourtObject.CourtModel.Positions.FinishSpawn.CFrame)
	end
	
	CourtObject:SetAttribute("Id", nil)
	Round.Rounds[id] = nil
	CourtObject.QueueParts:SetAttribute("Active", true)
end

function Round.GivePoint(CourtObject: Folder, Team: string)
	local id = CourtObject:GetAttribute("Id")
	local selectedRound = Round.Rounds[id]
	
	local scoringTeam = selectedRound[Team]
	
	scoringTeam.Score += 1
	print(scoringTeam.Score)
	
	local team1 = selectedRound.Team1
	local team2 = selectedRound.Team2
	
	local allPlayers = table.pack(table.unpack(team1.Players), table.unpack(team2.Players))
	
	for index, player in allPlayers do
		if index == "n" then continue end
		
		UpdatePointsEvent:FireClient(player, {
			Team1 = team1.Score,
			Team2 = team2.Score
		})
	end
	
	
	if scoringTeam.Score < selectedRound.Win then return end
	
	Round.remove(CourtObject, Team)
end

function Round.Serve(CourtObject: Folder, Team: string)
	local StarBallFolder = CourtObject:WaitForChild("StarBallFolder")

	local CourtModel = CourtObject:WaitForChild("CourtModel")
	local CanCollide = CourtModel:WaitForChild("CanCollide")
	local Positions = CourtModel:WaitForChild("Positions")
	local ServePosition = Positions:WaitForChild(`{Team}Serve`).Position

	local newBall = ServerStarBall:Clone()
	newBall.Parent = StarBallFolder
	newBall.Position = ServePosition
	
	local id = CourtObject:GetAttribute("Id")
	local selectedRound = Round.Rounds[id]

	newBall:GetAttributeChangedSignal("RallyWinner"):Once(function()
		local rallyWinner = newBall:GetAttribute("RallyWinner")
		
		if rallyWinner == nil then return end
		
		local rallyWinnerNum = 0
		
		if rallyWinner == "Team1" then
			rallyWinnerNum = 1
		elseif rallyWinner == "Team2" then
			rallyWinnerNum = 2
		end
		
		local allPlayers = Round.GetPlayers(CourtObject)
		
		task.spawn(function()
			local scorer = newBall:GetAttribute("LastTouched")
			local playerList = Players:GetPlayers()
			local scorerPlayer = nil
			
			for _, player in playerList do
				if player.Name == scorer then
					scorerPlayer = player
				end
			end

			if not scorerPlayer then return end

			local ownScore = false
			local color = nil
			local text

			if scorerPlayer:GetAttribute("Team") ~= rallyWinnerNum then
				ownScore = true
				color = RED
				text = `{scorer} scored on themself!`
			else
				color = GREEN
				text = `{scorer} scored a point!`
			end

			for _, player in allPlayers do
				task.spawn(function()
					UpdateTextEvent:FireClient(player, text, color, 3)
				end)

			end
		end)
		
		if rallyWinner == "None" then
			local num = math.random(1, 2)
			local chosenTeam = Round.RoundEnum.Team[`Team{num}`]
			Round.Serve(CourtObject, chosenTeam)
			
			for _, player in allPlayers do
				task.spawn(function()
					UpdateTextEvent:FireClient(player, `Team{num} is serving!`, WHITE, 2)
				end)
				
			end
		end
		
		Round.GivePoint(CourtObject, rallyWinner)
		newBall:SetAttribute("RallyWinner", nil)
		
		if selectedRound[rallyWinner].Score >= selectedRound.Win then return end
		
		task.wait(2)
		Round.Serve(CourtObject, rallyWinner)
		
		for _, player in allPlayers do
			task.spawn(function()
				UpdateTextEvent:FireClient(player, `{rallyWinner} is serving!`, WHITE, 2)
			end)

		end
	end)
	
	StarBall.ApplyGravity(newBall, CanCollide, {Gravity = 0.35})
end

function Round.new(CourtObject: Folder, Team1: Array, Team2: Array, Params: Dictionary)
	local id = time()
	local params = Params or {}
	
	local newRound = setmetatable({}, metatable)
	newRound.Id = id
	Round.Rounds[id] = newRound
	newRound.Court = CourtObject
	newRound.Team1 = {
		Players = Team1,
		Score = params.Team1Score or 0
	}
	newRound.Team2 = {
		Players = Team2,
		Score = params.Team2Score or 0
	}
	newRound.Spectators = {}
	newRound.Status = Round.RoundEnum.Status.Starting
	
	newRound.Win = params.Win or 7
	
	CourtObject:SetAttribute("Id", newRound.Id)
	
	for _, player in Team1 do
		player:SetAttribute("Team", 1)
		player:SetAttribute("Round", id)
		teleport(player, CourtObject.CourtModel.Positions.Team1Serve.CFrame)
		ShowPointsEvent:FireClient(player, true)
		UpdatePointsEvent:FireClient(player, {
			Team1 = newRound.Team1.Score,
			Team2 = newRound.Team2.Score
		})
	end
	
	for _, player in Team2 do
		player:SetAttribute("Team", 2)
		player:SetAttribute("Round", id)
		teleport(player, CourtObject.CourtModel.Positions.Team2Serve.CFrame)
		ShowPointsEvent:FireClient(player, true)
		UpdatePointsEvent:FireClient(player, {
			Team1 = newRound.Team1.Score,
			Team2 = newRound.Team2.Score
		})
	end
	
	local serveDecider = math.random(1, 2)
	local startServe = `Team{serveDecider}`
	
	Round.Serve(CourtObject, startServe)
	local allPlayers = Round.GetPlayers(CourtObject)
	
	for _, player in allPlayers do
		task.spawn(function()
			UpdateTextEvent:FireClient(player, `{startServe} is serving!`, WHITE, 2)
		end)

	end
end

function Round.Get(Id: number)
	return Round.Rounds[Id]
end

function Round.GetPlayers(CourtObject: Folder)
	local selected = Round.Get(CourtObject:GetAttribute("Id"))
	
	local allPlayers = table.pack(table.unpack(
		selected.Team1.Players),
		table.unpack(selected.Team2.Players),
		table.unpack(selected.Spectators)
	)
	
	allPlayers["n"] = nil
	
	return allPlayers
end

return Round

WEDNESDAY’s Touch pad script (Worked fine)

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ModuleScripts = ReplicatedStorage.ModuleScripts

local Round = require(ModuleScripts.RoundModule)
local CourtObject = script.Parent:FindFirstAncestorWhichIsA("Folder")

local debounce = false
local partCounter = 0

local queued = {
	Team1 = {},
	Team2 = {}
}

local function ResetQueue()
	queued = {
		Team1 = {},
		Team2 = {}
	}
	for _, part in script.Parent:GetChildren() do
		if part:IsA("Part") then
			part.Color = Color3.fromRGB(255, 255, 255)
		end
	end
end

local queueParts = script.Parent:GetChildren()

script.Parent:SetAttribute("Active", true)

for _, part in queueParts do
	if part:IsA("Part") then
		partCounter += 1
		
		part.Touched:Connect(function(otherPart)
			if script.Parent:GetAttribute("Active") == false then return end
			
			if debounce then return end
			
			local character = otherPart.Parent
			local player = Players:GetPlayerFromCharacter(character)
			
			if Players:GetPlayerFromCharacter(character) then
				player.AncestryChanged:Once(function()
					if player.Parent ~= nil then return end
					
					local isFound1 = table.find(queued.Team1, player)
					local isFound2 = table.find(queued.Team2, player)
					
					if isFound1 then
						table.remove(queued.Team1, isFound1)
					elseif isFound2 then
						table.remove(queued.Team2, isFound2)
					end
				end)
				
				if player.Parent == nil then return end
				
				local partTeam = part:GetAttribute("Team")
				local allQueued = table.pack(table.unpack(queued.Team1), table.unpack(queued.Team2))
				
				if table.find(allQueued, player) then return end
				if #queued[`Team{partTeam}`] >= partCounter // 2 then return end
				
				table.insert(queued[`Team{partTeam}`], player)
				part.Color = Color3.fromRGB(120, 255, 120)
				
				if #queued.Team1 == partCounter // 2 and #queued.Team2 == partCounter // 2 then
					script.Parent:SetAttribute("Active", false)
					Round.new(CourtObject, queued.Team1, queued.Team2)
					ResetQueue()
				end
				
				debounce = true
				task.wait(0.15)
				debounce = false
			end
		end)
		
		part.TouchEnded:Connect(function(otherPart)
			local character = otherPart.Parent
			local player = Players:GetPlayerFromCharacter(character)

			if Players:GetPlayerFromCharacter(character) then
				local partTeam = part:GetAttribute("Team")
				local queuedTeam = queued[`Team{partTeam}`]
				local isFound = table.find(queuedTeam, player)

				if not isFound then return end
				
				table.remove(queued[`Team{partTeam}`], isFound)
				part.Color = Color3.fromRGB(255, 255, 255)
			end
		end)
	end
end

Above are Wednesday’s scripts, because they worked fine there, but I don’t know what I added from there and now caused the whole thing to break.

Thank you to anybody who tries to help, I know these scripts are relatively long so even a guess as to what is happening would help.

I understand that you use the Touched event to determine players who entered the zone and TouchEnded for those who left. Your problem may be related to zone hitboxes not detecting players correctly.
The only thing I can recommend you is to use the GetPartsInPart method instead of the last two in order to detect players in the zone and exclude those who left it before the round starts.

2 Likes

or even GetBoundingBox (if its correct name, smth like that) ig would be better to detect parts that are in certain box

1 Like

for storing players i would set attributes to the tennis court. you can only set them from server side, but you can call them from anywhere.

1 Like

Thanks, it worked and the players can complete a round properly. I am still wondering however why the script worked on Wednesday and not later on.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.