Variable dt causes game to run twice as fast (DEF-3146) (SOLVED)

I’m using a 165hz monitor with nvidia g-sync, does this also have an effect? I have yet to sit down in my reading lounge with these last explanations so I’m a bit confused.

Edit: Just moving the running dmengine.exe from my 165hz monitor to my 60hz monitor speeds up and slows down the game immensly, so yes, it does have an effect :slight_smile:

2 things I’m still confused about now is:

  1. Is there a performance hit for settings msg.post("@system:", "set_vsync", { swap_interval = 0 } ) ? I tried that, and that removes the “sped up” effect on my 165hz monitor, both monitors seems to act the same.
    This is with variable dt unchecked btw.

  2. What settings gives the most similar/consistent experience between my dev pc and slower mobile phones that might drop below 60 fps here and there? I suppose the answer is dependant on what I define as similar experience…

Is it correct to assume that with variable dt, the game could actually slow down due to frame drops but not let the player “miss” anything, but without variable dt, the game could drop frames and the choppy gameplay could make it harder for the player to react to things, essentially “missing” stuff happening between the frames?

The way I understood it:

WITHOUT variable dt, the game will slow down, but not let the player miss things. WITH variable dt, the game will run at constant speed, but frame skips might make the player miss things

Without variable dt, there is no way to make sure the game runs at the same speed if the display refresh rate is not 60Hz (Which makes this option a no-go for me), UNLESS you use swap_interval = 0, which updates the game on a timer, ignoring vsync (which I believe might cause tearing).

With variable dt, you rely on whatever the driver setting for vsync is and the game will always run at the same speed. Also physics updates might be imprecise due to variable dt.

There is no performance penalty for swap_interval = 0 except your FPS will be fixed at update_frequency.

2 Likes

This makes it a bit clearer for me, but I’m not sure I’m 100% there.

I don’t want tearing, and I don’t want imprecise physics.

@devs, documentation suggestion, maybe have like a simple table with different approaches and their pro’s/con’s, and a comment on different types of games that would benefit from which type of approach?

4 Likes

I’m working on my game on Windows, which runs the game slightly faster than on my Galaxy S7.

I noticed that if I just bump up the timestep on my collection proxy, the game feels a lot better (like on my computer), so I think I’m going to lower the timestep instead during development, adjust gameplay feel accordingly, and then put it to 1.0 when finishing up.

It’s not hard to do since I’m already tweaking timestep due to gameplay features. Only drawback off the bat is that the ratio between “full speed” and slowed down events are off if I keep switching the full speed timestep value and not the others.
The “others” being for example slow down on player death or dramatic events in game.

1 Like

That is a great idea.

3 Likes

In the meantime, I made this work-around to the variable_dt on Windows bug. It measures game time and real time for an interval of 1 second and tells you the time step you should use in your collection proxies.

2 Likes

Hi! Any news on this? @Johan_Beck-Noren? @britzl? It’s a pretty serious bug and my workaround is not perfect.

1 Like

We added ticket DEF-3146 for tracking this issue, but no progress so far I’m sorry to say.

As a first step we talked about better documenting how vsync, variable_dt and monitor refresh rate play together in Defold.

As the problem is described in this thread it definitely seems like a problem with how we measure time, perhaps too low os timer resolution. We are working on it!

8 Likes

Solved in Defold 1.2.126

4 Likes

I’m making a Facebook Instant game. When using go.animate on iOS devices on battery saving mode (and thus locked to 30fps) the animations take twice as long. When “Variable Dt” is ticked in the project settings they appear to take the correct amount of time, but the animations are choppy.

Equally, on my external monitor the game runs at 75 fps and the animations are too fast when “Variable Dt” is unticked.

Could this be related to the discussions in this thread, or is this expected behaviour? If so, what’s the correct way to deal with this? I’m using Defold 1.2.140.

We will release support for variable refresh rate screens soon. Most likely in 1.2.142, in two weeks.

Not sure about iOS battery saver mode though. @Johan_Beck-Noren?

3 Likes

variable_dt should be a solution for most cases since it measures actual time elapsed for the time step used. Can you describe more how the animations are choppy? Choppy as in unstable just 30fps-choppy?

1 Like

Amazing!

Choppy as in skipped frames; the animation is stable but not smooth.

Well to be more precis, we will soon support monitors that run at a refresh rate ≠ 60 Hz. Supporting monitors utilising full variable refresh rate (e.g. Nvidia Gsync or AMD Freesync) is still a way off and has not been designed as of yet.

3 Likes

Will this also affect Facebook Instant games on iOS devices?

Because go.animate is time based, shouldn’t the animations take the same amount of time, regardless of framerate?

It is time based, but tied to a timestep dt. This allows to for example pause a collection or let it run in slow-mo. “variable_dt” measures actual time which is more robust under different setups (vsync on/off in driver settings, low bat mode etc.) but can cause issues with physics if there are large differences in frame time since the same dt is used for all system throughout the engine.

In the future we should decouple our physics more from the timestep, either by handling short/long frame times in a nice manner or putting it on a separate thread.

Okay, I’ll have to experiment with this to make it work as intended. I can’t easily use delta time in my game, because I calculate a lot of things in only one frame. I may have to grab the average delta time and use that.

Hmm how do you mean? Can you describe what you are trying to solve?

Basically I’m trying to make go.animate run smoothly on Facebook Instant on a variety of devices, including the low power mode on iOS.

To exclude that I’m doing something silly in my game that eats CPU/GPU, I’m making a test project now. I will be back!

So I’ve thoroughly tested this on a number of devices loading a Facebook Instant game. On iOS devices there is an initial 1-2 stutter, where framerate drops/frames are skipped. After this period it stabilises and runs smoothly.

After removing culling code I was running every frame, my game also behaves like above. I’m starting a new topic for that here: To cull or not to cull

Thanks!