How can I add a cooldown to this?

Hello! I’ve birthed this absolutely terrible mother of spaghetti code of a module, used for ragdolling rigs. When a player ragdolls and unragdolls quickly, they regain control but their torso moves and their limbs flop around in a sort of limbo state between walking and ragdolling.

I’ve tried some things to no avail, so how can I add a cooldown/debounce to my code?

local module = {}
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")

local PhysicsService = game:GetService("PhysicsService")

local ragParts = script.RagdollParts:GetChildren()
local ImpactSFX = script.ImpactSFX

local sounds = script.Sounds:GetChildren()
local slip = script.Slip

local defaultMinZoomDistance = game.StarterPlayer.CameraMinZoomDistance

local function playSound(part, s, vol)
	local sound = s:Clone()
	
	sound.Parent = part
	sound.Volume = vol or 0.5
	sound:Play()

	task.wait(0.1)
	Debris:AddItem(sound, sound.TimeLength + 0.1)
end

local function playRandomSound(char)
	local sound = sounds[math.random(1, #sounds)]
	local head = char and char:FindFirstChild("Head")
	
	if not head or not sound then return end

	playSound(head, slip)
	playSound(head, sound, 0.2)
end

local function createCollider(limb : BasePart)
	if limb.Name == "HumanoidRootPart" then return end
	
	local collider = Instance.new("Part")
	collider.CFrame = limb.CFrame
	collider.Massless = true
	collider.Size = limb.Size * 0.5
	collider.Transparency = 1
	
	local weld = Instance.new("WeldConstraint")
	weld.Part0 = collider
	weld.Part1 = limb
	weld.Parent = collider
	
	collider:AddTag("Collider")
	collider.Name = limb.Name .. " Collider"
	collider.Parent = limb.Parent
	
	return collider
end

function module:Setup(char : Model, isPlayer)
	if not char.Humanoid then return end

	local humanoid = char:FindFirstChild("Humanoid")
	assert(humanoid, "Can only set-up ragdoll on R6 humanoid rigs")
	assert(humanoid.RigType == Enum.HumanoidRigType.R6, "Can only set-up ragdoll on R6 humanoid rigs")
	assert(humanoid.RootPart ~= nil, "No RootPart was found in the provided rig")
	assert(char:FindFirstChild("HumanoidRootPart"), "No HumanoidRootPart was found in the provided rig")

	if not isPlayer then
		for _, v: BasePart in ipairs(char:GetDescendants()) do
			if v:IsA("BasePart") then
				v:SetNetworkOwner(nil)
			end
		end
	end

	-- Setup ragdoll
	char.Head.Size = Vector3.new(1, 1, 1)
	humanoid.BreakJointsOnDeath = false
	humanoid.RequiresNeck = true

	local clones = {}
	for _, v in ipairs(ragParts) do
		clones[v.Name] = v:Clone()
	end

	local folder1 = Instance.new("Folder")
	folder1.Name = "RagdollConstraints"
	for _, v in pairs(clones) do
		if v:IsA("Attachment") then
			v.Parent = char[v:GetAttribute("Parent")]
		elseif v:IsA("BallSocketConstraint") then
			v.Attachment0 = clones[v:GetAttribute("0")]
			v.Attachment1 = clones[v:GetAttribute("1")]
			v.Parent = folder1
		end
	end
	folder1.Parent = char

	local folder2 = Instance.new("Folder")
	folder2.Name = "Motors"
	local value
	for _, v in ipairs(char.Torso:GetChildren()) do
		if v:IsA("Motor6D") then
			value = Instance.new("ObjectValue")
			value.Value = v
			value.Parent = folder2
		end
	end
	folder2.Parent = folder1

	-- Ragdoll trigger
	local trigger = Instance.new("BoolValue")
	trigger.Name = "RagdollTrigger"
	trigger.Parent = char

	trigger.Changed:Connect(function(bool)
		if bool then
			module:Ragdoll(char)
		else
			module:Unragdoll(char)
		end
	end)
	
	humanoid.Died:Once(function()
		trigger.Value = true
	end)
end

function module:Ragdoll(char: Model)
	if not char.Humanoid then return end
	
	char.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
	char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, false)
	char.Humanoid.AutoRotate = false
	
	local player = Players:GetPlayerFromCharacter(char)
	if player then
		player.CameraMinZoomDistance = player.CameraMaxZoomDistance
		playRandomSound(char)
	end
	
	char:AddTag("CanGrab")
	
	for _, v in ipairs(char.RagdollConstraints.Motors:GetChildren()) do
		v.Value.Enabled = false
	end

	for _, v in ipairs(char:GetChildren()) do
		if v:IsA("BasePart") then
			v.CollisionGroup = "Ragdoll"
			
			--createCollider(v)
		end
	end
	
	local hrp = char:FindFirstChild("HumanoidRootPart")
	local rootJoint = hrp:FindFirstChildOfClass("Motor6D")
	if rootJoint then
		task.spawn(function()
			rootJoint.Enabled = false
			task.wait()
			rootJoint.Enabled = true
		end)
	end
	
	local newSFX = ImpactSFX:Clone()
	newSFX.Parent = char
	newSFX.Enabled = true

	hrp:ApplyAngularImpulse(Vector3.new(-120, 0, 0))
end

function module:Unragdoll(char: Model)
	if not char.Humanoid then return end
	
	char.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
	char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, true)
	
	local player = Players:GetPlayerFromCharacter(char)
	if player then
		player.CameraMinZoomDistance = defaultMinZoomDistance
	end
	
	char:RemoveTag("CanGrab")
	
	for _, v in ipairs(char.RagdollConstraints.Motors:GetChildren()) do
		v.Value.Enabled = true
	end

	for _, v in ipairs(char:GetChildren()) do
		if v:IsA("BasePart") then
			v.CollisionGroup = player and "Players" or "Default"
			
			--[[if v:HasTag("Collider") then
				v:Destroy()
			end]]--
		end
	end
	
	local foundSFX = char:FindFirstChild("ImpactSFX")
	if foundSFX then
		foundSFX:Destroy()
	end
	
	char.Humanoid.AutoRotate = true
end

return module

Do you think this would work with your code?

char:SetAttribute("RDeb", true)
task.Spawn(function()
  task.wait(0.5)
  char:SetAttribute("RDeb", nil)
end)

and then adding an if statement in the unragdoll function at the start to check if the attribute is there

if not char:GetAttribute("RDeb") then

i tried a cooldown table earlier which is basically the same thing, but ill try this too