Reliable server wait/timing

	while true do
        print("Target set")
        wait (1)
    end

This should happen every second. If the server load is very high though wait becomes slower. This means that it will take more than 1 second to print “Target set”. In turn, this messes up other animations. How to fix this problem where wait becomes unreliable?

The problem is not in the targeting code. But in wait becoming unreliable to measure time.

Dont think this is something that can be fixed, while loops will always buckle under stress. Maybe you can wait a little longer to decrease the lag.

The problem can be solved with the mentioned solution. But it is cumbersome. Maybe there is a better way.

There is no way to get reliable time yielding without heartbeat or renderstepped.

local lasttime = 0
local time = 0
game:GetService("RunService").Heartbeat:Connect(function(dt)
    time = time+dt
    if time-lasttime>=1 then
      lasttime = lasttime+1
      do
        print("Target set")
      end
    end
end

You could run the targeting system per user on the client, then the client tells the server when to shoot at the player.

This weeks be more reliable under stress, however the user could also use exploits to disable this feature.

Yes, unfortunately this method is prone to exploitation as you said.

Perhaps you could check if you’re still receiving pings from the client, if not, suspect of exploit and kick the player?

Perhaps every 2-3 seconds check if the player has sent a valid Target to the server

Ok, I guess this is the only reliable solution

Instead of creating a security system to prevent exploits, I would better use the heartbeat solution. Both are cumbersome but the latter is a bit easier to implement and predict.

AFAIK this is pretty much what the wait function and thread scheduler does internally already, so that function will most likely have the same issues under a lot of stress.

Are you actually seeing this issue? If so, there’s probably something unnecessarily slowing down the thread scheduler and you should look into solving that first.

Using wait is generally fine where it makes sense and the time difference is usually barely noticeable.

1 Like

Indeed there are other issues that I fixed. However I wanted to find a way to make the code failproof in case of lag in the future.

So as long as my game is not slow by design wait should do just fine, right?

The function wait is not guaranteed to wait the exact amount of seconds you specify. Here’s an old thread that briefly talks about wait and its return values (as it’s a callback function):

tl;dr wait(n) does not wait exactly n seconds.

This whole thread sounds more like you have code optimisation problems in which you’re running generally inefficient code. I don’t think there’s anything wrong with wait. You’re asking about the wrong topic here - look into your code efficiency. This problem roots from a bigger one.

Yes, in most cases.

This old blog post might be helpful: https://blog.roblox.com/2012/05/using-wait-wisely/

1 Like

Thank you, this blog post was indeed very informative.

This is compensated by the following:

local lasttime = 0
local time = 0

and

if time-lasttime>=1 then
      lasttime = lasttime+1

The difference between 2 waits will not be consistent just like a standard wait(1) loop; however, it will avoid wait time build up.

After running 1000 cycles of a wait(1) loop, you will accumulate a total of around 1040 seconds, maybe even more, while my solution will accumulate around 1000.1 seconds. There will always be an offset, but my solution keeps it always within 1 second.

Sure, but it still wouldn’t help if threads are being throttled. It could even be worse, as a lot more thread have to be resumed every Heartbeat step.

There are cases where your solution would be useful, but might not be that necessary for something like a targeting/follow script.

3 Likes

This is true. I have used this approach before. Does not matter how much the server lags. If your animations depend on steps generated in this way then they look chopier but in the end they are accurate.

1 Like

Yes, what happens is that you account for it in your code. You make your animations/targeting/reloading account for that delta time.

In the end is like using wait() return value. I just have to get used to it.

Never really noticed that being the case. I had a benchmarking place (that I accidentally deleted after formating :frowning: ) with this and didn’t really see any issues even with throttling.