Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm working on an RTS and there is a lot of camera movement involved. The camera moves at a constant speed but it stutters (seems to jump/jerky movement) if I don't enable vsync. I understand why this is happening, if the game is running at 74 frames per second then 14 (my refresh rate is 60 Hz) frames will be ignored/skipped. If the camera moves 10 units between two consecutive frames then a skipped frame means a movement of 20 units instead which makes the movement jumpy.

My question is how do other games manage to keep their movements smooth even at odd frame rates and fluctuations?

I've not included the code because I've ran numerous tests and I believe the code itself is fine. I've also read this article and am using the suggested game loop. Cheers!

Edit: Thank you for the suggestion Lachlac and Mr. Beast. I changed my code to use delta time instead but the movement is still jerky at 70 frames per second.

while(main_event->type != SDL_QUIT)
{
    last_time = current_time;
    current_time = get_tick_count();
    delta = current_time - last_time;

    SDL_PollEvent(main_event);

    if(rect_data.x < 101) vel_x = 600;
    if(rect_data.x > 1300) vel_x = -600;

    rect_data.x += vel_x * (delta / static_cast<double>(frequency));

    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, rect_texture, NULL, &rect_data);
    SDL_RenderPresent(renderer);
}

I've tried both fixed and variable time steps and they produce the same jerky motion. I'm guessing it's because of frames being skipped but I've included my code in case I'm doing something silly.

Edit 2: For eBusiness:

I have my physics set to 120 Hz and I'm also interpolation between the last and current game state. Each time the renderer rendered, I made it output the displacement in the render position from last frame to the current frame and also the time difference between last and current frame. Here is some of the data:

10              -0.0159823
10              -0.0160441
9               -0.0158394
9               -0.0150374
9               -0.0150993
10              -0.0160116
9               -0.0159414
10              -0.016037
10              -0.0159659
9               -0.0160212

The data was very consistent, it's just that if a frame is skipped because of the refresh rate then instead of moving 9 or 10 pixels, it'll move about 20 pixels which results in the jumpy motion. I also tried to ignore the interpolation value and just use the latest game state and that didn't help either.

Using variable time steps also have the same problem, the displacement and time difference is consistent and frame skips again ruin the smoothness.

share|improve this question
    
I admit this is a sticky plaster solution but why are you running at the unnatural 70 fps rather than the more usual 60? –  Richard Tingle Aug 10 '13 at 9:37
    
Just out of curiosity, I've played several games that run smooth at 70 frames per second so I was wondering how they manage it. I've also read that I shouldn't rely on vsync to cap frame rate, it's just for screen tearing. –  sythical Aug 10 '13 at 9:45
    
What is frequency? You shouldn't need it. Also are you using integer coordinates? Don't. Use floats instead. –  API-Beast Aug 10 '13 at 9:53
    
Frequency is the number of ticks per second and delta is the number of ticks that have elapsed. I'll switch to floats instead, thanks! –  sythical Aug 10 '13 at 9:57
2  
Well, if you use integers and do +=, you will miss the 0.5 parts (+= 1 or += 1.2476 makes a huge difference) and thus get stutter. –  API-Beast Aug 10 '13 at 10:10

4 Answers 4

up vote 2 down vote accepted

I think you may actually have an input latency problem, especially if your game involves a mouse (which is often the case in an RTS).

What probably happens when you run with vsync is that you capture the mouse movement at the beginning of the frame, deal with the information to create the new frame (move objects, camera, etc.), then have it displayed. The elapsed time between mouse capture and rendering is about 16.66 milliseconds. And the elapsed time between user action and rendering will vary between 16.66 and 33.33 milliseconds, meaning an average of 25 milliseconds latency. Depending on your display device there is additional delay for the image to reach your eyes, but you can’t easily control that.

So here is my first, general tip: always read the user input as late as possible in the game loop.

Now if your game can run at 74 fps, rendering still happens at 60 fps but it only takes 13.51 milliseconds to perform all your operations. Since the engine and the renderer are not synchronised, delay will be erratic and you will sometimes get reduced input latency, and sometimes increased latency. In average the latency will be smaller but you will get stuttering.

My suggestion to get the best of both worlds: if you can render faster than 60 fps, use vsync anyway to reduce input latency, even if this implies doing nothing: if your calculations need 13.51 milliseconds but your rendering needs 16.67, you can reduce input lag by about 3 milliseconds simply by sleeping at the beginning of the frame.

This can be tricky. If you miss the vertical refresh, your frame will be delayed 16.66 additional milliseconds. A self-calibrating heuristic to activate or deactivate this mechanism seems like a good option to me.

share|improve this answer

A few options:

120 Hz logic rate:

Fits the common 60 Hz displays nicely, and is fast enough that any possible issues will be minor.

Ludicrous logic rate:

If only your logic rate is high enough you won't have any visible issue. The downside is of course that it cost a lot of processing power.

Rendering interpolation or extrapolation:

Gameplay wise a logic rate of 20 or 30 Hz will suit most RTS games just fine. (Though you can go higher if you find that to be an advantage.) When rendering you just have to take into consideration how old the logic frame is and apply a proportional fraction of the objects velocity to the position for rendering.

In pseudocode:

[rendering position] = [logic position] + [velocity] * [logic frame age]
share|improve this answer
    
I've tried all of those options and unfortunately they didn't help much. I'll update my question with some of the data I got. –  sythical Aug 10 '13 at 15:29
    
@sythical There is not a lot you can do if there is a frame skip, screen content will remain the same until next update. What happens if you turn vsync off? What framerate will you get? And does it stop the jitter? –  eBusiness Aug 10 '13 at 16:03
    
If I keep vsync on, everything is smooth and I get 60 fps. If I turn it off, it's above usually around 70 to 110 but isn't smooth anymore. I've been told that it's a bad idea to rely on vsync which is why I'm looking for other solutions (if they exist). –  sythical Aug 10 '13 at 16:15
    
@sythical How much not smooth? A little jiggeryness is to be expected when vsync is off. And just to be clear, you shouldn't rely on vsync to keep the pace of the game, but it is completely fair to ask you users to have vsync on if they want the best possible experience. –  eBusiness Aug 10 '13 at 19:22
    
If the camera is moving towards the right, it'll periodically jump forward. I'm not relying on vsync to control the speed of the game, just to make it look smoother. I'll just keep vsync on and hope the user doesn't turn it off. Thanks :) –  sythical Aug 11 '13 at 1:18

The Fix your timestep article is about physics, not graphics, for the most predictable result you'll need a fixed timestep, but for the smoothest animation you'll need to use delta time directly.

Realistically, just enable VSync, there isn't really much of a downside. You don't spend your time calculating something you don't need in the end and you get a constant frame-rate.

share|improve this answer
    
I'm using vsync but I was wondering if there is something that I'm not aware of that may be causing the problem. I've used variable delta time before and tried it again, and the movement is still jerky. I've edited my question. –  sythical Aug 10 '13 at 9:33
    
Of course the answer with the physics fps vs graphics fps is to separate the two and interpolate between 2 physics steps to get the graphics position –  Richard Tingle Aug 10 '13 at 9:39

You shouldn't move anything in game by a fixed amount each frame. You should multiply all movement by delta time which is usually found (or estimated) by measuring the amount of time since the previous frame. Edit : I just went through the article and now I'm confused as to what you're problem actually is.

share|improve this answer
    
I think the problem will exist even if I use variable time steps. If there are 70 frames per second and an object is moving at a constant speed, it will move (almost) the same amount of pixels each frame. If 20 frames are dropped, the object will appear jumpy. I just changed my code to use delta time instead and it looks the same. I've edited my question based on your suggestion. –  sythical Aug 10 '13 at 9:31
    
@sythical For smooth appearance, you either need to update your game state at least as often as you display it, or display an interpolated (or extrapolated) game state based on the closest available game state(s). –  congusbongus Aug 10 '13 at 11:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.