Weapon randomly one shots

so, ive been coding a sword (not a tool, its a model attached to the player with a moto 6d, and with animations). for some reason, it randomly one shots players. ive tried many fixes such as adding task.wait() and added a thing that makes player invincible for a little bit to prevent damage, added a table of hit players that resets every swing, and checks if a players been damaged before. nothing works. does anyone have any idea on how to make it not one shot

physicalBox.Touched:Connect(function(hit)
			if hit.Parent and hit.Parent:IsA("Model") and hit.Parent:FindFirstChild("Humanoid") then
				if hit.Parent == character or character:WaitForChild("IsRagdoll").Value == true or table.find(affected, hit.Parent.Name) then return end
				task.wait()
				if debounce == true then
				task.wait()
					debounce = false -- this should prevent from damage running again
					table.insert(affected, hit.Parent.Name)	
					if game.Players:WaitForChild(hit.Parent.Name).Bool.Invincible.Value == true then return end
					hit.Parent:WaitForChild("Humanoid"):TakeDamage(12)
					game:GetService("Players"):WaitForChild(character.Name).leaderstats.Hits.Value += 1
					swordRagdoll(hit.Parent, character)						
				end	
			else return end
end)
4 Likes

where are you actually changing the value of “debounce”? maybe the issue relies there.

3 Likes

it changes to false when hit, and changes back to true whnen swing stops

2 Likes

should be checking if its false and then later on it to false when the swing ends

2 Likes

Ello!

Does this work?

local debounce = false
local affected = {} -- Track players already hit during a single swing

physicalBox.Touched:Connect(function(hit)
    -- Validate if the hit object is a valid player character
    if hit.Parent and hit.Parent:IsA("Model") and hit.Parent:FindFirstChild("Humanoid") then
        -- Check if the hit target is the attacker or already affected
        if hit.Parent == character or character:WaitForChild("IsRagdoll").Value == true then
            return
        end

        if table.find(affected, hit.Parent.Name) then
            return
        end

        -- Check if debounce is active
        if debounce then
            return
        end

        debounce = true -- Set debounce to true to prevent repeated execution
        table.insert(affected, hit.Parent.Name) -- Add to the affected list

        -- Ensure the target is not invincible
        local player = game.Players:FindFirstChild(hit.Parent.Name)
        if player and player:FindFirstChild("Bool") and player.Bool.Invincible.Value then
            debounce = false -- Reset debounce before returning
            return
        end

        -- Apply damage
        local humanoid = hit.Parent:FindFirstChild("Humanoid")
        if humanoid then
            humanoid:TakeDamage(12)
        end

        -- Update stats and apply ragdoll effect
        local attacker = game.Players:FindFirstChild(character.Name)
        if attacker and attacker:FindFirstChild("leaderstats") then
            attacker.leaderstats.Hits.Value += 1
        end
        swordRagdoll(hit.Parent, character)

        -- Small delay to reset debounce
        task.wait(0.2)
        debounce = false
    end
end)

wouldn’t that be quite close to my original code. either way i’ll try it tomorrow and get back to you :D.

You can just do it:

local Players = game:GetService('Players')

local lastTick = tick()
local cooldown = .5

physicalBox.Touched:Connect(function(hit)
       local plr = Players:GetPlayerFromCharacter(hit.Parent)
       if not plr then return end
       
       local nowTick = tick()
       if nowTick - lastTick < cooldown then return end
       lastTick = nowTick
       --- code
end)

I copied this code exactly and it still occassionally oneshots its weird

Not sure about this one with a cooldown as the cooldown is located under something else. Tested it either way and didnt work.

You should begin by adding print()s to your script and figuring out what exactly it does when it hits multiple times, what are the values of the guard variables and such. My guess is, since debounce doesn’t help, you might have multiple instances of the sword or of the script each applying damage. Or maybe the Touched is called in parallel on multiple threads, although it shouldn’t.