Tenoch's Turmoil: Finding Frame Rate Flaws

Ludum Dare 43 is just about wrapped up, and we had a great time making Tenoch's Turmoil. While we've already implemented a plethora of updates and fixes in our currently unreleased post-jam version, we've only pushed a single bugfix to our jam submission, and I wanted to take the time to share what I've learned from it.

Unexpected feedback

If you've played Tenoch's Turmoil, you'll likely have noticed that Tenoch moves rather briskly - unfortunately a little too briskly for some players. But one person left a comment saying they thought Tenoch moved too slowly. What?! This was the absolute last complaint we expected to hear! So I set out to investigate what was going on.

What's your game's frame rate?

If you're like me, you might have assumed that Unity games always ran at 60fps, and the frame rate would change only when it dropped under heavy load, so it wasn't worth considering for a jam game. But as it turns out, this is not the case at all. By default, Unity will try to match the frame rate of the game to the refresh rate of the player's monitor. For most of you, that will probably be 60Hz, so games will run at 60fps. But there are quite a number of people out there with 144Hz monitors, and I found my TV had options to run as low as 24Hz, so you really can't afford to make any assumptions.

Confirming the problem

I don't have a 144Hz monitor, but by plugging my laptop into my 24Hz TV I was able to observe the opposite effect - Tenoch was now well and truly too fast, covering the entire length of the play area in one second flat - more than double the speed he was supposed to be running.

At this point the bug was confirumed, but to be thorough I found the setting to force Unity to run at 144fps, and saw what the player would have been seeing. Tenoch was running at less than half his intended speed, and the game was miserable. No wonder the player was upset!

What went wrong?

When you press left or right, Tenoch's velocity is set to a fixed value. At some point, we added code to multiply this by Time.deltaTime in order to smooth it. But the problem is that this kind of smoothing is only necessary for displacement, not velocity (displacement over time), and multiplying by the length of the frame had more or less the opposite effect: Tenoch's movement speed was inversely proportional to frame rate. At 24fps he was running at 60/24 = 2.5x normal speed, and at 144fps he was running at 60/144 ~= 0.4x normal speed. The fix was simple - remove the Time.deltaTime and multiply his speed by 1/60, and all was well again.

Bugs happen, but what could we have done differently?

I've taken the script from here and added some editor-only hotkeys to cycle through some different frame rate options. Being able to easily play the game at different frame rates (both faster and slower!) makes some bugs easier to see, and others impossible to miss.

If you want to do this yourself (and I recommend you do!), the code you'll need is:

QualitySettings.vSyncCount = 0; Application.targetFrameRate = targetFrameRate;

Using this, I've already spotted and fixed a ton of other bugs like this one, plus some other single-frame glitches that become glaringly obvious at lower frame rates. I hope this helps you too!

Thanks!

Overall I had a great time this jam, learned some new things, and ended up with a submission that I and the team are all proud of. I'm grateful for everyone who has taken the time to play, rate and comment on our submission, and everyone else who submitted a game and helped make this jam what it was. Thanks!