Code is Laggy, How Would I Optimize It?

I just tested my game and it is really laggy to a lot of people. The snippet of code that causes the lag is posted below. Hopefully someone can recognize what makes it so laggy.

        local crumbleCount = math.floor(#game.Workspace.Map.Destroyable:GetChildren() * 0.2)
		for crumble = 0, crumbleCount, 1 do
			local chosenBlock = game.Workspace.Map.Destroyable:GetChildren()[math.random(1, #game.Workspace.Map.Destroyable:GetChildren())]
			chosenBlock.Color = Color3.fromRGB(255,0,0)
			chosenBlock.Parent = game.Workspace.Map.Destroyed
			delay(0.5, function()
				chosenBlock.CanCollide = false
				chosenBlock:Destroy()
			end)
		end

The maps in the game have thousands of parts so I guess this is why it would be so laggy. The first iteration would be removing around 1000 parts. I’m wondering if there is a way to make the game run smoothly without having to get rid of parts in the map.

First off, why are you changing a object’s collision just to destroy it? That seems kind of counter productive.

chosenBlock.CanCollide = false
chosenBlock:Destroy()

Secondly, 1000 un-anchored parts is going to cause lag. All of those collisions will be the problem. It is easy to get lag with 500 un-anchored parts, much less 1000. This may be your problem: Too many unanchored parts. Try lowering the count if they are un-anchored.

Finally, the third thing. You are opening almost 1000 separate threads with the delay function. Try using debris service instead instead:

Debris does not yield the current thread, does not require a new thread and will not error if the object is already destroyed. For this reason it is the recommended method for cleaning up objects with a fixed lifetime.

See Roblox’s article on Debris service

local chosenBlock = game.Workspace.Map.Destroyable:GetChildren()[math.random(1, #game.Workspace.Map.Destroyable:GetChildren())]
chosenBlock.Color = Color3.fromRGB(255,0,0)
chosenBlock.Parent = game.Workspace.Map.Destroyed
game:GetService([[Debris]]):AddItem(chosenBlock, 0.5)

I used [[]] instead of quotes because I am composing this on a mobile device. Apologies.

3 Likes

I think I forgot to get rid of the cancollide when I changed the way I removed the parts. These are not unanchored parts, they just turn red, then they get destroyed. I forgot that AddItem was a thing :stuck_out_tongue: I’ll try that.

AddItem is much more efficient that using delay to destroy parts because

  • Both yeild (great for loops)
  • Doesn’t create a seperate thread each time (prevents lags from that many threads)
  • Both are accurate to the nearest 30 miliseconds
  • Checks to see if the part still exists before destroying it

In this case, the code would error as it tries to destroy an item that has already been destroyed

@Kampfkarren The wiki article on debris service states destroying a already destroyed object will cause a error. If this is not the case, It should be updated. (Destroying a already destroyed object errors)

AddItem Is the BEST way to destroy parts after a certain time period.

2 Likes

For clarification to the OP:

Delay doesn’t yield either.

So is delay.

Calling :Destroy() on an object that’s already destroyed doesn’t break anything, so I don’t see why this matters.

1 Like