I'm developing a real-time browser roguelike using an ECS and currently I'm unsure of how to handle time. As of right now, whenever I need the current time, I just call performance.now(), so I currently have around 100 calls to performance.now() in my code (for things like animations, buff timings, etc.)

This causes no issues, but after doing some profiling, I've noticed it's taking up a decent amount of execution time (more than I would like, anyway), because it is run in a hot loop (my game update loop).

I use requestAnimationFrame for the rendering loop and I know that it passes in the timestamp for each invocation, but I wasn't sure if this was granular enough. For example, if the game is running at 60 fps, the timer updates will be spaced 16.67 milliseconds apart, whereas currently they have sub-millisecond granularity.

Another idea I had to have better granularity without constant calls to performance.now() was having some sort of global function for getting the current time that I would update every so often. I could have some sort of setInterval() for updating the timer every second, or perhaps I could update the time after every individual system ran.

Regardless, I was unsure of exactly how to solve this problem. I don't think it is wise to just sprinkle performance.now() all throughout my code whenever I need a current timestamp, as it seems not very performant and inelegant, but the alternative (requestAnimationFrame) is not nearly granular enough (~17 millisecond spacing).

Is there any other alternative to just caching the time and updating it every so often?

  • 2
    \$\begingroup\$ For what purposes in your game do you need time values at sub-frame precision? Updating the logical time value once per displayed frame (ie. 16.67 ms apart at 60 fps) is a very common practice in games, and can be sufficient for uses you mention including animation and buff timings. The player doesn't see the effects of a timer completing until the next 60 fps display frame *anyway", so generally we can catch up on any events that occurred in that interval and display the net result at the end. Can you clarify a specific use case where this has been insufficient for your needs? \$\endgroup\$
    – DMGregory
    Jun 21 '21 at 1:00
  • \$\begingroup\$ @DMGregory I think it's just a better experience to have more precision? Like for example, casting a spell the millisecond it's off cooldown instead of having to wait for the next frame. As an example, let's say that a spell is technically off cooldown (it can be cast every 250 milliseconds and the exact timestamp is 251 milliseconds after the cast), but the frame time is only 245 milliseconds. In this case, you would have to wait for the next frame (an additional 16 milliseconds) to cast the spell. So not having accurate timers can increase input latency. \$\endgroup\$ Jun 21 '21 at 2:13

You must log in to answer this question.

Browse other questions tagged .