Urgent issue related to tools and lagging

Greetings. I just figured out this insane performance bug in my game.
If a player is clicking fast enough, in this case autoclicking on a tool in its inventory, after about 5 to 10 seconds itll start droppign their fps like INSANE until they stop equipping and unequipping

What can i do to fix this?? could i make it so that theres an autoclicker detector for when equipping and unequipping any tool?

What are you doing when you equip and unequip?

there’s multiple tools and they have different functions,

ill take the first one as example:

--// Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local mouse = player:GetMouse()
local removeModeEnabled = false
local currentHighlight = nil
local swimmablePart = workspace:WaitForChild("WorkingWater"):WaitForChild("SwimmablePart")
local playerHighlight = nil
local tooltipGui = nil
local tooltipLabel = nil


local confirmUI = player:WaitForChild("PlayerGui"):WaitForChild("RemoveConfirmUI")
local yesButton = confirmUI.ConfirmFrame.Yes
local noButton = confirmUI.ConfirmFrame.No
local confirmLabel = confirmUI.ConfirmFrame.PlacingLabel
local confirmInfo = confirmUI.ConfirmFrame.FishDesc

local removeFishEvent = ReplicatedStorage.RemoteEvents:WaitForChild("RemoveFishRequest")
local fishToRemove = nil
local fovTween = nil

local REMOVE_TOOL_NAMES = {
	["Bucket [Remove fishes]"] = true,
	["Bucket [Remove fish]"] = true
}

local function createTooltipUI()
	tooltipGui = Instance.new("ScreenGui")
	tooltipGui.Name = "RemoveTooltip"
	tooltipGui.ResetOnSpawn = false
	tooltipGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
	tooltipGui.IgnoreGuiInset = true
	tooltipGui.Parent = player:WaitForChild("PlayerGui")

	tooltipLabel = Instance.new("TextLabel")
	tooltipLabel.Name = "TooltipLabel"
	tooltipLabel.AnchorPoint = Vector2.new(0, 0)
	tooltipLabel.BackgroundTransparency = 0.3
	tooltipLabel.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
	tooltipLabel.BorderSizePixel = 0
	tooltipLabel.Text = "Click to remove fish 🗑️"
	tooltipLabel.FontFace = Font.new("rbxasset://fonts/families/GothamSSm.json", Enum.FontWeight.Bold, Enum.FontStyle.Normal)
	tooltipLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
	tooltipLabel.TextSize = 14
	tooltipLabel.TextScaled = false
	tooltipLabel.TextWrapped = true
	tooltipLabel.TextXAlignment = Enum.TextXAlignment.Center
	tooltipLabel.TextYAlignment = Enum.TextYAlignment.Center
	tooltipLabel.Position = UDim2.fromOffset(0, 0)
	tooltipLabel.Size = UDim2.fromOffset(180, 24)
	tooltipLabel.Visible = false
	tooltipLabel.Parent = tooltipGui

	local stroke = Instance.new("UIStroke")
	stroke.Color = Color3.fromRGB(255, 75, 75)
	stroke.Thickness = 2
	stroke.Transparency = 0.3
	stroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
	stroke.LineJoinMode = Enum.LineJoinMode.Round
	stroke.Parent = tooltipLabel

	local corner = Instance.new("UICorner")
	corner.CornerRadius = UDim.new(0, 6)
	corner.Parent = tooltipLabel
end


--// Get Player Farm
local function getPlayerFarm()
	for _, farm in ipairs(workspace.Farms:GetChildren()) do
		if farm:GetAttribute("AssignedPlayer") == player.Name then
			return farm
		end
	end
	return nil
end

--// Enable/Disable Fish ClickDetectors
local function setFishClickDetectors(enabled)
	local farm = getPlayerFarm()
	if not farm then return end
	for _, model in ipairs(farm:GetDescendants()) do
		if model:IsA("Model") and model:GetAttribute("WeightKg") then
			local cd = model:FindFirstChildOfClass("ClickDetector")
			if cd then
				cd.MaxActivationDistance = enabled and 100 or 0
			end
		end
	end
end

--// Highlight Functions
local function showHighlight(model)
	if currentHighlight then currentHighlight:Destroy() end
	local highlight = Instance.new("Highlight")
	highlight.FillColor = Color3.new(0.666667, 0, 0)
	highlight.OutlineColor = Color3.new(0.333333, 0, 0)
	highlight.FillTransparency = 0.8
	highlight.OutlineTransparency = 0.3
	highlight.DepthMode = Enum.HighlightDepthMode.Occluded
	highlight.Adornee = model
	highlight.Parent = model
	currentHighlight = highlight
end

local function clearHighlight()
	if currentHighlight then
		currentHighlight:Destroy()
		currentHighlight = nil
	end
end

--// Remove Mode Toggle
local function onToolEquipped(tool)
	if not REMOVE_TOOL_NAMES[tool.Name] then return end
	removeModeEnabled = true
	createTooltipUI()

	-- ✅ Show RemoveMode UI
	local removeModeUI = player:WaitForChild("PlayerGui"):FindFirstChild("RemoveMode")
	if removeModeUI then
		removeModeUI.Enabled = true
	end

	-- Player highlight
	local char = player.Character
	if char and not playerHighlight then
		playerHighlight = Instance.new("Highlight")
		playerHighlight.FillColor = Color3.fromRGB(170, 0, 0)
		playerHighlight.OutlineColor = Color3.fromRGB(170, 0, 0)
		playerHighlight.FillTransparency = 1
		playerHighlight.OutlineTransparency = 0.3
		playerHighlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
		playerHighlight.Adornee = char
		playerHighlight.Parent = char
	end

	setFishClickDetectors(true)

	if swimmablePart then
		swimmablePart.CanQuery = false
	end

	local farm = getPlayerFarm()
	if farm then
		for _, part in ipairs(farm:GetDescendants()) do
			if part:IsA("BasePart") and part.Name == "EggPlacementArea" then
				part.CanQuery = false
			end
		end
	end

	print("🗑️ Remove mode activated.")
end

local function onToolUnequipped(tool)
	if not REMOVE_TOOL_NAMES[tool.Name] then return end
	removeModeEnabled = false

	-- ✅ Hide RemoveMode UI
	local removeModeUI = player:WaitForChild("PlayerGui"):FindFirstChild("RemoveMode")
	if removeModeUI then
		removeModeUI.Enabled = false
	end

	if fovTween then
		fovTween:Cancel()
		fovTween = nil
	end

	if playerHighlight then
		playerHighlight:Destroy()
		playerHighlight = nil
	end


	if tooltipGui then
		tooltipGui:Destroy()
		tooltipGui = nil
		tooltipLabel = nil
	end


	setFishClickDetectors(false)
	clearHighlight()

	if swimmablePart then
		swimmablePart.CanQuery = true
	end

	local farm = getPlayerFarm()
	if farm then
		for _, part in ipairs(farm:GetDescendants()) do
			if part:IsA("BasePart") and part.Name == "EggPlacementArea" then
				part.CanQuery = true
			end
		end
	end

	print("✅ Remove mode deactivated.")
end

--// Setup listeners
local function setupToolListeners(character)
	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") and REMOVE_TOOL_NAMES[child.Name] then
			child.Equipped:Connect(function() onToolEquipped(child) end)
			child.Unequipped:Connect(function() onToolUnequipped(child) end)
		end
	end)

	for _, tool in ipairs(character:GetChildren()) do
		if tool:IsA("Tool") and REMOVE_TOOL_NAMES[tool.Name] then
			tool.Equipped:Connect(function() onToolEquipped(tool) end)
			tool.Unequipped:Connect(function() onToolUnequipped(tool) end)
		end
	end
end

player.CharacterAdded:Connect(setupToolListeners)
if player.Character then
	setupToolListeners(player.Character)
end

--// Mouse Click (Confirm UI Trigger)
mouse.Button1Down:Connect(function()
	if not removeModeEnabled then return end
	game:GetService("SoundService")["Favorite&DeleteClick"]:Play()
	local target = mouse.Target
	if not target then return end

	local model = target:FindFirstAncestorOfClass("Model")
	if not model or not model:GetAttribute("WeightKg") then return end
	if not model:FindFirstChildOfClass("ClickDetector") then return end

	local farm = getPlayerFarm()
	if not farm or not model:IsDescendantOf(farm) then return end -- 🛑 Block clicks outside player's farm

	local infoUI = model:FindFirstChild("Info_UI")
	if infoUI then
		local label = infoUI:FindFirstChildWhichIsA("TextLabel", true)
		if label then
			confirmLabel.Text = "You're about to delete:"
			confirmInfo.Text = label.Text
			confirmInfo.TextColor3 = label.TextColor3
		else
			confirmInfo.Text = "(no label found)"
			confirmInfo.TextColor3 = Color3.new(1, 1, 1)
		end
	else
		confirmInfo.Text = "(no Info_UI found)"
		confirmInfo.TextColor3 = Color3.new(1, 1, 1)
	end

	fishToRemove = model
	confirmUI.Enabled = true
end)


--// Highlight Loop
RunService.RenderStepped:Connect(function()
	if not removeModeEnabled then
		clearHighlight()
		if tooltipLabel then
			tooltipLabel.Visible = false
		end
		return
	end

	local target = mouse.Target
	if not target then
		clearHighlight()
		if tooltipLabel then
			tooltipLabel.Visible = false
		end
		return
	end

	local model = target:FindFirstAncestorOfClass("Model")
	local farm = getPlayerFarm()
	local validTarget = model and model:GetAttribute("WeightKg") and model:FindFirstChildOfClass("ClickDetector") and farm and model:IsDescendantOf(farm)

	if validTarget then
		if not currentHighlight or currentHighlight.Adornee ~= model then
			showHighlight(model)
		end

		if tooltipLabel then
			tooltipLabel.Visible = true
			tooltipLabel.Position = UDim2.fromOffset(mouse.X + 16, mouse.Y + 16)
		end
	else
		clearHighlight()
		if tooltipLabel then
			tooltipLabel.Visible = false
		end
	end
end)


--// Confirmation Buttons
yesButton.MouseButton1Click:Connect(function()
	if fishToRemove then
		if fishToRemove:GetAttribute("IsFavorite") then
		game:GetService("SoundService").FailDelete:Play()
			confirmLabel.Text = "⚠️ Cannot delete favorited fish!"
			confirmInfo.Text = "Unfavorite it first."
			confirmInfo.TextColor3 = Color3.fromRGB(255, 85, 85)
			task.delay(2.5, function()
				confirmUI.Enabled = false
			end)
			return
		end
		removeFishEvent:FireServer(fishToRemove)
		game:GetService("SoundService").RemovedSound:Play()
	end
	fishToRemove = nil
	confirmUI.Enabled = false
end)

noButton.MouseButton1Click:Connect(function()
	fishToRemove = nil
	confirmUI.Enabled = false
end)

This is pretty much what it does.
There’s a GUI appearing when tool is equipped and unequipped and a highlight inside the player.

Could we get a model of the tool itself? It would help to see the issue ourselves.

Well i could send you the tool itself and the localscript i gave you but it not everything will work by itself like that as its connected to some other scripts

fish removing.lua (9.3 KB)
bucket tool.rbxm (23.0 KB)

I think it might be because of your script firing remoteevents or doing a lot of things on tool.Equipped and tool.Unequipped so when the tool is repeatedly equipped and unequipped it gets overwhelmed causing the lag. I’d recommend doing some basic counter thing which you reset every second for example:

local Clicks = 0
local MaxClicksPerSecond = 10
tool.Equipped:Connect(function()
    Clicks += 1
    if Clicks < MaxClicksPerSecond then
        -- you continue your code
    else
        Humanoid:UnequipTools()
        print("Player is spamming Equip/Unequip")
    end
end)
tool.Unequipped:Connect(function()
    Clicks += 1
    if Clicks < MaxClicksPerSecond then
        -- you continue your code
    else
        print("Player is spamming Equip/Unequip")
    end
end)
task.spawn(function()
    while task.wait(1) do
        Clicks = 0
    end
end)

Did you tried disabling all tool scripts to see if the issue still persists without them?
If the issue still occurs without the scripts, then it could be due to layered clothing, try disable it in StarterPlayer properties.

Addionaly, I just noticed that there is a memory leak here, you are duplicating connection each time a tool is added.

local function setupToolListeners(character)
	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") and REMOVE_TOOL_NAMES[child.Name] then
			child.Equipped:Connect(function() onToolEquipped(child) end)
			child.Unequipped:Connect(function() onToolUnequipped(child) end)
		end
	end)

	for _, tool in ipairs(character:GetChildren()) do
		if tool:IsA("Tool") and REMOVE_TOOL_NAMES[tool.Name] then
			tool.Equipped:Connect(function() onToolEquipped(tool) end)
			tool.Unequipped:Connect(function() onToolUnequipped(tool) end)
		end
	end
end
1 Like

you were right, thank you :smiley:

yeah, fixed it. thanks :smiley:

1 Like

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