Wait times randomly extended [Urgent-ish]

For some reason in my game using Wait() in my game can have extended wait times.
I used wait(0.1) to slightly something in my game. I’ve had it delay up to something like 15 seconds. What could be causing this? It really breaks the gameplay.

Keep in mind this doesn’t happen all the time, but it is still fairly frequent.

Is there some bug that could cause these extended wait times?

If you use wait() it will yield the thread until the scheduler decides to run it again, due to the nature of thread scheduling it’s not defined when that will be but I highly doubt 15 seconds like you suggest is solely caused by the scheduler. There’s probably some other issue going on there that’s slowing the whole server down, perhaps another thread is taking priority for the full 15 second interval, causing your thread in which you call wait() not to run for a while.

Not sure why this happens, most likely some form of server lag. I would recommend using wait() on server, and making custom yield function using tick() and RenderStepped on local.

Or just do

game:GetService("RunService").RenderStepped:wait()

I hate when people suggest this as an alternative for the “quickest wait” possible. To add to that, that isn’t even relevant to the thread. He’s wanting to wait one-tenth of a second, not a frame.

That being said, RenderStepped is completely based on the client’s frame rate. If the client is achieving 60 frames-per-second, the code will run 60 times-per-second. If the client is achieving 30 frames-per-second, the code will essentially run at half of its intended speed. This can produce undesirable effects when trying to run code at a consistent rate.

The alternative to this would be to use the regular Stepped or Heartbeat events. These events are consistent and - in my experience - have been the most reliable at running code at a consistent speed.

@FriendlyBiscuit

local start = tick()
repeat
renderstepped:wait()
until tick() - start >= 0.1

Could replace the renderstepped with stepped @OP

1 Like

@DermonDarble

So basically what I like to call “TickStep”.

Free Code Here
-- _TickStep(number Duration, function Callback)
-- Forces an operation to complete over time, not frames.
-- Performs a callback, passing the following arguments (in order):
-- number Ratio: How far the task is in decimal percentage (0 to 1). Use this for animations and stuff.
-- number Elapsed: How long the task has actually taken.
function _TickStep(Duration, Callback)
	local Time = 0
	local LastTime = 0
	local Delta = 0
	
	while Time < Duration do
		LastTime = tick()
		game:GetService("RunService").RenderStepped:wait()
		
		Delta = tick() - LastTime
		Time = Time + Delta
		
		Callback(Time / Duration , Time)
	end
	
	Callback(1, Time)
end

Regardless, that is irrelevant to the OP. Let’s try to focus on the topic at hand.

Do you have lots of serverscripts looping at the same time? I found that in my old games that it got to the point where there were so many “while true do”'s all in serverscripts that wait(1) actually equaled about wait(4) and the game went incredibly slow. Switch to localscripts and/or more events that are triggered by something rather than using a loop to constantly check.

Letting everyone know this is from a localscript. The amount of time it has to wait seems to be directly affected by the amount of players or other performance heavy things occurring. The 15 seconds happened when I was doing test>Start server with 2 players. I have fairly good framerate but anytime a non renderstepped wait() was called it was extended a huge amount.

So guys, this is becoming a MAJOR ISSUE. Everything that uses a wait in the game can have massive delays. Everything can be running at 60fps but any time there is a regular wait() of any kind it’s extended a ton.

Even wait(0.01) can wait up to a second.
Thats in a “for i = 1,10 do wait(0.01)” script. It just fades in a gui. It takes multiple seconds with the wait delays. All sections where I use Renderstepped work perfectly.

This really breaks the game, and I think it’s important.

You need to envision what is happening on a lower level. When you call wait, your thread is yielded and other threads will then run first. If there are many other threads or a single thread is not yielding for a second, then your original thread can not magically run in between, the scheduler only switches between threads when they yield (or when their CPU quantum has passed).

This means either you have too many threads client-side, or some thread has a cycle between yields that is way too long and it is hogging up client resources, temporarily preventing other threads from running as frequently as they should.

I am not seeing this issue at all in my games, so it has to be something specific in your game. If you really think this is a bug, you should try to extract a minimum example where the extended wait times still happen frequently.

See also this thread for a general explanation on how threading works.