Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

What are the factors that cause lag?

So my game is Filtering Enabled, I'm not sure if the wait functions on the client side will affect the latency of the game at all. The wait functions does not connected to the server but only used in the local scripts. So:

  • What makes "lag"?
  • How should i use my loops functions?
  • Is there a way to prevent/reduce lags?

2 answers

Aside from the normal causes (ping, etc.), lag in ROBLOX is usually caused by things on the server.

Things running on the client run on the client's computer. This would not cause latency, because it is not sending or receiving anything. The only form of 'lag' this could produce is a low frame rate.

Think of it this way - the more the server needs to send, the more latency. Just try to keep the line between client and server sharp - only blur the line when it is needed.

If something can be run on the client (GUIs, tools, music), run it on the client.

Also make sure not to spam RemoteEvents/Functions (the :FireServer/Client() methods, not the objects).


Hope I helped!

~TDP

Wait and YieldFunctions do not produce lag

The wait command and anything that is considered a YieldFunction (ex. when using RemoteFunctions or DataStores) do not produce lag. They effectively pause the execution of the script until something has happened.

In Roblox, all scripts (and possibly even the physics engine) take turns executing. When a script says wait(5), it tells Roblox "I'm done executing for now. Wake me up in 5 seconds!"; Roblox then starts running the next script, until all scripts are done executing. Then it advances the game time (workspace.DistributedGameTime) and runs the physics.

What causes lag

"Lag" occurs when the server is trying to process more than it can handle and so cannot keep up with sending and receiving network updates to/from clients. This might occur if you have lots of bricks all colliding with each other, for instance (making Roblox do lots of physics calculations), or if you have lots of scripts doing complex or intensive work all at the same time.

Loops

Loops just ask Roblox to repeat a set of commands multiple times and are very cheap for Roblox to set up. However, if aren't careful to avoid repeating expensive operations, a loop makes it easy to get very poor performance. Let's take an example:

function Sum(startingSum)
	local sum = startingSum or 0
	for i = 1, 100 do
		for j = 1, 10 do
			for k = 1, 100 do
				for m = 1, 10 do
					sum = sum + i*j*k*m
				end
			end
		end
	end
	return sum
end
print(Sum(0))
local result = {}
for start = 1, 10000 do
	result[start] = Sum(start)
end

Sum() is an expensive operation. You see how the for loops are all inside each other (this is called "nesting")? When this happens, you multiply the number of times each loop will run together to get the total number of iterations (in this example, 100 * 10 * 100 * 10 = 1,000,000). Roblox can actually run Sum() on my computer in about 0.066 seconds (which means we could do this once every frame and not create any substantial lag). So, the print(Sum(0)) is no problem.

But then we take a look at the for start = 1, 10000 do loop. Since it calls Sum every iteration, we multiply the number of iterations together (10,000 * 1,000,000) to get 10 billion. We can see that this would cause prohibitive lag! (On my computer it would take approximately 11 minutes -- if my computer was acting as a Roblox server, this means that everyone's client would freeze for that entire time! My computer isn't nearly as powerful as Roblox servers, but even freezing for a minute is obviously no good).

Solutions to the scenario

There are two solutions to this scenario, assuming that we actually want/need the results.

  1. Add wait commands to spread out the work
print(Sum(0))
local result = {}
for start = 1, 10000 do
	result[start] = Sum(start)
	wait()
end

The whole loop will not finish for many minutes, but the rest of the game can keep processing.

  1. Simplify the script. In this example, the script can be rewritten so that Sum is only executed once. Though this won't be possible all the time in real life scripts, it's always good to do if you can. A better script (without changing Sum) would be this:
local baseSum = Sum()
print(baseSum) --instead of print(Sum(0))
local result = {}
for start = 1, 10000 do
	result[start] = baseSum + start --instead of Sum(start)
end

This script will run very quickly.

The general lessons are these:

  • If a function does a lot of work, try not to call it multiple times when you could cache the result (that is, save it to a variable) instead.
  • Be wary of putting lots of loops inside each other if, when you multiply the number of times they will run together, you get a large number (ex one million). If it is too large, you either need to redesign, or consider using wait commands so that you don't freeze Roblox.

This discussion is preserved as it was. New answers, comments, and votes are closed.