Big lag when adding lot's of parts proceduraly

The script is very simple:

local y = 0

for i=1,100000 do 
	local p = Instance.new("Part")
	p.Anchored = true
	p.Position = Vector3.new(0,y,0)
	p.Parent = workspace
	y = y + 2
end

print("Hello world!")

At the time the game is RUN I can see “Hello world”, so the loop has completed. But there is a Huge lag (2-6 seconds) before I can start to get normal frame-rates, move my mouse etc. I wonder why? Can I hook to some event when all processing is done and show some loading Bar until the game is playable?

The game I’m working on is all about procedural content generation so this a problem for me.

It is probably because you have no wait time inbetween, it just spams them into the game.

Firstly, you are running the loop extremely fast, that is 100,000 times. Place a yield.

Secondly, it can be optimized by removing your current integer variables in the loop by using for y = 0, 200000, 2 do instead so the y variable is not needed although you can do it however you want.

You could try @ScottFaber 's suggestion.

Or what you could do is make the part, but dont parent yet and instead, shove them into a table.
Take the table, then have a script parent them in all at once.
Though that honestly may still cause issues :man_shrugging:. It was just a wild guess.

Another method I could think of is to just turn off collisions on the parts, and make the visible property false at first.

Then when all have been created, make them visible again and add collisions if you want. This will help lessen strain on the server.

Though if its on the server, you could try doing it on the client instead? And if you want everybody to see it, FireAllClients?

1 Like

In the real Game I do not want the player to stand and watch part appearing between wait() time. Because it would ruin the game concept. I want to show some loading thing and when it’s ready player sees all constructed. Yes it does spam, the question is why its a problem.

What do you mean with yield? Example?

Secondly, it can be optimized by removing your current integer variables

You can Imagine this is just and simplified example of the real Game, where of course I’m doing some math for every part added, and that math is not just y++.

Because that is what can cause lag when adding in parts or doing something in a loop without having a wait.

You could aslo set the wait() to very low and that could even help.

Try something like

wait(0.01)

Maybe?

Try doing a RunServic.RenderStepped:Wait()

1 Like
  1. Read my answer to @ScottFaber
  2. parent them in all at once > how does that work? Can you give an example code?
  3. Then when all have been created, make them visible again and add collisions if you want. This will help lessen strain on the server > so its another loop?
  4. Yes it’s on the server and needs to be on the server. Becouse

Also this small Value has The effect, of parts appearing before player Eyes. I could count the parts and show-loading bar Until it’s all done. But this just seems inadequate to slow down the generation.

Hm. I could not see any other way of doing it without causing a mass amount of lag. Maybe running it on the client could help? Otherwise I can’t figure out anyother way.

RenderStepped event can only be used from local scripts. This no goer for me. The generation has to be dictated by server, so no cheating is possible.

Thank you for your efforts. I can’t use generation on client side (read answer above). I was just hoping, that maybe there is event or trick doing it without wait

And honestly it doesn’t feel like a “server strain”. Because of the FPS drop and “can’t move mouse” thing. It feels like a local strain.

local y = 0
local m = Instance.new("Model")

for i=1,100000 do 
	local p = Instance.new("Part")
	p.Anchored = true
	p.Position = Vector3.new(0,y,0)
	p.Parent = m
	y = y + 2
end

m.Parent = workspace

print("Hello world!")

This actually improved the situation by a lot! Not sure why, but I can try implement this strategy in my game. Adding parts to workspace directly, create some kind of overhead for CPU. I also start to think that this is a Studio thing, as it has to populate the tree in the explorer and that is costy.

You can use wait() without having to wait ~0.03 seconds between each iteration; have a counter variable that you increment by 1 every iteration, and then have a conditional wait() when that counter variable passes a certain value, let’s say 100. Just remember to reset the counter, I’ve made that mistake many times.

Edit: As an aside, we now have a += operator, so you can use y+=2 instead of y=y+2

Thank you, but the code above works just fine. Without waits

If it works fine, then what are you asking for help with here? What problem are you having.

This is completely expected. You’re generating 100,000 parts at once. What do you expect?

You’ve been given many sensible solutions here, however it boils down to the fact that what you are doing, in the form you want to do it, is not possible on this platform.

If it works fine, then what are you asking for help with here? What problem are you having.

  1. You are not fallowing the context. The code above is meant this Big lag when adding lot's of parts proceduraly - #15 by trshmanx , not my initial POST. I came up with it because @3rdhoan123 and others gave me good ideas. So I needed help and I got Help.
  2. Stitching the parts to a model, and then adding model to workspace actually helped a lot (on my machine the huge lag is gone). With some additional tweaks its hell yeah possible.

Next time you comment, try fallow the whole discussion and context.Otherwise its pointless bro.

Yielding is when you cause the script to sleep which stops it temporarily.

Examples of this is using :Wait() on events or the wait(num) function itself.