[Help Needed] Creating An Accurate Game Timer


I am currently working on a speed-running style game, and need an accurate timer for score tracking on leaderboards etc. At the moment i am using a timeline to keep track of time and then simply using a trigger at the end of the level to stop the timer. This works fine, but i have a few issues with it.

Firstly, the game has to be capped at 60 fps in order to keep scoring fair, since allowing players to go higher essentially means they will be able to trigger the ending earlier despite potentially technically being slower than someone playing at a lower fps. I would like to uncap the fps in my game whilst maintaining a fair scoring system. Secondly, because the fps is capped at 60, this means that scores can only be a multiple of .016 of a second, which isn’t as accurate as i would like, as i already have a few of my shorter levels with tied times despite only having a hand full of testers.

The obvious solution to this would be a sub-tick timer that will work accurately regardless of the fps. Before posting here, i asked around several UE4-oriented discords that i frequent and spoke to a few people about it, many of which told me they think it would be impossible. I have a theory on how to achieve this however, but i am unable to work my head around the actual math behind it, which is where i need and would greatly appreciate some help.

My theory could also be complete nonsense, or a much easier method to achieve the same thing could exist, so if you believe either of these are true, i would also really appreciate your response.

My idea is that i can continue to use the timeline and trigger to stop the time, and the on the same frame, calculate the penetration distance of the players character into the trigger using the current velocity and direction, and then calculating the time it would have taken to travel that distance given the current fps. That time can then be subtracted from the end time provided by the timeline to get the true time that the level would have ended.

The players character is a simple sphere with a varying radios (which will need to be taken into consideration), and the ending trigger is a cylinder that extends into the sky which should hopefully make for easier calculations, although they are still above my head… xD

The way i think of the calculation working is basically just calculating the distance from where the ball currently is inside the trigger, to where the ball would initially start touching the trigger (taking into account all axis) taking into account the direction the ball is travelling. Then using the velocity (and taking into account the current fps), calculating how long it would have taken to travel the calculated distance. Then its just a simple case of subtracting that from the original time.

Il provide some terrible paint drawings also to hopefully help people visualize the idea a little easier.

Lastly, thanks for anyone who took the time to read this far and especially to anyone who tries to help out. <3 i really do appreciate it!

I am assuming you are somehow taking time from an incrementing variable on tick. But you could solve any time issues related to frame dependency by taking into account the delta time (time since last tick; node: GetWorldDeltaSeconds). I.e. if you have player set to 500 units velocity that IS framerate dependent then they will move 500 units per frame (a slow pc will move slower than a fast pc in this case); but if you use 500 units velocity multiplied by delta time they will move 500 units per SECOND (both slow and pcs will move at the same speed).

Final results crossing a finishline or checkpoint would be a little trickier; you’d have to take velocity into account, and the distance between the players previous frame location and where the player crossed the line. There’s a node to find intersection along a plane, should use that for crossed point location.
Final time = previous frame time + ((last frame dist to finish line / velocity) * (delta time))
// I may be wrong, I haven’t done this before. That said, it doesn’t sound impossible at all.

In my initial outline for the idea, i suggest using the final frame (the frame that the end trigger occurs) and then use the direction of travel to calculate the distance INSIDE the trigger that has been traveled and then calculating how long that would take and then SUBTRACTING it from the final time (the time that was taken when the trigger activated).

In your suggestion however, you sort of invert the solution by instead using the frame before the end to calculate the distance TO the finish area and then ADDING that time to the time taken to get to 1 frame before the ending was triggered.

Both solutions would give the same answer, but i’m curious why you chose to change my initial suggestion? Would it not be more effort for the game to have to keep track of the players velocity and time for every previous frame throughout the entire level over simply just using information gathered from the frame that the trigger is hit? I ask this as a genuine question and not sarcastically, because i’m curious if there is something i don’t understand as to why it my original proposal wouldn’t work or why your way would be better.

When i first started thinking how to accomplish such a timer, my initial idea was the same as yours, but i changed it to the one currently on the OP because i figured it would be less effort for the game to handle.

Now that you mention it… Your way would have to store the delta time every frame, my way would have to store the game time every frame. It’s up to preference methinks. In either case, there’s little extra effort for the engine to take a variable that’s already calculated and to store it for later. I had a hard time understanding the diagram so I just went ahead and blurted out what I think would get the cleanest solution.

I may be missing something. Why would i have to store delta time every frame using my method?

In your setup, you are calculating running across the finish line before running across the finish line; In my setup, you are calculating after running across the finish line.

Have you tried using timers as they do not depend on “frames” but actual world time? Like you can have a timer fire every 1/100th of a second and I have used that to create stopwatches that count to the hundredths of a second accurately. I created a blueprint node actually that does all this for racing style games. Gives you a “time stamp” output string or you can access the actual values as floats if you choose. But basically this node starts a timer and it counts up at a rate of your choosing and the end result is a string of text like 01:03:58 which would be 1 minute 3 seconds and 58/100 seconds. Not sure how much more accurate you need to be honestly. Here is the link if you are interested.

I’ve recently fell in love with the set timer by event name node instead of the event tick. It’s so easy to add to the project and from what i’ve read is better for performance. Anything I want to fire off at a constant rate I just add this node to the begin play or at player spawn. Set the time and type in the name of the function I want to repeat.