Trouble with Inf Loop

im working on a copy of a game, I have an ability that works as a 2 part counter, 1 hit for the initial stun, and a 2nd for damage, However, i have an another ability that clones yourself into an NPC that fights for you, it can be destroyed in 2 hits, since the counter counts as 2 hits, it will instantly destroy the clone, except after it is destroyed the script will keep infinitely Cframe your character up over and over.

i assumed it has something to do with the HumanoidRootPart in the clone no longer existing after being destroyed so its infinitely checking for it but cant find it. I’v attempted to fix it by checking if the humanoid you hit still exist, but I don’t think i did it right/Don’t know if its the best way to solve it. Would love some directions

  elseif hitchar.Effects:FindFirstChild("SwiftEscape") then
		if element == "Tai" then
			local FlipAnim = hitchar.Humanoid:LoadAnimation(script.SwiftEscape.Flip)
			local ShadowCon


			if hitchar.HumanoidRootPart:FindFirstChild("AirComboVel") then
				hitchar.HumanoidRootPart:FindFirstChild("AirComboVel"):Destroy()
			end

			InvisChar(hitchar, nil)

			local DestroyLater = {}

			local attacking = Instance.new("BoolValue", hitchar.Effects)
			attacking.Name = "Attacking"
			table.insert(DestroyLater,attacking)

			local SuperArmor = Instance.new("Folder", hitchar.Effects)
			SuperArmor.Name = "SuperArmor"
			table.insert(DestroyLater,SuperArmor)


			local attacking2 = Instance.new("BoolValue", hitchar.Effects)
			attacking2.Name = "iFrame"
			table.insert(DestroyLater,attacking2)

			local speed = Instance.new("IntValue", hitchar.Effects)
			speed.Name = "Speed"
			speed.Value = -99999
			table.insert(DestroyLater,speed)


			local jump = Instance.new("IntValue", hitchar.Effects)
			jump.Name = "Jump"
			jump.Value = -99999
			table.insert(DestroyLater,jump)


			module.damage(hitchar,character,{
				element = "Tai",
				typee = "Blunt",
				damage = .3,
				stun = .4,})

			local Animation = hitchar.Humanoid:LoadAnimation(script.SwiftEscape.GroundSlam) :: Animation
			Animation:Play()
			Animation:AdjustSpeed(1.8)

			local vel = Instance.new("BodyVelocity")
			vel.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
			vel.Velocity = character.HumanoidRootPart.CFrame.lookVector * -10 + Vector3.new(0, 25 ,0)
			table.insert(DestroyLater, vel)

			local s = script.SwiftEscape.Escape:Clone()
			s.Parent = hitchar.Head
			s.Playing = true
			game.Debris:AddItem(s, 2)

			local Flash = script.SwiftEscape.ParticleEmitter2:Clone()
			Flash.Parent = hitchar.HumanoidRootPart
			Flash:Emit(5)
			game.Debris:AddItem(Flash, 2)


			Animation:GetMarkerReachedSignal("Slam"):Connect(function()
				Uninvis()

				local SwiftEscapefx = script.SwiftEscape["Swift Esc"]:Clone()
					SwiftEscapefx.Parent = workspace.Effects
					SwiftEscapefx:PivotTo(character.HumanoidRootPart.CFrame * CFrame.new(0,-1.5,0) * CFrame.Angles(math.rad(-90),0,0))
					SwiftEscapefx.RoughShockwaveElectricity.handleeffect2.Enabled = true

				local smash = script.SwiftEscape.smash:Clone()
				smash.Parent = workspace
				smash.Position = character.HumanoidRootPart.Position
				smash.Attachment.ParticleEmitter:Emit(30) 
				smash.Attachment2.ParticleEmitter2:Emit(100)
				game.Debris:AddItem(smash, 3)

				hitchar.HumanoidRootPart.CFrame = character.HumanoidRootPart.CFrame * CFrame.new(0,5,0)

				module.damage(hitchar,character,{element = "Tai",
					typee = "Blunt",
					damage = 15,
					stun = 2,
					speed = -7,
					knockback = nil,
					knockbackduration = 0.15,
					blockable = true,
					blockbreak = false,
					behind = false,
					customanim = nil,
					subbable = true,})
				
				FlipAnim:Play()
				
				spawn(function()
					ShadowCon = game["Run Service"].Heartbeat:Connect(function()
						ShadowClone(hitchar)
					end)
				end)


				vel.Parent = hitchar.HumanoidRootPart 
				InvisChar(hitchar,nil)
			end)


				Animation:GetMarkerReachedSignal("End"):Connect(function()
				FlipAnim:Stop()
				Uninvis()
				ShadowCon:Disconnect()

				for i,v in pairs(DestroyLater) do
					v:Destroy()
				end
			end)

			return getReturnInfo()
		end
	end
end

Yes, you’re correct that the issue may be related to the HumanoidRootPart in the clone no longer existing after being destroyed. One way to fix this issue is to check if the humanoid still exists before executing the code that causes the infinite CFrame loop.

Here’s an example script that checks if the humanoid still exists before executing the code that causes the infinite loop:

-- Define variables
local player = game.Players.LocalPlayer
local cloneAbility = script.Parent -- Change this to the object that contains the clone ability script
local stunAbility = script.Parent -- Change this to the object that contains the stun ability script

-- Function to check if humanoid still exists
local function humanoidExists(humanoid)
    if humanoid and humanoid.Parent then
        return true
    else
        return false
    end
end

-- Connect to stun ability hit event
stunAbility.Hit:Connect(function(hit)
    if hit and hit.Parent then
        local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
        if humanoid and humanoidExists(humanoid) then
            -- Execute code for initial stun
        end
    end
end)

-- Connect to clone ability hit event
cloneAbility.Hit:Connect(function(hit)
    if hit and hit.Parent then
        local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
        if humanoid and humanoidExists(humanoid) then
            -- Execute code to clone NPC
            humanoid.Died:Connect(function()
                -- Code to execute when the humanoid dies
                if humanoidExists(humanoid) then
                    -- Execute code to remove the clone
                end
            end)
        end
    end
end)

In this script, we added a function called humanoidExists that checks if the humanoid still exists. We also added this check to the hit events for the stun ability and clone ability, as well as the Died event for the cloned NPC’s humanoid. This should prevent the script from executing the infinite CFrame loop if the humanoid no longer exists.

I don’t think this will work for 2 reasons

  1. Clones cant actually die, if they get hit twice by anything that can hit a clone, it just poofs away and gets destroyed from workspace, even if I had an ability that does 10 million damage, the clone would still be standing because it needs to be hit twice.

2 I don’t think it necessarily has to do with just the HumanoidRootPart, i think it also lies in “GetMarkerReachedSignal”

FlipAnim:Play()
				
				spawn(function()
					ShadowCon = game["Run Service"].Heartbeat:Connect(function()
						ShadowClone(hitchar)
					end)
				end)


				vel.Parent = hitchar.HumanoidRootPart 
				InvisChar(hitchar,nil)
			end)


				Animation:GetMarkerReachedSignal("End"):Connect(function()
				FlipAnim:Stop()
				Uninvis()
				ShadowCon:Disconnect()

				for i,v in pairs(DestroyLater) do
					v:Destroy()
				end
			end)

			return getReturnInfo()
		end
	end
end

Before writing this i had no idea what GetMarkerReachedSignal were, but after learning that they are events in animation that can be triggered, meaning that once the HumanoidRootPart is destroyed, I don’t think it can reach the Marker so it just never triggers the last section of the script, so i think i need a failsafe so that even when the HumanoidRootPart cant be found anymore, it will still reach the marker so the ability can finish

However I could still be wrong and if you think so id be very interested in why not

local function HumanoidExists(humanoid): boolean
    return (humanoid ~= nil and humanoid.Parent ~= nil)
end
local HumanoidExistsModule = {}
local meta = {__index = HumanoidExistsModule}
function HumanoidExistsModule.New(Humanoid:Humanoid)
return setmetatable({Humanoid = Humanoid}, meta)
end

function HumanoidExistsModule.exists()
--Retrieves the parent of the humanoid if it exists.
return self.Humanoid and self.Humanoid.Parent
end

function HumanoidExistsModule.existsAndAlive(): boolean
return self.exists() and self.Humanoid.Health > 0
end

return HumanoidExistsModule

To solve OP’s problem, it’s possible that the HumanoidRootPart is getting destroyed or the Humanoid is. We can use this class above to determine if the humanoid is still alive to prevent multiple CFrames from being done.