How to optimize a fire spread script?

So, I have a script that spreads fire to all the surrounding parts, what the script does is it creates an invisible ball, goes through all the touching parts of that ball and it replicates the script to the new parts, and then deletes it. The problem is that the average script activity is 17-20% or above that and it’s really laggy.

How can I optimize it?

Here is the script:

local fire = Instance.new("Fire", script.Parent)
fire.Parent = script.Parent
script.Parent.Material = Enum.Material.Neon
script.Parent.Color = Color3.new(1, 0.4, 0)
wait(math.random(5, 10))
local AlreadyBurntValue = Instance.new("BoolValue")
AlreadyBurntValue.Name = "AlreadyBurnt"
AlreadyBurntValue.Parent = script.Parent
script.Parent.Material = Enum.Material.Grass
script.Parent.Color = Color3.new(0.1, 0.1, 0.1)
script.Parent.Anchored = false
script.Parent:BreakJoints()
fire:Destroy()
local RangePart = Instance.new("Part")
RangePart.Shape = Enum.PartType.Ball
RangePart.Parent = workspace
RangePart.Transparency = 1
RangePart.Size = Vector3.new(10, 10, 10)
RangePart.Position = script.Parent.Position
for i, v in ipairs(RangePart:GetTouchingParts()) do
	if not v:FindFirstChild("FireSpreadScript") and not v:FindFirstChild("AlreadyBurnt") then
		local FireSpreadScript = script:Clone()
		FireSpreadScript.Parent = v
	end
end
RangePart:Destroy()
script:Destroy()

N̶o̶t̶ ̶g̶o̶n̶n̶a̶ ̶h̶a̶v̶e̶ ̶a̶ ̶h̶u̶g̶e̶ ̶i̶m̶p̶a̶c̶t̶ ̶o̶n̶ ̶o̶p̶t̶i̶m̶i̶s̶a̶t̶i̶o̶n̶,̶ ̶B̶U̶T̶:̶

Consider using GetPartsBoundInRadius instead of creating a RangePart. To use it, remove all the RangePart stuff, and replace RangePart:GetTouchingParts() with workspace:GetPartsBoundInRadius(script.Parent.Position, 5)

1 Like

Instead of using multiple scripts use one script and recursion. This will most likely fix the problem:

--Move the script in ServerScriptService so it can't be destroyed
local function destroyJoints(part: BasePart)
	for _, joint in pairs(part:GetJoints()) do joint:Destroy() end
end

local function fireState(part: BasePart, state: boolean)
	part:SetAttribute("Burning", state)
	part.Material = state and Enum.Material.Neon or Enum.Material.Grass
	part.Color = state and Color3.new(1, 0.4, 0) or Color3.new(0.1, 0.1, 0.1)
	if state then 
		Instance.new("Fire", part) 
	else
		local fire = part:FindFirstChildWhichIsA("Fire")
		if fire then fire:Destroy() end
		destroyJoints(part)
		part.Anchored = false
	end
end

local function burn(part: BasePart)
	fireState(part, true)
	task.wait(math.random(5, 10))
	fireState(part, false)
	local parts = workspace:GetPartBoundsInRadius(part.Position, 10)
	for _, v in pairs(parts) do
		--Direct comparison with nil to avoid reburning burned parts
		if v:GetAttribute("Burning") ~= nil then continue end
		task.spawn(burn, v) --new thread so it doesn't delay the loop
	end
end

burn(workspace.Baseplate) --initiate the chain reaction

Recursion is when a function calls itself inside its own code.

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