Why doesn't my custom leaderboard module detects when a team is changed?

I’ve been fiddling around with this module script, and I got it to work as intended, however, it doesn’t update the GUI whenever I join a new team. It is seemingly stuck at the first time I was in when joining. I’ve tried to locate where the module changes teams, but to no avail.

Module script

local PS = game:GetService('Players')
local TMS = game:GetService('Teams')
local RPS = game:GetService('ReplicatedStorage')
local CAS = game:GetService('ContextActionService')
local UIS = game:GetService('UserInputService')
local SGS = game:GetService('StarterGui')
local RS = game:GetService('RunService')

type EntityData = {Type : string, Instance : Player | Team, GuiObject : GuiObject?, LayoutOrder : number}
type Stat = {Name : string, IsPrimary : boolean, Priority : number, AddId : number}

SGS:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false)
if not (game:IsLoaded()) then game.Loaded:Wait() end

local Icons = require(script.Modules.Icons)
local CreateGUIObject = require(script.Modules.CreateGUIObject)
local InspectPlayer = require(script.Modules.InspectPlayer)
local FormatStatString = require(script.Modules.FormatStatString)

local localPlayer : Player = PS.LocalPlayer
local Templates = script.Templates

local StatsText : GuiObject = Templates.StatsText
local HeaderText : GuiObject = Templates.HeaderText

local GUI = CreateGUIObject('ScreenGui', 'PlayerList', {Enabled = false, ResetOnSpawn = false, IgnoreGuiInset = true}, nil)
local Container = CreateGUIObject('Frame', 'Container', {
	AnchorPoint = Vector2.new(1,0),
	Position = UDim2.new(1,-4,0,40),
	Size = UDim2.new(0, 166, 0.5, 0),
	Visible = true,
	ZIndex = 1
}, GUI)

local OffsetFrame = CreateGUIObject('Frame', 'OffsetFrame', {
	Size = UDim2.new(1, 0, 1, 0),
	BackgroundTransparency = 1,
	
}, Container)

local Listlayout = CreateGUIObject('UIListLayout', nil, {
	FillDirection = Enum.FillDirection.Vertical,
	HorizontalAlignment = Enum.HorizontalAlignment.Left,
	SortOrder = Enum.SortOrder.LayoutOrder,
	VerticalAlignment = Enum.VerticalAlignment.Top
}, OffsetFrame)

local ScrollingFrame : ScrollingFrame = CreateGUIObject('ScrollingFrame', nil, {
	Size = UDim2.new(1,0,1,-20),
	ScrollBarImageTransparency = 1,
	ScrollBarThickness = 0,
	CanvasSize = UDim2.new(0, 0, 0, 0),
	LayoutOrder = 1,
}, OffsetFrame)

local ToggleFrame = CreateGUIObject('Frame', 'UIToggle', {
	Size = UDim2.new(0,32,0,32),
	Position = UDim2.new(0, 104, 0, 4),
	BackgroundColor3 = Color3.new(0, 0, 0),
	BackgroundTransparency = 0.5,
}, GUI)

local ToggleButton : ImageButton = CreateGUIObject('ImageButton', nil, {
	AnchorPoint = Vector2.new(0.5, 0.5),
	Position = UDim2.new(0.5, 0, 0.5, 0),
	Size = UDim2.new(.8, 0, .8, 0),
	Image = Icons.Button.Toggle
}, ToggleFrame)

do
	local UICorner = Instance.new('UICorner')
	UICorner.CornerRadius = UDim.new(0.25, 0)
	UICorner.Parent = ToggleFrame
end

local Header : GuiObject = Templates.Header
Header.LayoutOrder = 0
Header.Visible = false
Header.Parent = OffsetFrame

local ScrollLayout = Listlayout:Clone()
ScrollLayout.Parent = ScrollingFrame


local FakeNeutralTeam = Templates.EntitySlot:Clone()
do
	FakeNeutralTeam.Name = 'FakeNeutralTeam'
	FakeNeutralTeam.Size = UDim2.new(1, 0, 0, 24)
	FakeNeutralTeam.BackgroundColor3 = BrickColor.Gray().Color
	FakeNeutralTeam.NameFrame.EntityName.NameText.Text = 'Neutral'
	
	
	FakeNeutralTeam.NameFrame.Icon:Destroy()
	FakeNeutralTeam.NameFrame.UIPadding:Destroy()
	
	
	local padding = Instance.new('UIPadding')
	padding.PaddingLeft = UDim.new(0, 15)
	padding.Parent = FakeNeutralTeam.NameFrame.EntityName.NameText
	
	FakeNeutralTeam.LayoutOrder = 1e3
	
	FakeNeutralTeam.NameFrame.EntityName.NameText.TextScaled = false
	FakeNeutralTeam.Visible = false
	FakeNeutralTeam.Parent = ScrollingFrame
end

local isMobile : boolean = UIS.TouchEnabled
local isShowing : boolean = true
local appearPosition : UDim2 = UDim2.new(0,0,0,0)
local disappearPosition : UDim2 = UDim2.new(1.1, 0, 0, 0)

local nameSizeIncrement : number = 11
local guiSizeIncrement : number = 77
local maxStats : number = 4

local insert = table.insert
local remove = table.remove

local currentInspectedPlayer : Player? = nil
local nameProperty : string = 'DisplayName'

local blockedUsers = SGS:GetCore('GetBlockedUserIds')
local playerBlocked = SGS:GetCore('PlayerBlockedEvent')
local playerUnblocked = SGS:GetCore('PlayerUnblockedEvent')
local playerFriended = SGS:GetCore('PlayerFriendedEvent')
local playerUnfriended = SGS:GetCore('PlayerUnfriendedEvent')

local teamData : {EntityData} = {}
local playerData : {EntityData} = {}
local currentGameStats : {Stat} = {}

local playerConnections : {[string] : {RBXScriptConnection}} = {}
local teamConnections : {[string] : {RBXScriptConnection}} = {}
local guiConnections : {[string | number] : RBXScriptConnection} = {}

local function getPrimaryStat() : Stat
	for i, stat : Stat in pairs (currentGameStats) do
		if stat.IsPrimary then
			return stat
		end
	end
end

local function isValidStat(object : Instance) : boolean
	return (object:IsA('IntValue') or object:IsA('NumberValue') or object:IsA('StringValue'))
end

local function find(list, value) : Player | Team
	for i,v in pairs (list) do
		if v.Instance == value then
			return i
		end
	end
end

local function gameStatExists(statName : string) : (boolean, Stat?)
	for i,v in pairs (currentGameStats) do
		if (v.Name == statName) then
			return true, v
		end
	end
		
	return false
end

local function getNumberOfTeamlessPlayers() : number
	local count = 0
	for i,v in pairs (PS:GetPlayers()) do
		if not (v.Team) then
			count += 1
		end
	end
	
	return count
end

local function sortStatOrder()
	table.sort(currentGameStats, function(a, b)
		if a.IsPrimary ~= b.IsPrimary then
			return a.IsPrimary
		end
		if a.Priority == b.Priority then
			return a.AddId < b.AddId
		end
		return a.Priority > b.Priority
	end)
	
	for i,stat in pairs (currentGameStats) do
		local uiObject = Header:FindFirstChild('Stat_'..stat.Name)
		
		if (uiObject) then
			uiObject.LayoutOrder = i
		end
		
		for _,entityData in pairs (playerData) do
			local statObj = entityData.GuiObject:FindFirstChild('Stat_'..stat.Name)
			
			if (statObj) then
				statObj.LayoutOrder = i
			end
		end
		
			end
		end

local function addUpPlayerStatOfTeam(team, statName : string) : number
	local count = 0
	for i,v in pairs (team:GetPlayers()) do
		if (v:FindFirstChild('leaderstats') and v.leaderstats:FindFirstChild(statName)) then
			if (v.leaderstats[statName]:IsA('IntValue') or v.leaderstats[statName]:IsA('NumberValue')) then
				count += v.leaderstats[statName].Value
			end
		end
	end
	return count
end

local function addUIStat(entityData : EntityData, stat : Stat) : Stat
	local statIndex : number = table.find(currentGameStats, stat)
	local newStat : GuiObject = entityData.GuiObject:FindFirstChild('Stat_'..stat.Name) or StatsText:Clone()
	newStat.Name = 'Stat_'..stat.Name
	newStat.LayoutOrder = statIndex
	
	if (entityData.Type == 'Player') then
		local leaderstats = entityData.Instance:FindFirstChild('leaderstats')
		local statObject = leaderstats and leaderstats:FindFirstChild(stat.Name)
		newStat.Text = (statObject and tostring(statObject.Value)) or '-'
	else
		local value = addUpPlayerStatOfTeam(entityData.Instance, stat.Name)
		newStat.Text = FormatStatString(value)
	end
	
	do
		local yOffset = entityData.GuiObject.NameFrame.Size.Y.Offset
		entityData.GuiObject.NameFrame.Size = UDim2.new(0, 150 + (#currentGameStats * nameSizeIncrement), 0, yOffset)
	end
	
	if (newStat.LayoutOrder > 4) then
		newStat.Visible = false
	end
	
	newStat.Parent = entityData.GuiObject
	return newStat
end

local function removeUIStat(entityData : EntityData, stat : Stat)
	local statUIObject = entityData.GuiObject:FindFirstChild('Stat_'..stat.Name)
	local statLayoutOrder = statUIObject.LayoutOrder
	
	if (statUIObject) then
		statUIObject:Destroy()
	end
	
	do
		local yOffset = entityData.GuiObject.NameFrame.Size.Y.Offset
		entityData.GuiObject.NameFrame.Size = UDim2.new(0, 150 + (#currentGameStats * nameSizeIncrement), 0, yOffset)
	end
	
	for i,v in pairs (entityData.GuiObject:GetChildren()) do
		if (v.Name:match('Stat_') and v.LayoutOrder > statLayoutOrder) then
			v.LayoutOrder -= 1
		end
	end
end

local function addGameStat(statObject : ValueBase)
	
	local newIndex = #currentGameStats + 1
	local isPrimary = false
	local priority = 0

	local isPrimaryVal = statObject:FindFirstChild("IsPrimary")
	if isPrimaryVal then
		if isPrimaryVal:IsA("BoolValue") then
			isPrimary = isPrimaryVal.Value
		else
			isPrimary = true
		end
	end
	local priorityVal = statObject:FindFirstChild("Priority")
	if priorityVal and (priorityVal:IsA("IntValue") or priorityVal:IsA("NumberValue")) then
		priority = priorityVal.Value
	end
	
	local stat : Stat = {
		Name = statObject.Name,
		IsPrimary = isPrimary,
		Priority = priority,
		AddId = newIndex
	}
	currentGameStats[newIndex] = stat
	
	if (newIndex <= maxStats) then
		Container.Size = UDim2.new(0, 166 + (guiSizeIncrement * newIndex), 0.5, 0)
		
		local newHeaderStat = HeaderText:Clone()
		newHeaderStat.Text = stat.Name
		newHeaderStat.Name = 'Stat_'..stat.Name
		newHeaderStat.Parent = Header
	end
	
	Header.NameText.Size = UDim2.new(0, 150 + (#currentGameStats * nameSizeIncrement), 1, 0)
	Header.Visible = (#currentGameStats > 0)
	
	sortStatOrder()
	for i,entityData in pairs (playerData) do 
		addUIStat(entityData, stat)
	end
	
	end

local function removeGameStat(name : string)
	local statToRemove : Stat = nil
	
	for i, v in pairs (currentGameStats) do
		if (v.Name == name) then
			statToRemove = remove(currentGameStats, i)
			break
		end
	end
	
	do
		local count = math.clamp(#currentGameStats, 0, maxStats)
		Container.Size = UDim2.new(0, 166 + (guiSizeIncrement * count), 0.5, 0)
		
		Header.NameText.Size = UDim2.new(0, 150 + (#currentGameStats * nameSizeIncrement), 1, 0)
		Header.Visible = (#currentGameStats > 0)
		Header['Stat_'..name]:Destroy()
	end
	
	sortStatOrder()
	for i, entityData in pairs (playerData) do
		removeUIStat(entityData, statToRemove)
	end
	

	end

local function getNumberOfPlayersWithLeaderstats() : number
	local count = 0
	for i,entity : EntityData in pairs (playerData) do
		if entity.Instance:FindFirstChild('leaderstats') then
			count += 1
		end
	end
	
	return count
end

local function checkGameStatsExist(playerToIgnore : Player)
	local hasGameStat = {}
	for _, gameStat in ipairs(currentGameStats) do
		hasGameStat[gameStat.Name] = false
	end
	
	if (getNumberOfTeamlessPlayers() > 1) then
		for i, data : EntityData in ipairs(playerData) do
			if (data.Instance == playerToIgnore) then continue end

			local leaderstats = data.Instance:FindFirstChild('leaderstats')
			if (leaderstats) then
				for statName, bool in pairs (hasGameStat) do
					if (bool) then continue end
					if leaderstats:FindFirstChild(statName) then
						hasGameStat[statName] = true
					end

				end
			end

		end
		
	else
		local leaderstats = playerToIgnore:FindFirstChild('leaderstats')
		if (leaderstats) then
			for statName, bool in pairs (hasGameStat) do
				if leaderstats:FindFirstChild(statName) then
					hasGameStat[statName] = true
				end

			end
		end
	end
	for statName, hasStat in pairs(hasGameStat) do
		if not hasStat then
			removeGameStat(statName)
		end
	end
end

local function createEntityTable(entity : Player | Team) : EntityData
	return {Type = entity.ClassName, Instance = entity, GuiObject = nil, LayoutOrder = #playerData}
end

local function sortTeams()
	--task.desynchronize()
	print 'SORT'
	if #teamData == 0 then
		print 'team data < 1'
		--task.synchronize()
		return
	end
	
	table.sort(teamData, function(a, b)
		return (a.Instance.Name:lower() < b.Instance.Name:lower())
	end)
	
	
	local numberOfNoTeams = getNumberOfTeamlessPlayers()
	--task.synchronize()
	print(numberOfNoTeams)
	FakeNeutralTeam.Visible = (numberOfNoTeams > 0)
	
	teamData[1].LayoutOrder = 1 + numberOfNoTeams
	
	for i = 2, #teamData do
		--task.desynchronize()
		local previous = teamData[i - 1]
		local entityData = teamData[i]
		entityData.LayoutOrder = previous.LayoutOrder + (#previous.Instance:GetPlayers() + 1)
		--task.synchronize()
		entityData.GuiObject.LayoutOrder = entityData.LayoutOrder
	end
	
end

local function sortPlayerData(playerDatas : {EntityData})
	local primaryStat = getPrimaryStat()

	if not (#playerDatas > 1) then
		--task.desynchronize()
		local pData = playerDatas[1]
		if not (pData) then --[[task.synchronize()]] return end

		local playerTeam = pData.Instance.Team
		if (playerTeam) then
			local tData = teamData[find(teamData, playerTeam)]

			if (tData) then
				--task.synchronize()
			end
		end
		--task.synchronize()
		return
	end

	if (primaryStat) then
		--task.desynchronize()
		table.sort(playerDatas, function(a, b)
			local aLeaderstats = a.Instance:FindFirstChild('leaderstats')
			local aStat = aLeaderstats and a.Instance:FindFirstChild(primaryStat.Name)

			local bLeaderstats = b.Instance:FindFirstChild('leaderstats')
			local bStat = bLeaderstats and b.Instance:FindFirstChild(primaryStat.Name)

			return (aStat and aStat.Value or 0) < (bStat and bStat.Value or 0)
		end)
		--task.synchronize()
	else
		--task.desynchronize()
		table.sort(playerDatas, function(a, b)
			return (a.Instance[nameProperty]:lower() < b.Instance[nameProperty]:lower())
		end)
		--task.synchronize()
	end
end

local function sortPlayers() 
	
	local gameHasTeams = TMS:FindFirstChildOfClass('Team') and true or false
	
	if (gameHasTeams) then
		for i, team : Team in pairs (TMS:GetTeams()) do
			local players = {}
			local tData = teamData[find(teamData, team)]
			for i, player in pairs (team:GetPlayers()) do
				local index = find(playerData, player)
				
				if (index) then
					players[#players + 1] = playerData[index]
				end
			end
			
			
			sortPlayerData(players)
			
			if (tData) then
				for i,pData in pairs (players) do
					pData.LayoutOrder = tData.LayoutOrder + i
					pData.GuiObject.LayoutOrder = tData.LayoutOrder + i
				end
			end
			
		end
		
		local playersWithNoTeams = {}
		for i, entityData in pairs (playerData) do
			if not (entityData.Instance.Team) then
				playersWithNoTeams[#playersWithNoTeams + 1] = entityData
			end
		end
		sortPlayerData(playersWithNoTeams)
		
		for i,player : EntityData in pairs (playersWithNoTeams) do
			player.LayoutOrder = FakeNeutralTeam.LayoutOrder + i
			player.GuiObject.LayoutOrder = FakeNeutralTeam.LayoutOrder + i
		end
		
	else
		for i, entityData in pairs (playerData) do
			entityData.LayoutOrder = i
			entityData.GuiObject.LayoutOrder = i
		end
	end
end

local function sortPlayersAndTeams()
	sortTeams()
	sortPlayers()
end

local function updateIcon(icon, isBlocked, otherPlayer)
	if (otherPlayer.UserId == RPS:GetAttribute('Creator')) then
		icon.Image = Icons.Display.Owner
	elseif localPlayer:IsFriendsWith(otherPlayer.UserId) then
		icon.Image = Icons.Display.Friended
	elseif isBlocked then
		icon.Image = Icons.Display.Blocked
	elseif localPlayer.TeamColor == BrickColor.new("Crimson") then
		icon.Image = Icons.Display.TestTeam
	else
		icon.Image = Icons.Display.Empty
	end
end
local function addSlot(data : EntityData)
	local slot = Templates.EntitySlot:Clone()
	local name = (data.Type == 'Team' and data.Instance.Name) or data.Instance[nameProperty]
	
	data.GuiObject = slot
	slot.NameFrame.EntityName.NameText.Text = name
	
	slot.Name = data.Instance.Name
	slot.Size = UDim2.new(1, 0, 0, data.Type == 'Team' and 24 or 40)
	slot.NameFrame.Size = UDim2.new(0, 150 + (#currentGameStats * nameSizeIncrement), 0, slot.Size.Y.Offset)
	slot.BackgroundTransparency = (data.Type == 'Team' and 0.5) or slot.BackgroundTransparency
	slot.BackgroundColor3 = localPlayer.Team.TeamColor.Color
	slot.LayoutOrder = data.LayoutOrder

	-- Event Connections
	local function updateStats()
		if (#currentGameStats > 0) then
			for i, stat in pairs (currentGameStats) do
				local statText : TextLabel = slot:FindFirstChild('Stat_'..stat.Name)
				statText = statText or addUIStat(data, stat)
				statText.Text = data.Type == 'Team' and FormatStatString(addUpPlayerStatOfTeam(data.Instance, stat.Name)) or data.Instance.leaderstats[stat.Name].Value

			end
		end
	end
	
	if data.Type == 'Player' then
		
		local tIcon = slot.NameFrame.Icon

		slot.MouseEnter:Connect(function()
			local hue, sat, value = slot.BackgroundColor3:ToHSV()
			value = (value >= .75 and value - .25) or value + .25
			slot.BackgroundColor3 = Color3.fromHSV(hue, sat, value)
		end)
		
		slot.MouseLeave:Connect(function()
			local hue, sat, value = slot.BackgroundColor3:ToHSV()
			value = (value <= .5 and value + .25) or value - .25
			slot.BackgroundColor3 = Color3.fromHSV(hue, sat, value)
		end)
		
		slot.InputBegan:Connect(function(inputObject : InputObject)
			if not (inputObject.UserInputType == Enum.UserInputType.MouseButton1) and not (inputObject.UserInputType == Enum.UserInputType.Touch) then return end
			
			if (inputObject.UserInputState == Enum.UserInputState.Begin) then
				if not (Container:FindFirstChild(data.Instance.Name..'Inspector')) then
					InspectPlayer(data.Instance, data.GuiObject, blockedUsers)
				end
			end
		end)
		
		updateIcon(tIcon, (table.find(blockedUsers, data.Instance.UserId) and true) or false, data.Instance)
		updateStats()
	else
		
		do
			local padding = Instance.new('UIPadding')
			padding.PaddingLeft = UDim.new(0, 15)
			padding.Parent = slot.NameFrame.EntityName.NameText
		end
		
		slot.NameFrame.Icon:Destroy()
		slot.NameFrame.UIPadding:Destroy()
		slot.NameFrame.EntityName.NameText.TextScaled = false
		
		teamConnections[data.Instance.Name] = {
			data.Instance.PlayerAdded:Connect(updateStats),
			data.Instance.PlayerRemoved:Connect(updateStats)
		}
		
		updateStats()
	end
	
	slot.Parent = ScrollingFrame
end

local function removeSlot(data)
	if (data.GuiObject) then
		data.GuiObject:Destroy()
	end
	
	local connectionTable = data.Type == 'Player' and playerConnections or teamConnections
	local connectionData = connectionTable[data.Instance.Name]
	if (connectionData) then
		for i,connection in pairs (connectionData) do
			connection:Disconnect()
		end
	end
	
	connectionTable[data.Instance.Name] = nil
end

local function onPlayerAdded(player)
	if find(playerData, player) then return end
	
	playerConnections[player.Name] = {}
	local connections = playerConnections[player.Name]

	local playerTable = createEntityTable(player)
	insert(playerData, playerTable)
	addSlot(playerTable)
	
	local leaderstatsObject 
	
	local function onLeaderstatChildRemoved(statChild : Instance)
		checkGameStatsExist(player)

		local statText = playerTable.GuiObject and playerTable.GuiObject:FindFirstChild('Stat_'..statChild.Name)
		if (statText) then
			statText.Text = '-'
		end

		if (player.Team) then
			local tData = teamData[find(teamData, player.Team)]
			local statObj = tData.GuiObject:FindFirstChild('Stat_'..statChild.Name)

			if (statObj) then
				local value = addUpPlayerStatOfTeam(tData.Instance, statChild.Name)
				statObj.Text = FormatStatString(value)
			end
		end

		connections[statChild.Name]:Disconnect()
		connections[statChild.Name] = nil
	end
	
	local function onLeaderstatsAdded(child : Instance)
		if (child.Name == 'leaderstats' and not leaderstatsObject) then
			leaderstatsObject = child
			
			local function leaderstatsChildAdded(statChild : Instance)
				if (isValidStat(statChild)) then
					local exists, stat : Stat = gameStatExists(statChild.Name)
					if not (exists) then
						addGameStat(statChild)
					else
						addUIStat(playerTable, stat)
					end
					
					connections[statChild.Name] = statChild.Changed:Connect(function(newValue)
						local statText = playerTable.GuiObject and playerTable.GuiObject:FindFirstChild('Stat_'..statChild.Name)
						local statType = type(newValue)

						if (statText) then
							if (statType == 'number') then
								statText.Text = FormatStatString(newValue)
							else
								statText.Text = newValue
							end
						end

						if (player.Team and statType == 'number') then
							local tData = teamData[find(teamData, player.Team)]
							local value = addUpPlayerStatOfTeam(tData.Instance, statChild.Name)
							tData.GuiObject['Stat_'..statChild.Name].Text = FormatStatString(value)
						end
					end)
				end
			end

			connections.LeaderstatsChildAdded = child.ChildAdded:Connect(leaderstatsChildAdded)
			connections.LeaderstatsChildRemoved = child.ChildRemoved:Connect(onLeaderstatChildRemoved)
			
			for i, preExistingChild in pairs (child:GetChildren()) do
				leaderstatsChildAdded(preExistingChild)
			end
		else
			if (child.Name == 'leaderstats') then
				child:Destroy()
				warn("Cannot have more than one child with the name of 'leaderstats' inside of Player object")
			end
		end
	end
	
	connections.LeaderstatsAdded = player.ChildAdded:Connect(onLeaderstatsAdded)
	connections.LeaderstatsRemoved = player.ChildRemoved:Connect(function(child : Instance)
		if (child == leaderstatsObject) then
			leaderstatsObject = nil
			checkGameStatsExist(player)
			
			for i,v in pairs (child:GetChildren()) do
				onLeaderstatChildRemoved(v)
			end
			
			connections.LeaderstatsChildAdded:Disconnect()
			connections.LeaderstatsChildRemoved:Disconnect()
			connections.LeaderstatsChildAdded = nil
			connections.LeaderstatsChildRemoved = nil
		end
	end)
	
	connections.TeamChanged = player:GetPropertyChangedSignal('Team'):Connect(sortPlayersAndTeams)
	
	ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, (#playerData * 40))
	if player:FindFirstChild('leaderstats') then
		onLeaderstatsAdded(player.leaderstats)
	end
	sortPlayersAndTeams()
end

local function onPlayerRemoving(player)
	local dataIndex = find(playerData, player)
	removeSlot(playerData[dataIndex])
	remove(playerData, dataIndex)
	
	ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, (#playerData * 40))
	sortPlayersAndTeams()
end


local function onInput(action, state)
	if state == Enum.UserInputState.Begin then
		isShowing = not isShowing
		
		do
			local h, s, v = ToggleButton.ImageColor3:ToHSV()
			local h2, s2, v2 = ToggleFrame.BackgroundColor3:ToHSV()

			ToggleButton.ImageColor3 = Color3.fromHSV(h, s, (1 - v))
			ToggleFrame.BackgroundColor3 = Color3.fromHSV(h2, s2, (1 - v2))
		end
		
		if (isShowing) then
			OffsetFrame.Visible = true
			OffsetFrame:TweenPosition(appearPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, .05, false)
		else
			
			OffsetFrame:TweenPosition(disappearPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, .05, false, function()
				OffsetFrame.Visible = false
			end)
		end
	end
end

guiConnections[#guiConnections + 1] = PS.PlayerAdded:Connect(onPlayerAdded)
guiConnections[#guiConnections + 1] = PS.PlayerRemoving:Connect(onPlayerRemoving)
guiConnections[#guiConnections + 1] = TMS.ChildAdded:Connect(onTeamAdded)
guiConnections[#guiConnections + 1] = TMS.ChildRemoved:Connect(onTeamRemoved)

guiConnections[#guiConnections + 1] = playerBlocked.Event:Connect(function(blockedPlayer)
	local pData = playerData[find(playerData, blockedPlayer)] 
	blockedUsers[#blockedUsers + 1] = blockedPlayer.UserId

	if not (pData) then
		task.spawn(function()
			repeat task.wait() pData = playerData[find(playerData, blockedPlayer)] until pData

			if not pData.GuiObject then
				repeat task.wait() until pData.GuiObject
			end

			local icon = pData.GuiObject.NameFrame.Icon
			updateIcon(icon, true, blockedPlayer)
		end)

	elseif not pData.GuiObject then

		task.spawn(function()
			repeat task.wait() until pData.GuiObject

			local icon = pData.GuiObject.NameFrame.Icon
			updateIcon(icon, true, blockedPlayer)
		end)

	else
		local icon = pData.GuiObject.NameFrame.Icon
		updateIcon(icon, true, blockedPlayer)
	end
	
end)

guiConnections[#guiConnections + 1] = playerUnblocked.Event:Connect(function(blockedPlayer)
	local icon = playerData[find(playerData, blockedPlayer)].GuiObject.NameFrame.Icon
	local index = table.find(blockedUsers, blockedPlayer.UserId)
	remove(blockedUsers, blockedPlayer)
	updateIcon(icon, false, blockedPlayer)
end)

guiConnections[#guiConnections + 1] = playerFriended.Event:Connect(function(friendedPlayer)
	local pData = playerData[find(playerData, friendedPlayer)]
	
	if not (pData) then
		task.spawn(function()
			repeat task.wait() pData = playerData[find(playerData, friendedPlayer)] until pData
			
			if not pData.GuiObject then
				repeat task.wait() until pData.GuiObject
			end
			
			local icon = pData.GuiObject.NameFrame.Icon
			updateIcon(icon, (table.find(blockedUsers, friendedPlayer) and true) or false, friendedPlayer)
		end)
		
	elseif not (pData.GuiObject) then
		
		task.spawn(function()
			repeat task.wait() until pData.GuiObject
			
			local icon = pData.GuiObject.NameFrame.Icon
			updateIcon(icon, (table.find(blockedUsers, friendedPlayer) and true) or false, friendedPlayer)
		end)
		
	else
		local icon = pData.GuiObject.NameFrame.Icon
		updateIcon(icon, (table.find(blockedUsers, friendedPlayer) and true) or false, friendedPlayer)
	end
end)

guiConnections[#guiConnections + 1] = playerUnfriended.Event:Connect(function(friendedPlayer)
	local icon = playerData[find(playerData, friendedPlayer)].GuiObject.NameFrame.Icon
	updateIcon(icon, (table.find(blockedUsers, friendedPlayer) and true) or false, friendedPlayer)
end)

guiConnections[#guiConnections + 1] = ToggleButton.MouseButton1Click:Connect(function()
	onInput(nil, Enum.UserInputState.Begin)
end)

for i,v in ipairs (PS:GetPlayers()) do
	onPlayerAdded(v)
end

CAS:BindAction('Appear', onInput, false, Enum.KeyCode.Tab)
sortPlayersAndTeams()

GUI.Enabled = true
GUI.Parent = localPlayer.PlayerGui
return GUI

I’m looking to refresh the leaderboard each time a team switch is detected.

In your on player added function you should connect a function to :GetPropertyChangedSignal() you can do this like this:

player:GetPropertyChangedSignal("Team"):Connect(function()
       print("Player Team Changed!")
       -- Refresh code here or what ever is needed
end)

as I’m a new scripter, I am unsure of which line you’re speaking of, as I can select two playeradded functions within the module.

I would do it somewhere in local function onPlayerAdded(player) im not sure what line its on cause thats not a thing thats listed