In programming, there's many ways you can make something happen every second. But not all methods are equally precise.


The best way is to compare against a fixed point in time, but this needs to be stored and calculated with double precision to remain precise even if it keeps running for days.

It's not too hard to roll your own solution for getting the time in doubles; you just need to make sure it's done once per frame before other scripts run, and have all scripts reference that. If each script get the time value on the fly, your game logic timing will be a mess.

Show thread

@runevision For things on slow enough timers like >1 second, is it not worth rolling a single ordered queue of timers each with delta times (so you decrement the first item in the queue each frame until it pops then pass on excess)? Only evaluates minimum number each frame, evaluation respects "when it happened" ordering, but adding a new timed event is relatively more expensive.

@shivoa It don't fully follow, but it sounds like you're talking about an optimization that might be relevant if you have tons of these timers going on at the same time.

@runevision So rather than calculate anything in absolute time, every timer is recorded as +delta past last timer in ordered queue (no FP emergent errors from leaving a game running too long). You're only ever subtracting the frame delta (from the timer with the least time left) & don't have to query every active timer to see if any of them have gone past zero (if you have many long timers active).

@shivoa Whenever you rely on deltas, things can drift due to floating point precision errors that can add up for every subtraction.

@runevision Ye, the lack of a perfect solution is real (but then we are talking about systems where, under the hood, we are lucky to have anything more than the guarantee of a monotonically nondecreasing clock for deltas [eg QPC] & not even that for wall time estimations).
Might suggest a "check wall time for drift" repeating timer that corrects drift every few minutes as part of the timer queue system is least bad compromise.

@shivoa How are you going to check for drift if you're not using a fixed frame of reference? Forget the queue system and consider just a single variable that you increment with deltaTime each frame. How would you check if it's drifting and correct it?

@runevision Because the underlying system isn't just a freefloating delta but is tied to the underlying platform (relatively) cheap "tick" system like QPC. Basically we're not dealing with FP issues because under the hood everything is ints with the OS/CPU holding a vague notion of time deltas (without a guarantee that every ms is identical in length but at least they can't timetravel backwards unlike walltime queries).

@runevision With the caveat that OS guarantees are sometimes broken & that's really annoying if you're on one of those platforms. eg discussed here:

@shivoa I'm not talking about drifting in the time system we're using, I'm talking about drifting caused by floating point arithmetic itself. If you add 0.001 together 1000 times it's not going to equal 1, and this has nothing to do with any time backend.

@runevision Sorry, now I'm lost.
I'm proposing using the QPC-style timers derived from the CPU without being expensive to call as determining how we get the deltas. The underlying system is ints & the queue on top should probably just use ms ints (even int32 that's 25 days as the max delta you can store).

@shivoa Oh, you want to use ints for the timers? I mean, this has drifted so far from the small code snippets I was discussing that I think it's an entirely separate discussion. My point was advise that is just a few simple lines of code so people could easily adapt it.

@runevision Sorry. I got caught up in "best way" meaning of all possible ways not just of those proposed (with a focus on underlying platform ability to report time + does a method scale when more timers are added).
Timers are tricky problems; didn't meant to tread all over your lesson.

@shivoa Don't worry about it. :) And to be clear, it could well be what you propose would be best (can't say really) but it would just need for someone to go and implement it and make it easily accessible for it to be a practical approach for most people.

Sign in to participate in the conversation
Gamedev Mastodon

The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!