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()
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)
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.