Basically, in my script, i want the script to add a frame if a player join the game and remove a frame if the player leave the game. I want the frame to actualise if the player party stats changes to check if the player can be invited or not.
How do i know there is a memory leak going:
The client fire multiple time the remote when pressing the invite button
Multiple connections are made at every 1 seconds
The script:
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Indentify remotes
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents",3)
local PartyRemotes = RemoteEvents:WaitForChild("Party",3)
local CallPartyInvitation = PartyRemotes.CallPartyInvitation
local StartParty = PartyRemotes.StartParty
local SendPartyInvitation = PartyRemotes.SendPartyInvitation
local scrollingframe = script.Parent.ScrollingHolder.ScrollingFrame
function ColorButton(template,player)
if not template then
print("no template")
return
end
if player and player:FindFirstChild("PlayerStats") and player.PlayerStats:FindFirstChild("PartyStats") then
if player.PlayerStats.PartyStats.Party.Value == Players.LocalPlayer.UserId then
template.Invite.Text.Text = "Kick"
template.Invite.BackgroundColor3 = Color3.new(1, 0, 0)
template.Invite.TextButton.MouseButton1Click:Connect(function()
CallPartyInvitation:FireServer(player,"Kick")
end)
return
end
if player.UserId == Players.LocalPlayer.UserId then
template.Invite.Text.Text = "You"
template.Invite.BackgroundColor3 = Color3.new(0.666667, 0.666667, 0.666667)
return
end
if player.PlayerStats.PartyStats.PartyInviteId.Value == Players.LocalPlayer.UserId then
template.Invite.Text.Text = "Invited"
template.Invite.BackgroundColor3 = Color3.new(0.666667, 0.666667, 0.666667)
return
end
if player.PlayerStats.PartyStats.PartyInviteId.Value == 0 and player.PlayerStats.PartyStats.Party.Value == 0 and player.UserId ~= Players.LocalPlayer.UserId then
template.Invite.Text.Text = "Invite"
template.Invite.BackgroundColor3 = Color3.new(0, 0.666667, 0)
template.Invite.TextButton.MouseButton1Click:Connect(function()
CallPartyInvitation:FireServer(player,"Invite")
end)
return
end
end
end
script.Parent.Start.TextButton.MouseButton1Click:Connect(function()
StartParty:FireServer()
end)
local PlayersInYourParty = {}
while wait(1) do
PlayersInYourParty = {}
for _,frame in scrollingframe:GetChildren() do
if frame:IsA("Frame") and frame.Name ~= "Template" and not Players:FindFirstChild(frame.Name) then
frame:Destroy()
end
end
for i, player in Players:GetPlayers() do
if not scrollingframe:FindFirstChild(player.Name) then
print("Added frame")
local template = scrollingframe.Template:Clone()
template.Parent = scrollingframe
template.Visible = true
template.Name = player.Name
template.TextLabel.Text = player.Name
local success, errorm = pcall(function()
template.FrameForImage.PlayerImage.Image = Players:GetUserThumbnailAsync(player.UserId,Enum.ThumbnailType.HeadShot,Enum.ThumbnailSize.Size60x60)
end)
if not success then
print(errorm)
end
ColorButton(template,player)
end
-- Color the button depending if user is free
for _,frame in scrollingframe:GetChildren() do
if frame.Name == player.Name then
template = frame
ColorButton(template,player)
end
end
if player.PlayerStats.PartyStats.Party.Value == Players.LocalPlayer.UserId then
table.insert(PlayersInYourParty,player)
end
end
script.Parent.ActivePlayers.Text = #PlayersInYourParty.."/50"
if #PlayersInYourParty > 0 then
script.Parent.Start.BackgroundColor3 = Color3.new(0.333333, 1, 0)
else
script.Parent.Start.BackgroundColor3 = Color3.new(0.298039, 0.298039, 0.298039)
end
end
Does anyone have solution for that script or a similar system that could work and not ruin the player memory?
Did you ask an Ai already? If there’s a really obvious source of memory leak they detect those pretty easily (something like forgetting to destroy an object or disconnect events).
I personally can’t help you though because I’m not good at scripting yet.
Yeah there is a leak in ColorButton() where you’re connecting MouseButton1Click everytime this is called.
Since this function is being called in a loop it creates multiple connections every second.
I think you could use a ChildAdded event for the scrollingframe to then call the ColorButton function which looks more like a setup function for the button to me.
From there it’d be easier to actually handle the button logic, using loops might keep causing headaches like this in the future
They should not disconnect especially when the player party value change, its the most important part of the system. The frame should allow to invite and kick somewone from the party.
Well is the server or the client handling the connection of clicking the button? As clients are preferred and 100% more efficient on handling user input stuff for gui
I fixed the script and eleminated 80% of the memory leak capacity
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Indentify remotes
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents",3)
local PartyRemotes = RemoteEvents:WaitForChild("Party",3)
local CallPartyInvitation = PartyRemotes.CallPartyInvitation
local StartParty = PartyRemotes.StartParty
local SendPartyInvitation = PartyRemotes.SendPartyInvitation
local scrollingframe = script.Parent.ScrollingHolder.ScrollingFrame
-- Set Player
local LocalPlayer = Players.LocalPlayer
function ColorButton(template,player)
if not template then
print("no template")
return
end
if not player then
print("No player found")
return
end
if player and player:FindFirstChild("PlayerStats") and player.PlayerStats:FindFirstChild("PartyStats") then
if player.PlayerStats.PartyStats.Party.Value == Players.LocalPlayer.UserId then
template.Invite.Text.Text = "Kick"
template.Invite.BackgroundColor3 = Color3.new(1, 0, 0)
return
end
if player.UserId == Players.LocalPlayer.UserId then
template.Invite.Text.Text = "You"
template.Invite.BackgroundColor3 = Color3.new(0.666667, 0.666667, 0.666667)
return
end
if player.PlayerStats.PartyStats.PartyInviteId.Value == Players.LocalPlayer.UserId then
template.Invite.Text.Text = "Invited"
template.Invite.BackgroundColor3 = Color3.new(0.666667, 0.666667, 0.666667)
return
end
if player.PlayerStats.PartyStats.PartyInviteDebounce.Value then
template.Invite.Text.Text = "Busy"
template.Invite.BackgroundColor3 = Color3.new(0.666667, 0.666667, 0.666667)
return
end
if player.PlayerStats.PartyStats.PartyInviteId.Value == 0 and player.PlayerStats.PartyStats.Party.Value == 0 and player.UserId ~= Players.LocalPlayer.UserId then
template.Invite.Text.Text = "Invite"
template.Invite.BackgroundColor3 = Color3.new(0, 0.666667, 0)
return
end
end
end
function HandleFrameButtons(template,player)
local PlayerLeftConnection
local PartyStatChangedConnection
local PartyInviteIdStatChangedConnection
local PartyInviteDebounceConnection
local ButtonConnection
-- Find the stats
local PlayerStats = player:WaitForChild("PlayerStats",3)
local PartyStats = PlayerStats:WaitForChild("PartyStats",3)
-- The stats
local Party = PartyStats:WaitForChild("Party",3)
local PartyInviteId = PartyStats:WaitForChild("PartyInviteId",3)
local PartyInviteDebounce = PartyStats:WaitForChild("PartyInviteDebounce",3)
-- Connect if the player leave
PlayerLeftConnection = Players.PlayerRemoving:Connect(function(leavingplayer)
if leavingplayer == player then
-- Disconnect the stats
PartyStatChangedConnection:Disconnect()
PlayerLeftConnection:Disconnect()
PartyInviteDebounceConnection:Disconnect()
-- Disconnect the button
ButtonConnection:Disconnect()
-- Delete the template
template:Destroy()
player = nil
template = nil
end
end)
-- Connect when inviteid stat change
PartyInviteIdStatChangedConnection = PartyInviteId:GetPropertyChangedSignal("Value"):Connect(function()
ColorButton(template,player)
end)
-- Connect when party stat change
PartyStatChangedConnection = Party:GetPropertyChangedSignal("Value"):Connect(function()
ColorButton(template,player)
end)
-- Connect if player debounce is changing
PartyInviteDebounceConnection = PartyInviteDebounce:GetPropertyChangedSignal("Value"):Connect(function()
ColorButton(template,player)
end)
-- Connect when the button is clicked
ButtonConnection = template.Invite.InviteButton.MouseButton1Click:Connect(function()
if template.Invite.BackgroundColor3 == Color3.new(0, 0.666667, 0) then
if template.Invite.Text.Text == "Invite" then
game.ReplicatedStorage.RemoteEvents.Party.CallPartyInvitation:FireServer(player,"Invite")
else
return
end
elseif template.Invite.BackgroundColor3 == Color3.new(1, 0, 0) then
if template.Invite.Text.Text == "Kick" then
game.ReplicatedStorage.RemoteEvents.Party.CallPartyInvitation:FireServer(player,"Kick")
else
return
end
else
return
end
end)
end
function CreateFrame(player)
local success,err = pcall(function()
local template = scrollingframe.Template:Clone()
template.Parent = scrollingframe
template.Visible = true
template.Name = player.Name
template.TextLabel.Text = player.Name
local successi, errorm = pcall(function()
template.FrameForImage.PlayerImage.Image = Players:GetUserThumbnailAsync(player.UserId,Enum.ThumbnailType.HeadShot,Enum.ThumbnailSize.Size60x60)
end)
if not successi then
print(errorm)
end
ColorButton(template,player)
-- Handle Buttons
task.spawn(HandleFrameButtons,template,player)
end)
if not success then
warn("FAILED CREATING PARTY FRAME : "..err)
end
end
-- Get all players in server when joigning
for _, player in Players:GetPlayers() do
CreateFrame(player)
end
-- Connect to player addeds
Players.PlayerAdded:Connect(function(player)
task.wait(0.05)
CreateFrame(player)
end)
script.Parent.Start.TextButton.MouseButton1Click:Connect(function()
StartParty:FireServer()
end)
local PlayersInYourParty = {}
while wait(1) do
PlayersInYourParty = {}
for _, player in Players:GetPlayers() do
if player.PlayerStats.PartyStats.Party.Value == LocalPlayer.UserId then
table.insert(PlayersInYourParty,player)
end
end
script.Parent.ActivePlayers.Text = #PlayersInYourParty.."/50"
if #PlayersInYourParty > 0 then
script.Parent.Start.BackgroundColor3 = Color3.new(0.333333, 1, 0)
else
script.Parent.Start.BackgroundColor3 = Color3.new(0.298039, 0.298039, 0.298039)
end
end