• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Hanksha

Advice to lock frame rate

11 posts in this topic

Hi!
 
I'm on a project of a 2D platform action game (it's my first "ambitious" project, I've just been able to finish mini game) code in C++ with SDL2.
 
I need some advice about how to lock the frame rate (by lock I understand that it's lock for frame rate to go higher but not lower). 
On my game the movement of the player is frame based, 6 pixel per frame (or 8 pixel when running), I've not been able to understand correctly the time based movement (At least to understand enough to write my own code), I thought to lock frame rate is my best solution. The game will not be graphically heavy so I guess it will not be a big deal since most of the computer could run it.
 
I've been able to write the following code:
 
- My game loop:

#define FRAMERATE 60

void CMain::GameLoop()
{
    while (windowEvent->GetMainEvent()->type != SDL_QUIT)
    {
    timerFps = SDL_GetTicks();


    windowEvent->Begin();


    SDL_GetMouseState(&MouseX, &MouseY);


    Player->Update();
    environment->Update();


    environment->DrawBack();
    environment->DrawFront();
    
    Player->Draw();

    windowEvent->End();
    
    timerFps = SDL_GetTicks() - timerFps;

        if(timerFps < 1000/FRAMERATE)
        {
            SDL_Delay((1000/FRAMERATE) - timerFps);
        }
    }
}

 Detail of functions used:

void CWindow_Event::Begin()
{
    SDL_PollEvent(mainEvent);
    SDL_RenderClear(renderer);
}

void CWindow_Event::End()
{
    SDL_RenderPresent(renderer);
}

When I check my frame rate with other tools, it indicates a fps around 65 (not steady), I notice on other 2D game (e.g Rogue Legacy or Spelunky) the frame rate is really stable 60.
So I guess there is something wrong in my code, and maybe it will look horrible for some of you. What should I change?
 
(ps: I have many question on other topic related to my project, should I open a topic for each or put everything in here?
pps: Sorry for my english, it's not my mother tongue.)

0

Share this post


Link to post
Share on other sites

On any platform you could control the rate of update and render with this simple algorithm

 

float dt; //delta time in seconds

float clock; //last time sample in seconds

float render_timer; //time control for rendering

 

dt = 0.0;

render_timer = 0.0; //init the render timer

clock = getTime(); //API callback to get the current time in seconds

 

while(true) //game loop

{

   dt = getTime() - clock; //get the current delta time for this frame

   clock = getTime(); //updates the clock to check the next delta time

 

   update(); //update stuff;

 

   if(render_timer >= (1.0f/60.0f)) //checks if the frame is ready to render

   {

      render(); //render your stuff

      render_timer -= (1.0f/60.0f); //do not set to zero, remove the accumulated frame time to avoid skipping

   }

 

   render_time += dt; //updates the render timer

 

}

0

Share this post


Link to post
Share on other sites

I never understood why ppl would lock their framerate manually rather than letting vsync do it's job...

0

Share this post


Link to post
Share on other sites

On any platform you could control the rate of update and render with this simple algorithm

...

Can somebody explain why this is downvoted?

2

Share this post


Link to post
Share on other sites

On any platform you could control the rate of update and render with this simple algorithm
 

 

 

I think I'm doing pretty much the same:

#define FRAMERATE 60
int timererFps;

while (true)
    {
        timerFps = SDL_GetTicks(); // SDL_GetTicks() gives the number of milliseconds since the program start.
                                   // I initialize the timer.

        update(); //update stuff...

        timerFps = SDL_GetTicks() - timerFps; //I get the time it took to update and draw;

        if(timerFps < 1000/FRAMERATE) // if timerFps is < 16.6666...7 ms (meaning it loaded the frame too fast)
        {
            SDL_Delay((1000/FRAMERATE) - timerFps); //delay the frame to be in time
        } 
        render(); // render stuff...
    }

Am I not correct?

 

ps: I just noticed I was rendering before to delay, I correct it, now I'm around 58fps.

 

 

 

 

I never understood why ppl would lock their framerate manually rather than letting vsync do it's job...

 

Because I don't know how to enable vsync with SDL2 I didn't see such thing.

0

Share this post


Link to post
Share on other sites


I think I'm doing pretty much the same

 

I think yours and eduardo's are different. Your algo will update, render and wait some time as filler to make it 16 millisec per frame (1 update per render with waiting), while eduardo's will update multiple times until 16 millisecs or more has passed before rendering (one or more updates per render without waiting).

 

For more information, look at the article Fix your timestep! on the internet, it talks about various kinds of game loops.

2

Share this post


Link to post
Share on other sites

Ah thank you I understand the difference, so are they equivalent or the one of eduardo is better to implement?

0

Share this post


Link to post
Share on other sites
Because I don't know how to enable vsync with SDL2 I didn't see such thing.

 

I never used SDL, but judging from that post and my opengl experience, i guess you didn't use double buffering. Double buffering will remove any tearing effect on fast moving scenes, and lock your framerate for you as a bonus by default.

Edited by Vortez
2

Share this post


Link to post
Share on other sites

Ah thank you I understand the difference, so are they equivalent or the one of eduardo is better to implement?

 

 

With frame based movement, they are most definitely NOT equivalent.  Quite the opposite, actually.  Multiple updates will cause multiple frame-based moves in a single 'frame'.  With frame based movement, you want only a one to one ratio of updates and renders.

 

Your fps fluctuations are possibly due to the precision of SDL_GetTicks, which is inadequately documented.  The precision of this call is platform dependent, but may be as poor as 10ms, which would prevent you from precisely locking down your framerate.  Even at it's documented 1ms accuracy you'll have trouble precisely locking down your framerate as the difference between 60fps and 65fps is only a bit over 1ms (16.66ms per frame vs 15.38ms per frame).

 

The real solution is to take the time and learn time based movement and get away from frame based movement.  Otherwise, look at using a sub-ms resolution high performance counter, which is going to be very platform dependent.  On Windows, look at QueryPerformanceCounter/QueryPerformanceFrequency.

1

Share this post


Link to post
Share on other sites

 

Because I don't know how to enable vsync with SDL2 I didn't see such thing.

 

I never used SDL, but judging from that post and my opengl experience, i guess you didn't use double buffering. Double buffering will remove any tearing effect on fast moving scenes, and lock your framerate for you as a bonus by default.

 

 

I think I found the better way, looking at the function SDL_SetVideoMode (which I think doesn't exist in SDL2) I notice a flag that I didn't see before SDL_RENDERER_PRESENTVSYNC , I just add it to my renderer creation function:

 

renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

 

Now the fps is stable 60. (But I wonder if this vsync can be still disable by the user)

 

So I guess now my best call is to really work on time based movement.

 

Thanks everyone for the help!

0

Share this post


Link to post
Share on other sites

 

I think I found the better way, looking at the function SDL_SetVideoMode (which I think doesn't exist in SDL2) I notice a flag that I didn't see before SDL_RENDERER_PRESENTVSYNC , I just add it to my renderer creation function:

 

renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

 

Now the fps is stable 60. (But I wonder if this vsync can be still disable by the user)

 

 

This is a bad idea. If your movement rate is based on fps. Enabling vsync will not do what you want. This is because vsync is not quaranteed to be 60hz. It depends on your gpu and display and settings. If you have a 75hz or 120hz display and your gpu supports it and have it enabled then with vsync your game will run at 75fps or 120fps. Or even worse if you are using a 1080i tv as a screen with 30hz progressive setting it will lock the fps to 30. And as you had already guessed users indeed can disable vsync from the driver settings.

 

You really need to use high preformance timers. Either by forcing updates to 60hz or adjusting movement rate with deltatime.

Edited by PunCrathod
0

Share this post


Link to post
Share on other sites

The purpose of multiple updates before rendering is splitting work in different steps before the render callbacks.

In a more hi-level solution, one could use different time-slices for different tasks and optimize the loop for a given application.

 

Like:

 

0ms                                              X ms                        16ms

Input Animation Update Physics                 Rendering Flush

 

Also, locking the rendering code in 60fps will avoid calling API commands like clear, shaders, swapbuffers, texture binding, ... in a rate greater than it is needed.

I had a great change in perfomance when I reduced the rate of calling of these commands.

In a worst case scenario locking at 40 or 30fps gave me more time to update other non-rendering stuff and the application performed even better!

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0