fabiangreffrath / crispy-doom

Crispy Doom is a limit-removing enhanced-resolution Doom source port based on Chocolate Doom.
https://fabiangreffrath.github.io/crispy-homepage
GNU General Public License v2.0
802 stars 132 forks source link

Bad frame interpolation when playing network game when uncapped framerate enabled #747

Open thearst3rd opened 3 years ago

thearst3rd commented 3 years ago

Background

Version of Crispy Doom:

I tested with:

Operating System and version:

Tested on both Windows 10 and Linux Mint 20.1. I got the same result.

I tested all of the above on Windows 10. For the commit compiled from source, I used MSYS2 and compiled it as 64 bit. On Linux, I only tested it by compiling it from source (since comparable Windows binaries are not available for download).

Game: (Doom/Heretic/Hexen/Strife/other)

Tested with DOOM.WAD and DOOM2.WAD

Any loaded WADs and mods (please include full command line):

crispy-doom.exe -iwad DOOM2.WAD -server -privateserver -deathmatch on machine 1 crispy-doom.exe -iwad DOOM2.WAD -connect <ADDRESS> on machine 2

Bug description

Observed behavior:

The interpolation of frames is jittery when playing a network game. When uncapped framerate is enabled, frames do not interpolate correctly and the resulting experience is not very smooth.

I have a video recorded here. Note, I recorded this video at 144 fps (the framerate of my monitor), then I slowed the footage (as best as I can) to be a 60 fps video, so it is slowed down and you can hopefully see each frame and how much they jitter around. Please excuse the poor video editing, I simply took the raw footage and slowed it down, I didn't trim it or anything. It should get the point across though.

https://youtu.be/FYESLXGn_mM

Expected behavior:

When playing a network game with uncapped framerate enabled, the gameplay should remain smooth. If needed, I can provide a comparison video in the same format as the above video but with a single player game.

I'm not sure if this is a known issue - I checked the GitHub issues and didn't see a duplicate. Let me know if there's something I missed. I'd love to help fix this issue, I'm planning a multiplayer Doom session with some friends and encountered this while setting it up myself before hand.

Thanks for your continued work on Crispy Doom!

rfomin commented 3 years ago

Try to add -oldsync to the command line. New sync doesn't work with interpolation properly.

thearst3rd commented 3 years ago

Yep, that seems to do the trick! So now I've got a few questions:

Can this be fixed with new sync enabled? Or does new sync internally work a way that will be hard to make this work?

Should we do something to warn players about this behavior when running a network game with new sync and advise them that they may want to use the -oldsync parameter?

rfomin commented 3 years ago

Can this be fixed with new sync enabled? Or does new sync internally work a way that will be hard to make this work?

That is what I'm trying to figure out. Relevant issue: #363

thearst3rd commented 3 years ago

Awesome, thanks for looking into it. I'm doing some experimentation with the code as well, maybe I can come up with something.

rfomin commented 2 years ago

@fabiangreffrath This patch fixes this for me in Crispy and Woof:

--- a/src/d_loop.c
+++ b/src/d_loop.c
@@ -721,7 +721,7 @@ void TryRunTics (void)

         // [AM] If we've uncapped the framerate and there are no tics
         //      to run, return early instead of waiting around.
-        if (return_early)
+        if (return_early && realtics == 0)
             return;
     }
     else

To be honest, I'm not sure exactly why, I got it after a few semi-random experiments. Could you take a look at this, please?

fabiangreffrath commented 2 years ago

Hm, makes sense, I guess. If realtics == 0 this means no new gametic has begun since we entered the funtion last time, so we don't need to update anything and just redraw the scene.

rfomin commented 2 years ago

we don't need to update anything

Here's what I'm not sure about. As I understand it, the new_sync method tries to update more often than the old_sync method. I tried looking at -netlog but didn't see much difference.

elvisish commented 2 years ago

Can confirm -oldsync fixes it.