Frame Cap and VSync

I use a 60Hz monitor. When I set vsync to disabled and frame cap to > 60, the value of dt decreases accordingly.

For example:
if frame_cap = 60, then dt = 0.016
if frame_cap = 120, then dt = 0.0083

This makes sense, but does this decrease in dt value affect anything since my monitor is only capable of drawing at a max of 60 FPS? My assumption is that this is doing nothing but wasting 60 frames.

Additionally, when I set vsync to enabled and frame cap to < 60, the game runs faster. For example, if frame_cap = 30, then the game moves in “x2 superspeed.” Conversely, when I set the frame cap to > 60, the game runs slower. For example, if frame_cap = 120, then the game moves in “x0.5 slow motion.” Could someone explain to me why this happens?

2 Likes

Hey, it shouldn’t run any faster/slower if you use dt for all time/motion related calculations. For example, if you have a timer which should trigger an event you will want to increment it by some scalar of dt (such as timer = timer + 2 * dt) or calculate things so the value of dt makes sense for your timings. If you have motion to have to multiply each change in velocity by dt such as position.x = velocity.x * speed * dt If you do this properly the game will run the same speed regardless of refresh rate.

Unfortunately this isn’t true, but I wish it were that straightforward. I believe it has something to do with the frame rate trying to match up properly with the refresh rate on a 60Hz monitor. It seems that using both vsync and frame cap causes problems.

I was also thinking that maybe it’s just the gui.animate() animations that were affected, but it seems that all calculations are super speed or slow motion.

I was playing with the settings in other non-Defold games and found that increasing the frame cap above 60 FPS with vsync enabled didn’t affect anything (but slows everything down in Defold) while decreasing frame cap below 60 FPS with vsync enabled acts as you’d expect: the game gets choppier, but overall runs at the same speed (but speeds everything up in Defold).

See if you force VSync on via your graphics card configuration panel. Sometimes it seems like it doesn’t get set on some computers and has to be manually enabled.

We have VSync enabled and frame cap to 60 in multiple released games and it seems like the best option.

1 Like

If you enable vsync or/and set framecap to 60, Defold will use fixed dt. So, if someone has slow device and fps is below 60, then your game will run like in a slowmo mode.

My target platform is web, so I prefer to disable vsync and set framecap to 0. It enables variable dt - https://github.com/defold/defold/blob/8d8a914076eae26460f48ecc47a0ddb9d8a0a3a6/engine/engine/src/engine.cpp#L676

2 Likes

I think we used to do that but on desktop there were more common problems. We still have a config option on our settings screen to disable VSync which also sets framecap/update_frequency to 0 just in case.

Edit: Looking at our project (turns out we were not setting set_update_frequency at the same time as toggling VSync) and experimenting there seems to be some problem with set_update_frequency while running.

If I disable VSync and set Frame cap in game.project to 0 then when running the game is solid 60FPS/16ms (we use system time for this, not engine dt). And toggling VSync / update_frequency in engine doesn’t seem to be a problem.

But if VSync is enabled / Frame cap is 60 in game.project then disabling VSync and setting update_frequency to 0 in engine does not have the same effect, instead it is slowmo with very slow actual ms updates. Seems to be a bug?

VSyncFramecapIssue.zip (2.4 KB)

Run this without changes and the dot does not seem to move at all. Comment the init lines in test.script and it runs as expected, then edit the game.project to set Frame cap to 0 and uncheck VSync and it also runs as expected. But shouldn’t the initial state of the project and the edited game.project be equivalent?

2 Likes

My experience is the following:

Enable vsync and set frame cap to 0 in game.project. This will allow the game to run at 60 FPS or whatever matches the test monitor’s Hz. Expected result.

Enable vsync and set frame cap to 0 in code. This will allow the game to run at 60 FPS or whatever matches the test monitor’s Hz. Expected result.

Enable vsync and set frame cap to 0 <= x < 60 in code. This destroys execution of the game, forcing it into “slow motion” mode. Unexpected result. Shouldn’t this respect min(frame_cap, monitor_Hz)?

Enable vsync and set frame cap to 60 < x in code. This destroys execution of the game, forcing it into “superspeed” mode. Unexpected result. Shouldn’t this respect min(frame_cap, monitor_Hz)?

Disable vsync and set frame cap to 0 in game.project. This will also allow the game to run at 60 FPS or whatever matches the test monitor’s Hz. Unexpected result. Shouldn’t this allow the game to run at maximum possible FPS?

Disable vsync and set frame cap to 0 in code. This destroys execution of the game, giving me exactly 1 frame per second. Unexpected result. Shouldn’t this allow the game to run at maximum possible FPS?

Disable vsync and set frame cap to 0 < x in code. This will allow the game the run at x FPS, choppy or smooth based on the value of x. Expected result.

So there are some issues here.
(1) Disabling vsync and setting frame cap to 0 in game.project presumably allows for FPS equal to monitor refresh rate, while doing this in code kills execution speed.
(2) All of the “unexpected result” statements mentioned above.
(3) How to deal with all of this is the game’s options menu? I want the player to be able to set the frame cap to anything between 10 and 120, while also allowing them to check or uncheck vsync. I don’t want them to have a poor experience with the options menu if unexpected results occur or unfair advantages or disadvantages due to superspeed and slow motion.

3 Likes

There must be something project specific going on. If I disable vsync and set framecap to 0 I get maximum FPS. It does lag and run at 1 FPS if I set the framecap to 1 as expected. What version of Defold are you using?

1.68, however it’s not a terribly old version. I’ll try testing this with the latest version.

Any differences are likely due to OS/GPU. For some GPUs, people have to force enable VSync in settings of the GPU to not have the game run super fast.

Some of the weirdness might be due to GLFW2, and upgrading to GLFW3 might help fix some issues but it would be a big task to do.

1 Like

I’m thinking that a workable solution would be to set frame cap to 0 when vsync is enabled. This would avoid the super speed and slow motion issues. When vsync is disabled, the player is free to set frame cap to any of the preset options (10 through 120). This sounds logical and acceptable to me. After all, if the player sets vsync to enabled, then there is no practical reason to set the frame cap to anything other than the monitor’s refresh rate.

I feel good about this now. My belief is that a game should always give technical control to the player, no excuses. Excluding these options shows a lack of care or skill from the developer.

1 Like

Unity team posted a great article about how they fixed delta time issues in the Unity 2020.2 - https://blogs.unity3d.com/2020/10/01/fixing-time-deltatime-in-unity-2020-2-for-smoother-gameplay-what-did-it-take/

Worth reading!

6 Likes