Character Boost System cooldown issues

Hello developers, recently i was making an boost system, for example when you step on a part and it gives you temporary speed boost (we will review it), and there im facing with this kind of problem. You should be able to activate more than one boost at the time.

When i’ve tried to test it, i saw that it works a bit strange:
I’ve activated first one, it worked, then second one, its working too, but for some reason they are having kind of same cooldown, however i dont see a reason for it to be like that. And more strange part about it - you cant activate the 1st one you’ve stepped until the 2nd boost ends. In reverse, when you try to activate 2nd speed booster after 1st boost ended, it becomes broken. Debounces seem to work fine, so i am assuming there is something wrong with RemoteFunction i applied as a method.

Video: 2023-11-30 11-11-47.mp4 - Google Drive

Server Script (Responds for Speed Boosters):

--[SERVICES]--

local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local Debris = game:GetService("Debris")

local RS = game:GetService("ReplicatedStorage")


--[VARIABLES]--

local VFX = script.VFX
local sound = script.Sound

local tagName = "SpeedBoosters"

local PopUpRemote = RS.Functions.ShowBoost

local debounces = {}


--[FUNCTIONS]--

local function setUniqueNames()
	local tab = {}
	local objectQuantity = #CollectionService:GetTagged(tagName)

	local function generateIndentifier()
		local id = tostring(math.random(1000, 9999))

		if not table.find(tab, id) then
			return id
		end
	end

	for i = objectQuantity, 0, -1 do
		local id
		repeat id = generateIndentifier() until id ~= nil
		table.insert(tab, id)
	end

	for i, object in pairs(CollectionService:GetTagged(tagName)) do
		object:SetAttribute("Id", tab[i])
	end
end

setUniqueNames()

for i, object in pairs(CollectionService:GetTagged(tagName)) do 
	local mainPart = object.BoostPart

	local speedBoost = object.SpeedBoost 
	local activeTime = object.ActiveTime 
	local cooldown = object.Cooldown

	local fullName = object.Name.."_"..object:GetAttribute("Id")

	local function touch(hit)
		if hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
			local char = hit.Parent
			local humanoid = char:FindFirstChild("Humanoid") 
			local player = Players:GetPlayerFromCharacter(char)

			local statChangersFolder = player:FindFirstChild("StatChangers")

			local function boost() 
				
				--if statChangersFolder:FindFirstChild("Speed_SpeedBooster") then return end] 

				local CloneVFX = VFX:Clone()
				CloneVFX.Parent = char.Torso or char.UpperTorso
				Debris:AddItem(CloneVFX, CloneVFX.Lifetime.Max)
				CloneVFX:Emit(20)

				local CloneSound = sound:Clone()
				CloneSound.Parent = char.Torso or char.UpperTorso
				Debris:AddItem(CloneSound, CloneSound.TimeLength)
				CloneSound:Play()

				local _SpeedMark = Instance.new("IntValue")
				_SpeedMark.Name = "Add_Speed_SpeedBooster"
				_SpeedMark.Value = speedBoost.Value
				_SpeedMark.Parent = statChangersFolder
				Debris:AddItem(_SpeedMark, activeTime.Value)

				local success, errormsg = pcall(function()
					local PopUp = PopUpRemote:InvokeClient(player, "StageBoosterObject", {["Object"] = object, ["ActiveTime"] = activeTime})
				end)

				if errormsg then
					warn(errormsg)
					debounces[player] = nil
				end

				--PopUpRemote:FireClient(player, "StageBoosterObject", {["Object"] = object, ["ActiveTime"] = activeTime})

				--task.wait(cooldown.Value - activeTime.Value)
				
				table.remove(debounces[player], debounces[player][fullName])

				--[[if type(debounces[player]) == "table" then
					if #debounces[player] > 0 then print(debounces, debounces[player], fullName)
						table.remove(debounces[player], debounces[player][fullName])
					else
						debounces[player] = {}
					end
				end]]
			end

			if humanoid.Health > 0 then 
				if type(debounces[player]) ~= "table" then 
					debounces[player] = {fullName}
					boost() print(debounces, 3)
					
				else
					if not table.find(debounces[player], fullName) then 
						table.insert(debounces[player], fullName) 
						boost()
					end
				end 
			end
		end
	end

	mainPart.Touched:Connect(touch) 
end

Local Script (UI Work):

--[SERVICES]--

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

local TS = game:GetService("TweenService")
local RS = game:GetService("ReplicatedStorage")


--[VARIABLES]--

local player = Players.LocalPlayer

local remote = RS.Functions.ShowBoost

local GUI = script.Parent
local stageBoosterObjectsFolder = GUI.StageBoosterObjects
local SBOPopUpTemplate = stageBoosterObjectsFolder.PopUpTemplate
local activeBoostsFolder = stageBoosterObjectsFolder.ActiveBoosts

local t_classes = {"StageBoosterObject"}

local usefulModule = require(RS.Modules.UsefulThingies)

local t_stageBoosterObjectInfo = {
	["SpeedBooster"] = {
		["Image"] = "rbxassetid://15268727256",
		["Color"] = Color3.new(242, 206, 0)
	}
}

local popUpTF = TweenInfo.new(1, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local hidePopUpTF = TweenInfo.new(1, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out)

local function updateBoosts()
	for i, frame in pairs(activeBoostsFolder:GetChildren()) do
		if frame:IsA("Frame") and frame:FindFirstChild("Status") then
			local status = frame.Status
			local nowActive = 0

			for ii, boost in pairs(activeBoostsFolder:GetChildren()) do
				if boost.Status.Value == "Active" or boost.Status.Value == "Activating" then
					nowActive += 1
				end
			end
			
			

			if status.Value == "Activating" then
				--if nowActive <= 1 and frame.Position ~= UDim2.fromScale(frame.Position.X.Scale, 0.835) then
					local tween = TS:Create(frame, hidePopUpTF, {Position = UDim2.fromScale(frame.Position.X.Scale, 0.835)})
					tween:Play()
					
					tween.Completed:Connect(function()
						status.Value = "Active"
					end)
				--end
			else
				if status.Value == "Active" then 
					local tween = TS:Create(frame, hidePopUpTF, {Position = UDim2.fromScale(frame.Position.X.Scale, 0.835 - (0.135*(nowActive-1)))})
					tween:Play()
				else
					if status.Value == "Ending" then
						local tween = TS:Create(frame, hidePopUpTF, {Position = UDim2.fromScale(frame.Position.X.Scale, 1.05)})
						tween:Play()
					end
				end
			end
		end
	end
end

local function showBoost(class, params)
	if table.find(t_classes, class) then
		if class == "StageBoosterObject" then
			local object = params["Object"]
			local activeTime = object.ActiveTime
			local cooldown = object.Cooldown

			local cooldownCounter = object.BillboardGui.CooldownCounter

			local templateClone = SBOPopUpTemplate:Clone()

			local status = templateClone.Status
			local barBG = templateClone.BarBackground
			local boosterImage = templateClone.BoosterImage
			local activeCounter = barBG.Counter
			local fill = barBG.Fill

			templateClone.Parent = activeBoostsFolder
			templateClone.Name = object.Name.."_"..object:GetAttribute("Id")
			templateClone.Visible = true

			local bindDeadline = tick() + activeTime.Value

			local remaining = activeTime.Value - tick()
			local s = math.floor(remaining%60)
			local ms = math.floor((remaining%1)*100)

			activeCounter.Text = string.format("%02i.%02i", s, ms)

			boosterImage.Image = t_stageBoosterObjectInfo[object.Name]["Image"]
			fill.BackgroundColor3 = t_stageBoosterObjectInfo[object.Name]["Color"]

			cooldownCounter.Visible = true
			cooldownCounter.Text = cooldown.Value

			status.Value = "Activating"
			spawn(updateBoosts)

			RunService:BindToRenderStep(player.Name.."_"..templateClone.Name, 0, function()
				local remaining = bindDeadline - tick()

				--local m = math.floor(remaining/60)
				local s = math.floor(remaining%60)
				local ms = math.floor((remaining%1)*100)

				if remaining > 0 then
					activeCounter.Text = string.format("%02i.%02i", s, ms)
					fill.Size = UDim2.fromScale(math.max(0, remaining / activeTime.Value), 1)
				end

				--[[
				fill:TweenSize(UDim2.fromScale(math.max(0, remaining / activeTime.Value), 1))
				print(remaining, bindDeadline)
				--]]

				if remaining <= 0 then
					activeCounter.Text = 0
					status.Value = "Ending"
					updateBoosts()
					RunService:UnbindFromRenderStep(player.Name.."_"..templateClone.Name)
				end
			end)
			
			for i = cooldown.Value, 0, -1 do
				--if i <= -1 then break end
				cooldownCounter.Text = i
				task.wait(1)
			end

			templateClone.Parent = nil
			
			if cooldownCounter.Text == "0" then
				cooldownCounter.Visible = false
				cooldownCounter.Text = 0
			end
			return
		end
	else
		warn("Class named wrong or doesn't exist: " .. class)
	end
end

remote.OnClientEvent:Connect(showBoost)]]
	
remote.OnClientInvoke = showBoost

The script is looong and i know not many people could help but im grateful for any info!