Fire script spreading uncontrollably

Hi, I made a script which spreads fire from part to part, but the problem is the script keeps cloning itself and i don’t know how to stop this.

Script:

script.Parent.Touched:Connect(function(hit)
	if hit.Name ~= "Fire" and hit.Anchored ~= true then
		if not hit:FindFirstChild(script.Name) then
			wait(math.random(1,5))
			hit.Name = "Fire"
			script:Clone().Parent = hit
		end
	end
end)

local mat = script.Parent.Material
script.Parent.Material = Enum.Material.Neon
script.Parent.Color = Color3.fromRGB(213, 115, 61)

wait(math.random(2,5))
script.Parent.Color = Color3.fromRGB(170, 85, 0)
script.Parent.Anchored = false
script.Parent:BreakJoints()

wait(math.random(2,5))
script.Parent.Color = Color3.new("")
script.Parent.Material = mat

if math.random(1,10) == 1 then
	local explosion = Instance.new("Explosion",workspace)
	explosion.Position = script.Parent.Position
	script.Parent.Velocity = Vector3.new(0,100,0)
end

wait(math.random(1,2))
script.Parent:Destroy()

Thank you!

1 Like

So you made a virus?

Instead, make one script to do all the work. I don’t think making a script to clone itself is ever a good idea.

it would error anyways after it cloned itself a few times

1 Like

How could i do this in one script?

Just put a script in ServerScriptService, and do the fire spreading there. Don’t just move the script you already have though, it won’t work.

choose a starting part, get nearby parts or parts that touch the fire, then include the same touch/nearby function on that part

local parts = {script.Parent}

script.Parent.Touched:Connect(function(hit)
	if hit.Name ~= "Fire" and hit.Anchored ~= true then
		table.insert(parts,hit)
	end
end)

while wait() do
	for _, v in pairs(parts) do
		v.Touched:Connect(function()
			local mat = v.Material
			v.Material = Enum.Material.Neon
			v.Color = Color3.fromRGB(213, 115, 61)

			wait(math.random(2,5))
			v.Color = Color3.fromRGB(170, 85, 0)
			v.Anchored = false
			v:BreakJoints()

			wait(math.random(2,5))
			v.Color = Color3.new("")
			v.Material = mat

			if math.random(1,10) == 1 then
				local explosion = Instance.new("Explosion",workspace)
				explosion.Position = v.Position
				v.Velocity = Vector3.new(0,100,0)
			end

			wait(math.random(1,2))
			v:Destroy()
		end)
	end
end

Is there anything wrong with this version?

Yes, you’re iterating all the parts, every millisecond. So your connecting touched events thousands of times per second, forever.

How c‌‌‌‌‌‌‌‌‌‌ould i fix‌‌‌‌‌‌‌‌ this?

Don’t use a while loop. Also use task.wait instead of wait.

What should i use instead of a while loop?

You don’t need a while loop to connect to events. So don’t replace it with anything.

if you loop that it will eventually crash since you are creating a bunch of touched events that stack up and when one fires all of them do, and then you crash

1 Like

I have a problem - the part i put the script inside eventually deletes itself meaning it can no longer spread, how could i make this a script in serverscriptservice instead? I don’t know how i’d write that.

I noticed that new parts that get added won’t be able to spread, so make a function for the touched event and make all new parts in the table use that function. Also make sure to check if the part is already in the fire parts table to not have duplicate parts in the table

1 Like
local startingPart = workspace:WaitForChild("YourPart") --path to part

-- use startingPart instead of script.Parent
1 Like

How could i implement this into my script?

1 Like

here is my edit of your script in order to make it work, I have explained all changes in the script and the script should be located in workspace or ServerScriptService.

local StartingPart = workspace.part --replace part with you parts name

local parts = {} --Removed StartingPart from the table because it gets added automatically

function TurnPartIntoFire(v: BasePart) --"v" is simply the name of the item passed in the function ": BasePart" is just saying that the item passed is supposed to be a BasePart
	FirePartTouched(v) --Apply the spread function
	local mat = v.Material
	v.Material = Enum.Material.Neon
	v.Color = Color3.fromRGB(213, 115, 61)

	wait(math.random(2,5))
	v.Color = Color3.fromRGB(170, 85, 0)
	v.Anchored = false --This is not really needed since the spread function checks if the part is unanchored or not
	v:BreakJoints()

	wait(math.random(2,5))
	v.Color = Color3.new()
	v.Material = mat

	if math.random(1,10) == 1 then
		local explosion = Instance.new("Explosion",workspace)
		explosion.Position = v.Position
		v.Velocity = Vector3.new(0,100,0) --v.Velocity will be underlined with red because it's depricated (not in use)
	end

	wait(math.random(1,2))
	table.remove(parts,table.find(parts,v)) --Removing the part from the parts table. This line can be moved to after the part is changed to the color black if you don't want it to spread past that point
	v:Destroy()
	--Also removed the .Touched() I don't know why it was there
end

function FirePartTouched(Part: BasePart)
	Part.Touched:Connect(function(hit)
		if not table.find(parts,Part) then return end --Stop the code if the part is not in the burning parts table
		if not table.find(parts,hit) and hit.Anchored ~= true then --I replaced the name check with table check so the part can keep it's original name
			table.insert(parts,hit) --Adding the part to the table so the touch function can only be applied once
			TurnPartIntoFire(hit) --Turning the part into fire and deleting it later
		end
	end)
end

FirePartTouched(StartingPart) --Applying these to the starting part because it won't run otherwise, you can also choose to wait with adding this
TurnPartIntoFire(StartingPart)
1 Like

It’s not setting fire to anything :frowning: does it work for you?

It only sets fire to unanchored parts since you added a and hit.Anchored ~= true which means “Anchored does not = true” basically the same thing as and hit.Anchored == false. meaning it only sets fire to unanchored parts

Oh nvm it doesn’t work, just add StartingPart to the parts table and it should work