Remote event firing is stacking up

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!
    I’m trying to prevent a remote event from stacking each time I fire it.

  2. What is the issue? Include screenshots / videos if possible!
    Each time I click an Image button in my shop system, it proceeds to fire correctly to the server, however each time I click an image button it fires and stacks up.
    https://youtu.be/WC0QZ-OWdeo

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve looked through a few of the dev forum posts around remote event stacking, however none of them have worked correctly for my situation, connection/disconnection, creating specific variables to prevent new triggers. It’s likely that I haven’t applied those solutions accordingly but I’m not sure where to go from here.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local playerUi = player.PlayerGui
local shopUi = playerUi.MainUI.Shop
local inGameUi = playerUi.InGameUi.InGame
local inLobbyUi = playerUi.MainUI.InLobby
local equipButton = player.PlayerGui.MainUI.Shop.ContentFrame.Equip
local equippedButton = player.PlayerGui.MainUI.Shop.ContentFrame.Equipped
local buyButton = player.PlayerGui.MainUI.Shop.ContentFrame.Buy
	
local shopEvent = rs.Remotes:WaitForChild("ShopEvent")
local buttonEvent = rs.Remotes:WaitForChild("ButtonEvent")
local buyEvent = rs.Remotes:WaitForChild("BuyEvent")
local equipEvent = rs.Remotes:WaitForChild("EquipEvent")
	
shopUi:GetPropertyChangedSignal("Visible"):Connect(function()
	if shopUi.Visible == true then
		for _,button : ImageButton in pairs(shopUi.ContentFrame.ItemContainer:GetChildren()) do --> Finds all the image buttons under Shop UI
				local shimeStart = shimeManager.new(button, 1.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.InOut, math.huge, false, 0.6)
				if not button:IsA("ImageButton") then continue end
				if shopUi.Visible == false then
					shimeStart:Pause()
				elseif button.Name == "Legendary" or button.Name == "Mythic" then
					shimeStart:Play()
				end
				button.MouseButton1Down:Connect(function()
					if not button.Parent:FindFirstChildOfClass("ImageButton") then return end
					local hammerClicked = button:FindFirstChild("Hammer").Value
					shopEvent:FireServer(button, hammerClicked)
				end)
			end
		end
	end)

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

2 Likes

you make an if statement for when its visible but then

you check if it isnt. (which can never happen)

try this instead:

local shimes = {}
for _, button in shopUi.ContentFrame.ItemContainer:GetChildren() do
	if not button:IsA("ImageButton") then continue end
	
	if button.Name == "Legendary" or button.Name == "Mythic" then
		shimes[button] = shimeManager.new(button, 1.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.InOut, math.huge, false, 0.6)
	end	

	button.MouseButton1Down:Connect(function()
--[[weird check]] if not button.Parent:FindFirstChildOfClass("ImageButton") then return end
		shopEvent:FireServer(button, button:FindFirstChild("Hammer").Value)
	end)
end

shopUi:GetPropertyChangedSignal("Visible"):Connect(function()
	local f = shopUi.Visible and "Play" or "Pause"
	for _, shime in shimes do
		shime[f](shime)
	end
end)

This is a huge memory leak right here.

Much appreciated for the reply,

I’ve tried implementing it, however I still have the same issue, it does solve one small bug I have so thank you for that.

Here is a ss:

I appreciate the reply. But it doesn’t really help me with my issue, do you have any idea on how I can prevent the said memory leak? Any post I can look at?

can you share the server script?

my solution already prevents it

1 Like

Sure, how do you want me to share it?

Like @Hzodx said his solution does prevent the memory leak, but to understand why it is a memory leak it’s because every time that remote event is fired you’re connecting an event to a function each time. Which uses up memory.

1 Like

prefferably paste a part of it here

Ok, here is the server script for the event.

shopEvent.OnServerEvent:Connect(function(player, button, hammerClicked) --> Manages what appears when the hammer profiles are clicked
		local player = player
		local profile = dataManager.Profiles[player]
		if not profile then return end
		
		local stringHammerEquip = player.PlayerGui.MainUI.Shop.ContentFrame.Equip.Hammer
		local stringHammerBuy = player.PlayerGui.MainUI.Shop.ContentFrame.Buy.Hammer
		
		if not table.find(profile.Data.Hammers, tostring(button.Hammer.Value)) and button.Hammer.Value ~= profile.Data.EquippedHammer then
			local buttonType = "Buy"
			stringHammerBuy.Value = hammerClicked
			buttonEvent:FireClient(player, buttonType)
		end
		if button.Hammer.Value ~= profile.Data.EquippedHammer and table.find(profile.Data.Hammers, tostring(button.Hammer.Value)) then
			local buttonType = "Equip"
			stringHammerEquip.Value = hammerClicked
			buttonEvent:FireClient(player, buttonType)
		end
		if button.Hammer.Value == profile.Data.EquippedHammer then
			local buttonType = "Equipped"
			buttonEvent:FireClient(player, buttonType)
		end
		
	end)

I apologize if its seems a bit messy or hard to understand

Sure is messy. Would you be so kind and share where the print statement is located?

Also, yikes, You should never get anything from the ui of a player it’s just bad practice.
You also are sending strings for what the button should say. But rather, you should be sending the player’s data to them and letting the client decide what it should say

Sorry i can’t send it right now. I’ll send it in an hour or so. Also about the managing on the client isn’t it risky or exploitable?

Thanks again for the help

No, once you send the player their inventory they can’t change it on the server side (unless you somehow allow that)

This is where the print statement is,

	equipEvent.OnServerEvent:Connect(function(player) --> Equip the hammer that the player clicked 
		local player = player
		local profile = dataManager.Profiles[player]
		if not profile then return end
		local stringHammerEquip = player.PlayerGui.MainUI.Shop.ContentFrame.Equip.Hammer
		local buttonType = "Equipped"
		player.Character:FindFirstChild("Handle"):Destroy()
		player.Character:FindFirstChild(profile.Data.EquippedHammer):Destroy()
		profile.Data.EquippedHammer = stringHammerEquip.Value
		print("[ShopHandler]: " .. stringHammerEquip.Value .. " Has been Equipped")
		buttonEvent:FireClient(player, buttonType)
		equipHandler.checkValues(profile, player, player.Character)
	end)

Here is the client side action

buttonEvent.OnClientEvent:Connect(function(buttonType, hammerClicked) --> Manages what appears when the hammer profiles are clicked
		if buttonType == "Equipped" then
			equipButton.Visible = false
			equippedButton.Visible = true
			buyButton.Visible = false
		elseif buttonType == "Equip" then
			equipButton.Visible = true
			equippedButton.Visible = false
			buyButton.Visible = false
			equipButton.MouseButton1Down:Connect(function()
				equipEvent:FireServer(hammerClicked)
			end)
		elseif buttonType == "Buy" then
			equipButton.Visible = false
			equippedButton.Visible = false
			buyButton.Visible = true
			buyButton.MouseButton1Down:Connect(function()
				buyEvent:FireServer(hammerClicked)
			end)
		end
	end)

ah, there it is.

You are connecting a mouse button click function every time the client recieves a string.
You are making signals, inside of signals and you dont properly clean them up.

1 Like

Damn, I assumed it was something like that but I couldn’t tell where. Thank you very much, would you have any advice on how I could clean it up. Sorry for asking so much.

I can only offer you a bandaid solution, your entire client to server interactions need to be remade

change the client to:

buttonEvent.OnClientEvent:Connect(function(buttonType, hammerClicked)
		if buttonType == "Equipped" then
			equipButton.Visible = false
			equippedButton.Visible = true
			buyButton.Visible = false
		elseif buttonType == "Equip" then
			equipButton.Visible = true
			equippedButton.Visible = false
			buyButton.Visible = false
		elseif buttonType == "Buy" then
			equipButton.Visible = false
			equippedButton.Visible = false
			buyButton.Visible = true
		end
	end)

equipButton.MouseButton1Down:Connect(function()
	equipEvent:FireServer(hammerClicked)
end)

buyButton.MouseButton1Down:Connect(function()
	buyEvent:FireServer(hammerClicked)
end)

Realistically you have only 1 button and just change it’s functionality depending on the current item selected and your inventory

Yeah, that’s originally what I wanted to do, however the person I’m working with created a UI that has a font that cannot be changed in the game, so I’m forced to work with multiple image buttons rather only one.

Anyway, your help is greatly appreciated I’ll probably try and remake the system based on the information you’ve given me!

1 Like

you can just… button.Image = “rbxassetid://idhere”

1 Like