Is there a wait() that doesnt freeze/slow when fps drops

while true do
	print("test");
	task.wait(0.1);
end

(this is just an example, my code is more complicated than this)
“test” will print slower to people who have lower fps
because for some reason wait() function doesnt finish until the next frame

is there a solution to this?

3 Likes

The whole point of a loop is that it runs at the client’s requirements, meaning the less FPS you have, the fewer threads, etc., going through. If you want to run a loop without worrying about FPS loss, you should look into ServerScripts since they run on the server speed rather than the Client Speed.

3 Likes

hello, thanks for the reply. would serverscripts rely on ping?

3 Likes

ServerScripts would rely on the Server’s ping rather than the clients. If you send requests to the client from the Server, the Server won’t get back the requests until the ping/sync matches up. Henceforth Desync.

2 Likes

oh well, thats unfortunate… thanks for the reply though

1 Like

You can solve this by keeping track of how long it’s been since the last frame and printing more times in a single frame to make up for it.

local accumulatedTime = 0
local printTime = 1/60-- once every 1/60th of a second, so once every frame at 60fps
local runService = game.Workspace:GetService("RunService")

while true do
    local deltaTime = runService.Heartbeat:Wait()-- Basically task.wait() but we also get the amount of time since the last frame
    accumulatedTime += deltaTime
    while accumulatedTime > printTime do
        accumulatedTime -= printTime
        print("test")
    end
end

(note: this is untested code, let me know if there are any issues with it)

3 Likes

Eh, that’s one work around I guess.

1 Like

I believe this is actually the industry standard way of handling use cases like these, haha. That’s why some games crash on low end hardware, because they enter a “death spiral” of sorts where processing a frame takes so long that they have to process 2 the next frame, then 4, so on and so forth.

1 Like

hello thanks for the reply, unfortunately my code uses tween in a while loop, i want the loop to restart once the tween is complete… (its much more complicated than that, so i cant just make the tweeninfo have -1 repeat)

1 Like

Can you send your code over then? It would be easier to help you fix it if we have a clearer idea of what the issue is

1 Like

yes sure, but the script has a hundred lines, and ill only put in a portion of it

while not done do
	local function tweenToPosition (targetCFrame)
		local tweenTime = speed/10;
		local tween = tweenService:Create(v, TweenInfo.new(tweenTime, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false), {CFrame = targetCFrame});
		tween:Play();
		v.AssemblyLinearVelocity = (targetCFrame.Position - v.Position) * 10/speed;
		tween.Completed:Wait();
		v.AssemblyLinearVelocity = Vector3.new(0,0,0);
		tween:Destroy()
	end
	for i = -#positions, #positions-1, 1 do
		if i ~= 1 and i ~= 0 then
			tweenToPosition(positions[math.abs(i)]);
		end
	end
end

basically the part tweens to different positions and reverses

1 Like

I don’t see a wait anywhere here. What’s the issue?

1 Like

the wait is the

tween.Completed:Wait();

1 Like

That’s not a wait like task.wait, though. That’s a connection. It’ll always run as early as possible regardless of framerate.

1 Like

can you tell me the problem?
is it the while loop?

the thing is that theres supposed to be a “delay” variable, once the script starts.
the script references many parts, with different delays on when to start.
when i start it the delay works (part 1 moves first, 1 second later part 2 moves)
but after some time, especially when having a low framerate, the parts become out of sync. (part 1 moved a second before part 2, but after some time it looks like part 1 only moved half a second before)

im sorry for the inconvenience, im still a beginner

Well, the ideal way to do this in order to make sure that everything is synchronized across everyone’s screen would be to not use a tween in the first place but instead use a timestamp system.

Using Workspace:GetServerTimeNow() will give you the time, synchronized between both the server and all of it’s clients. The server should tell each client when the “tween” started (whether via remotes or via attributes, anything works)

Then the client, each frame, checks the current time, compares it to when the tween started and uses that to figure out how far along the path the part should be placed.

More importantly, why do you need this part to be synchronized across every client? There may be a better and easier solution to implement depending on what the use case of this part is. What is this tweened part supposed to be doing in your game?

you may have misunderstood, the script isnt just referencing one part, the script is in a forloop of folder of parts. each part has different delays

That shouldn’t affect anything.

Emphasis on this because even when I was working on an on-rails shooter the timestamp solution ended up taking several weeks to implement. Work smarter not harder and all that.

im sorry, im a little confused. what did you mean by “synchronized across every client”, are you saying like, different players in the server? or just the current, local player client. the use for the moving part is for a “meta” obby, it has to be precise on the different part’s delay

again, im sorry for the inconvenience