Unstable FPS in Vsync mode

Hi guys. I’m making Vampire Survivors clone as my first project in Defold.

Everything works quite well, even with 1000 enemies rushing toward the player, as long as Vsync is disabled.

Let me share some more about the scene and settings:

  • All 1000 enemies have one animated sprite, dynamic collision object and script, that pushes them toward the player.
  • There are 18 drawcalls in each frame.
  • Physics engine is 2D type, with fixed timestep set to 30.
  • Apart from enemies, there are GUI, tiled map with 6000 tiles and the player.
  • Resolution: 1600x900, framerate of my display is 60Hz.

And the illustrative graphic:

I had issue with ustable FPS and have been exprimenting for quite long time with different types of collision objects (kinematic/trigger) and handling collsiion in lua, various physic timestamps etc, however nothing really helped, I couldn’t achieve stable 60 FPS for more that 100 enemies touching each other.

I decided to untick the Vsync in Display setting and I was stunned… 500 fps (with min: 400, max 800) just happend with basic dynamic collisions. It more than enough for me, however it’s strange that with Vsync enabled the FPS is unstable.

Summary of different settings and achieved FPS:

  1. Update freq: 0, Vsyns: DISABLED – FPS: min: 400, avg 560, max 800.
  2. Update freq: 30, Vsyns: DISABLED – FPS: min: 29.8, avg 30.0, max 30.1.
  3. Update freq: 60, Vsyns: DISABLED – FPS: min: 59.7, avg 60.0, max 60.3.
  4. Update freq: 120, Vsyns: DISABLED – FPS: min: 105, avg 110, max 115.
  5. Update freq: 0, Vsyns: ENABLED – FPS: min: 27, avg 59, max 64.
  6. Update freq: 30, Vsyns: ENABLED – FPS: min: 29.9, avg 30.0, max 30.01.
  7. Update freq: 60, Vsyns: ENABLED – FPS: min: 59.2, avg 60.0, max 60.5.
  8. Update freq: 120, Vsyns: ENABLED – FPS: min: 13, avg 58, max 63.

As you can see above, the theoretical max FPS is quite high and stable. Also it is possible to maintain 60 FPS with update frequency set to 60 and no Vsync.

Is anybody have clue why there is sudden drop in stability, when Vsync is enabled and update frequency is higher than display framerate? The FPS drops are still present even when the amount of enemies is reduced to 250.

1 Like

This was flagged recently

I’m using Windows and it’s not working exactly as pointed in this issue.
Rather I have just some random frame drops, but only in Vsync mode without update frequency set below refresh rate of my display. With update frequency set to 60 everything works perfectly smooth.

Hi there, I am facing exactly the same problem and been trying for days. I can easily have 1000 enemys with dynamic sphere collision moving towards the player (barebones script) with about 1600 fps (no vsync, fixed update rate of physics at 30 Hz), but as soon as I switch on vysnc, the framerate drops below 60 Hz occasionally and the game is stuttering.
I am on Windows too.
This is the same if I run the game from Defold or if I bundle a release for windows.
I love Defold from toying with it for a week now, but something is off here.

Thanks, so much for any help!

Nobody out there to help? Or is this a known issue that Defold cannot reach stable FPS? I tried everything, collision handling and all other scripts are now in seperate frames. Garbage collection on or off, no difference. Here two screenshots without Vsync about 1000 fps however, drops to 1% low (Nvidia Frameview) of 170 fps, but with Vsync drops to much below 60 fps … Help, please … I really like Defold otherwise. Great project.


@coroner-gss Thanks for digging this up.

Yeah, still same for me. In my game prototype I how more than 1000 FPS with fixed framerate and vsync disabled, stable 60 FPS with fixed update but with vsync and fixed fps disabled there are framerate drops.

For now I just dont use vsync at all and just set fixed 60 FPS.

When developing video games you should measure frame time, not FPS. Let’s leave the measurement of FPS and 1%, 0.1% etc to game journalists.

Next to the question of your game cycle and why it seems to work better with vsync disabled. Let’s imagine that use fixed timestep is enabled for physics, with vsync enabled on a 60hz monitor and with 30hz fixed update:

frame number | what is happening in the frame
1 | update, fixed update, render
2 | update, render
3 | update, fixed update, render
4 | update, render
5 | update, fixed update, render
6 | update, render
...

Without vsync:

frame number | what is happening in the frame
1 | update, fixed update, render
2 | update, render
3 | update, render
4 | update, render
5 | update, render
6 | update, render
7 | update, render
8 | update, render
9 | update, render
10 | update, fixed update, render
11 | update, render
...

So when measuring FPS, it will appear to you that with vsync disabled, their minimum values are higher, as there are simply more of them per second on average.

But periodic lags in the game will not disappear anywhere, because physics updates require a huge amount of time on such a large number of objects. Plus, if you put a script on each object, it will work as it does now.

7 Likes

I agree that frame time is the key for smoothness, however at least in my experience there is something wrong going on with the vsync. I respectfully disagree that is seems to work better with vsync disabled. Every time the update frequency is higher than my screen frequency I experience huge issues with smoothes, not just “a little bit worse 0.1%”.

My screen have 60 Hz refresh rate.
When I run my proto with update frequency set to 0 and vsync disabled framerate never drops below 200 FPS. When there are less enemies even 600 FPS can be achieved.

With update frequency set to 60 and vsync disabled, FPS sometimes drops to 55-56, however everything is smooth in general and pleasant to play.
With update frequency set to 60 FPS and vsync enabled still everything is still fine.
With vsync enabled and update frequency set to 0 or 120, there are 60 FPS with small amount of enemies but huge drops when there is more enemies. Bascilly unplayable.

Is there any preditable reason for issues with update frequency higher than vsync frequency?

Hi there, I already had a look at the frametime extensively. Just posted fps with the nvidia tool because you can see the issue quite good there.
I do not need to “leave anything to game journalists”, I came here because I have anoying stutters. This is also not the first game engine I am working with, I have over 30 years experience.

My code only runs a fixed update frame every 30 Hz (doing nothing except being in sync with the physics update at 30 Hz and setting a timer state) which takes about 3-4 ms (for physics) and following this one other interleaved “duty” frame with about 4 ms for game logic and go.animate() for smooth motion. All other frames inbetween without Vsync basically do nothing (except the engine runs go.animate), thus giving 1000+ fps on average. Nevertheless, without issues, the 1% low fps should thus be about 250 Hz (=1/4 ms).
However, there are some frames inbetween which take longer.

This problem is bigger at 60 Hz Vsync when my code executes interleaved two 30 Hz physics and 30 Hz game update, with (like above) 4 ms frame time each. So this should be super stable 60 Hz (=16.67 ms), with 12 ms overhead per frame, however, this is not the case, there are always longer intermittent frames … so you never get stable 60 Hz.

BTW I also ran 144 Hz with Vsync which gives me 1% drops to 120 Hz, still feeling some stuttering much less pronounced than at 60 Hz of course.
These numbers tell you that it is not my game (which in theory should give stable 250 Hz).

1 Like

It would be really great if you could post small real examples or a repo-case.

I made a quick equivalent of what I saw on the pictures above and so far everything is fine, it runs smoothly (source code). It demonstrates 1000 collision objects, 2D physics; the objects are moving towards the center.

No vsync, 144hz monitor, OpenGL

Vsync, 144hz monitor, OpenGL

image

And just to check that the empty project works okay too -

Empty project, vsync, OpenGL

image

Empty project, vsync, Vulkan

image

3 Likes

Hi there, thanks so much! Just adding

if (socket.gettime() - self.fpsclock) > 0.018 then
	print(socket.gettime() - self.fpsclock)
end
self.fpsclock = socket.gettime()

in fixed_update and initializing self.fpsclock in init already shows occasional random increases to 33 ms on my system. You do not recognize this in the example because nothing is moving in the end, but if you would now move with the camera around it would stutter.

I am not sure, in your example it might in fact be the physics collision that increases its runtime randomly in time, for me it seems to be the script.

BTW, sporadic fps drops also already occur with 100 objects … for me

Curious how this is for you