Reliable server wait/timing

Hi,

I want to write some repeatable “targeting code”. I want to do my “targeting logic” then wait some time and then run the logic again. Normally I would put this in a while true loop with a wait. However I know that the wait function is unreliable when server load becomes high. This might make the targeting happen way less often.

In the past I have written a module that uses heartbeat to trigger this kind of event. I would register my event and the time I want to wait and then just listen for the event. The module would use the heartbeat steps to update all the registered events.

I wonder if there is a simpler solution to this problem.

2 Likes

Could you define “targeting code”?

It is some code I use to find a target.

It is irrelevant for the purpose of the question. Any code that needs repeating will have the same issue.

As in, in an array? Or for things like turrets in range? Just trying to understand what problem you’re dealing with

An issue could be how your targeting code is written. Do show some code. Your question won’t get so far without code. Also the way you use “target” is ambiguous and you need to be more specific.

	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.