Function randomly decides to stop working midway

I’m attempting to create a simple “burn” function that takes the player, hit part of the body, and the enemy. Given these arguments, it applies damage to the target a total of 3 times and then destroys the particle effects. Despite being simple enough, it has proven to be anything but.

The function will randomly decide it’s had enough and just end itself midway through any part of it, even just at the beginning. This causes the particle effects to not be removed as the function was incomplete. I’ve tried using coroutines but that doesn’t seem to work either.

This is the troublesome code:

local function Burn(plr, hit, enemy)
	local chr = plr.Character or plr.CharacterAdded:Wait()
	local tool = chr:FindFirstChildOfClass("Tool")
	if not enemy or not hit or not tool then return end

	local tor = hit.Parent:FindFirstChild("UpperTorso")
	if not hit.Parent or not tor then return end

	if game.Players:GetPlayerFromCharacter(enemy.Parent) then return end

	if tor:FindFirstChild("FEffect") then return end

	local fireEffect = game.ReplicatedStorage.GameItems.Effects.Fire.FEffect:Clone()
	fireEffect.Parent = tor
	local fireLight = game.ReplicatedStorage.GameItems.Effects.Fire.FireLight:Clone()
	fireLight.Parent = tor
	local aBurn = game.ReplicatedStorage.GameItems.Effects.Fire.ABurn:Clone()
	aBurn.Parent = tor

	local dmg = require(tool.WeaponConfig).BurnDamage

	local function applyBurn()
		for i = 1, 3 do
			if not enemy or enemy.Health <= 0 then break end

			aBurn.Playing = false
			aBurn.Playing = true
			enemy:TakeDamage(dmg)

			local ObjModel = CreateObject(hit, dmg, false)
			DestroyTag(ObjModel)
			ObjModel:Destroy()
		end
		fireEffect:Destroy()
		fireLight:Destroy()
		aBurn:Destroy()
	end
	coroutine.wrap(applyBurn)()
end

Around 50% of the time the code works as intended. Other times it will usually break after the first burn apply, not doing any more of them and leaving the target with the burn particles still on them. The CreateObject function creates damage numbers that disappear after a second. It contains a few wait()s, creating gaps of time between each burn. What could possibly be wrong with this code?

1 Like

Hello! I would recommend using some print statements to get the states of variables to see what is triggering your return conditions.

2 Likes

Hi! I’ve tried doing this too. Putting in print statements everywhere to see where it ends. However, these just show that it ends at random times just as it has been. For example, if I have one in the for loop printing i, it just stops printing as randomly as the function stops working. Sometimes it prints every i as it should. Sometimes it only prints the first one, or a few but not all.

I don’t get why it doesn’t destroy the particles. I have written here where if it breaks out of the loop, to destroy the particles whether or not it has successfully applied each burn damage.

1 Like

Understood, basically the corountine is not going to tell you what is triggering the return functions because it is on a separate thread from the rest of the functionality and you would have to keep the print statement within the return functions thread (outside of the coroutine) to figure out why the whole thing is being haulted. I recommend printing each of the things the return statements are considering before the return statement happens so you can read the set of information that caused that return statement to happen.

the only code that could possibly cause a break is if it doesn’t have a reference to the enemy or it thinks that their health is less than or equal to 0, you should put a print in your break statement and print what case it may be accepting to cancel the damage function. that is of course, if theres no error that appears in the console when it stops.

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

local function Burn(Player, Hit, EnemyHumanoid)
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local Tool = Character:FindFirstChildOfClass("Tool")
	
	if not EnemyHumanoid or not Hit or not Tool then
        print("No Humanoid Or No Hit Or No Tool Found")
		return
	end
	
	local EnemyCharacter = Hit.Parent
	local UpperTorso
	
	if EnemyCharacter then
		UpperTorso = EnemyCharacter:FindFirstChild("UpperTorso")
		if not UpperTorso then
			print("No UpperTorso Found")
			return
		end
	end

	if Players:GetPlayerFromCharacter(EnemyCharacter) then
		print("Enemy Is A Player")
		return 
	end

	if UpperTorso:FindFirstChild("FEffect") then 
		print("Upper Torso Already Have FEffect")
		return 
	end
	
	local Damage = require(Tool:WaitForChild("WeaponConfig")).BurnDamage
	print("Extracted Damage Information")
	
	print("Creating Effects")
	local FireEffect = ReplicatedStorage.GameItems.Effects.Fire.FEffect:Clone()
	FireEffect.Parent = UpperTorso
	
	local FireLight = ReplicatedStorage.GameItems.Effects.Fire.FireLight:Clone()
	FireLight.Parent = UpperTorso
	
	local aBurn = ReplicatedStorage.GameItems.Effects.Fire.ABurn:Clone()
	aBurn.Parent = UpperTorso
	print("All Effects Created")

	local function ApplyBurn()
		print("Apply Burn Called")
		for i = 1, 3 do
			print("# "..i.." Loop Begin")
			
			if not EnemyHumanoid or EnemyHumanoid.Health <= 0 then
				print("No Humanoid Or Health Reach 0, Loop Break")
				break 
			end

			aBurn.Playing = false
			aBurn.Playing = true
			
			EnemyHumanoid:TakeDamage(Damage)
			
			print("Creating Damage Count Object")
			local ObjectModel = CreateObject(Hit, Damage, false)
			print("Damage Count Object Created")
			
			DestroyTag(ObjectModel)
			print("All Tags Removed From Object")
			
			ObjectModel:Destroy()
			print("Damage Count Object Destroyed")
		end
		
		print("Destroying Effects")
		FireEffect:Destroy()
		FireLight:Destroy()
		aBurn:Destroy()
		print("All Effects Destroyed")
	end
	
	task.spawn(ApplyBurn)
end

Maybe try to debug with this, I think the issue is most likely caused by the CreateObject/DestroyTag/No Humanoid or Health <= 0

1 Like

You’re right. The issue is being caused by CreateObject, as most of the time when it fails to complete the function, it reaches “# 3 Loop Begin”, “Creating Damage Count Object” and doesn’t reach “Damage Count Object Created”. This is what’s in that function:

local function CreateObject(hit,dmg, isCrit)
	local TweenService = game:GetService("TweenService")
	local ObjModel = Instance.new("Model", workspace.DebrisHolder)
	Debris:AddItem(ObjModel, 2)
	local Obj = Instance.new("Part", ObjModel)
	-- Appearance
	Obj.Material = Enum.Material.SmoothPlastic
	Obj.Transparency = 0.8
	-- Data
	Obj.Position = hit.Parent:FindFirstChild("Head").Position + Vector3.new(math.random(-1.6,1.6),2,math.random(-1.6,1.6))
	-- Behavior
	Obj.Anchored = true
	Obj.CanCollide = false
	Obj.Locked = true
	-- Part
	Obj.Shape = Enum.PartType.Ball
	Obj.Size = Vector3.new(1.5,1.5,1.5)
	-- Billboard Gui
	local Gui = script.BillboardGui:Clone()
	Gui.Adornee = ObjModel:FindFirstChild("Part")
	Gui.TextLabel.Text = "-"..Abb.Abb2(dmg)
	
	if isCrit then
		Obj.Color = Color3.fromRGB(225, 194, 17)
		Gui.TextLabel.TextColor3 = Color3.new(1, 0.839216, 0.0313725)
		Gui.TextLabel.TextSize = 70
		Gui.TextLabel.Text = Gui.TextLabel.Text .. "!!"
		local sound = game.ReplicatedStorage.Music.Critical:Clone()
		sound.Parent = Obj
		sound.Playing = true
		
	else
		isCrit = false
		Obj.Color = Color3.fromRGB(191, 50, 50)
		Gui.TextLabel.TextColor3 = Color3.new(1, 0.25098, 0.25098)
		Gui.TextLabel.TextSize = 40
	end
	
	Gui.Parent = ObjModel
	
	print("Waiting...")
	
	local ObjPos = Instance.new("BodyPosition", Obj)
	ObjPos.Position = Vector3.new(0,7.85,0)
	local OT1 = TweenService:Create(Obj, TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {Transparency = 0
	})OT1:Play()
	local GT1 = TweenService:Create(Gui.TextLabel, TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {TextTransparency = 0
	})GT1:Play()
	GT1.Completed:Wait()
	local OT2 = TweenService:Create(Obj, TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {Transparency = 1
	})OT2:Play()
	local GT2 = TweenService:Create(Gui.TextLabel, TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {TextTransparency = 1
	})GT2:Play()
	GT2.Completed:Wait()

	print("Done!")
	return ObjModel
end

The issue arises when “Done!” isn’t printed, so something sometimes goes wrong between these print statements, but I’m not sure what. What is actually done in that segment isn’t really that important, so I’m just going to remove it, and I think that should fix the problem

Edit: Removed that stuff, and I’ve yet to encounter any problems anymore. Thanks for the help.

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