A Tick System That Doesn’t Suck

Ticks are always difficult to get right. Everything in a game needs to move or animate at the right speed, and you need to know how many “ticks” have elapsed during each render frame in order to do that correctly. Javascript gives you the Date.now() function, which returns the number of milliseconds since Jan 1, 1970, for whatever reason. That’s a start.

You can call Date.now() on each render frame and figure out how many milliseconds have gone by since the last render frame. But what happens when the game is paused? You don’t want things moving around. You could just skip your render function altogether when the game is paused, but that doesn’t stop Javascript from continuing to count those milliseconds. As soon as you un-pause, everything is going to jump to some new position, which is bad.

My solution was to create something called a “time base.” It’s just a counter that gets initialized to the current value of Date.now() when the game starts up. So, if you subtract the current time minus the time base, you get exactly the amount of time you’ve been playing the game since it started. The second trick is to increase the time base whenever the game is paused. That way, the difference between the current time and the time base doesn’t change while the game is paused. Magic! The net result is that your getElapsedTime() function returns exactly how long you’ve been playing, not including any time that the game was paused.

It might seem more simple to just create your own timer and ignore Date.now(). For example, if you know that your game is rendering at 60 FPS, just increment your timer by 1/60th of a second on each frame. Then, when paused, you won’t do any rendering, so you won’t increment your counter. This works, kinda, but it gives you a really “coarse” timer. Your timer will only advance by 1/60th of a second, always. That might be fine in some cases, but if you want to do more precise things, like maybe measuring the performance of small sections of your render function, you’re going to need the millisecond accuracy of Date.now().

In other words, if you only increment your timer at the beginning of each render, it’s not going to change again until the next render. So forget about computing how long some specific section of your collision detection algorithm took, for example.

Aside from fixing my timer, I made a few other improvements and converted the asteroids into icosidodecahedrons because, well, why wouldn’t I?

Version here.

2 thoughts on “A Tick System That Doesn’t Suck”

Leave a Reply

Your email address will not be published.