3
\$\begingroup\$

I've got a serious issue with my game loop. This loop varies in time with the platform and with the same hardware. This is a list of FPS achieved:

  -  Windows       ======= 140 to 150
  -  Linux         ======= 120 to 125
  -  Windows(WINE) ======= 125 to 135

And since my game loop is fixed timestep, the speed of the game is not stable. Here's my game loop.

public final void run() {
    // Initialize the resources
    Map.initMap();
    initResources();
    // Start the timer
    GTimer.startTimer();
    GTimer.refresh();
    long elapsedTime = 0;
    // The game loop
    while (running) {
        // Update the game
        update(elapsedTime);
        if (state == GameState.GAME_PLAYING) {
            Map.updateObjects(elapsedTime);
        }
        // Show or hide the cursor
        if (Global.HIDE_CURSOR) {
            setCursor(GInput.INVISIBLE_CURSOR);
        } else {
            setCursor(Cursor.getDefaultCursor());
        }
        // Repaint the game and sync
        repaint();
        elapsedTime = GTimer.sync();
        Toolkit.getDefaultToolkit().sync();
    }
}

The timer package

How could I improve it?

\$\endgroup\$
6
  • \$\begingroup\$ I don't get it...You say the speed of the game is not stable, but your functions receive the elapsed time... So for instance, if animal A walks 1 unit per second, and you run update(2), it walks 2 units. It walked 2 units in 2 seconds which makes it walk 1 unit per second. If you give update function the argument 3, the speed would be the same, so what Am I missing here? The game logic shouldn't be running at a constant speed? \$\endgroup\$
    – jmacedo
    Sep 30, 2012 at 2:49
  • \$\begingroup\$ yes. The game is running much faster on windows and very slow on linux \$\endgroup\$ Sep 30, 2012 at 3:00
  • \$\begingroup\$ when you say faster, are you refering to the game logic or the FPS ? \$\endgroup\$
    – jmacedo
    Sep 30, 2012 at 3:06
  • \$\begingroup\$ the faster is both \$\endgroup\$ Sep 30, 2012 at 3:19
  • 2
    \$\begingroup\$ I added an answer, thought I'm not really sure if it is what you wanted. About different FPS in different platforms, it probably has to do with the drivers being more optimized in different platforms, and also the way each OS deals with memory / threads / etc. \$\endgroup\$
    – jmacedo
    Sep 30, 2012 at 3:48

2 Answers 2

5
\$\begingroup\$

There is an excellent article here about this subject: http://www.koonsolo.com/news/dewitters-gameloop/

Normally I update my game in the same way for every update call. I have the speed at which things happen measured in terms of game loops elapsed (if you choose to update your game the same number of times per second you can still measure speed of things in time with some basic math)

The best of the simple ways (i.e without interpolation parameters for the display method) to do the game loop is this (I added comments on this code which is from the article):

const int TICKS_PER_SECOND = 50;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 10;

DWORD next_game_tick = GetTickCount();
int loops;

bool game_is_running = true;
while( game_is_running ) {

    loops = 0;
    //Let's update the game... And take note of when we need to update again
    //If there is time left (GetTickCount() < next_game_tick), then we have some spare time to display the game. 
    //But if we are already late, we need to keep iterating the game (GetTickCount() > next_game_tick)
    //However if it is the case that we never are able to get some time to display the scene, 
    //loops variable will end up being greater then MAX_FRAMESKIP (loops > MAX_FRAMESKIP)
    //At this time we really need to show the user how is the game going.. (He couldn't see it for 10 iterations!), 
    //so the loop is 'broken' and we get to display the game
    //This is an exceptional situation where the game logic will start to slow down
    //until now game logic kept the same speed and only FPS could change
    while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
        update_game();

        next_game_tick += SKIP_TICKS; //We take note on when to update again
        loops++;
    }

    display_game();
}

You should really read the article for more detailed information, it is really good. Also, take into attention that in these code samples, update_game() makes the game do the same amount of progress every time it is called, whereas in your code, update_game(elapsedTime) makes the game progress more if more time has elapsed since last update. You will probably be better with the first approach if you use the model described in this answer.

\$\endgroup\$
2
  • \$\begingroup\$ The fact that the question title changed makes this answer look like it doesn't belong here... \$\endgroup\$
    – jmacedo
    Sep 30, 2012 at 4:05
  • \$\begingroup\$ I changed the title to something closer to what it was originally. Because titles should refelect the problem instead of "how do I fix X?" I think you answer still applies. \$\endgroup\$
    – House
    Sep 30, 2012 at 6:00
3
\$\begingroup\$

Any two OS give different performance based on hardware optimization. Even between Windows 7 and Windows 8 you will see some difference in frame rates. http://www.zdnet.com/windows-8-vs-windows-7-benchmarked-7000002671/

Your game loop speed varies on each different platform for because of various reasons:

  1. The JVM is implemented differently on each OS. It may be using slightly different software to compute the same game logic on a different OS and thus using your HW differently. You can narrow it down b writing generic code that only does computation and data manipulation (benchmark) to see if the issue relates specifically to the rendering or not.

  2. Each one is running different processes in the background.

To see the processes running(Windows):

  1. press Ctrl + Alt + Delete
  2. Click on 'Start Tast Manager'
  3. Click on 'Processes'

To see processes in Linux:

  1. open a shell (for instance run xterm)
  2. type 'ps a' and press Enter.

This issue with frame rate should not influence your game design. Why not adjust the movement of units in your game to compensate for the varying speeds?

If you mean that it is running at 140~ FPS in Windows and 120~FPS in Linux it is beyond optimization imho. You should normally stick with a lower than max fps cap, for the game to run smoothly at a steady speed. For instance if you think your game could run on speeds of 60 - 80 fps on the average user's computer, cap it at 60. Generally I try to calculate to the optimal fps for each machine my game runs on or decide, it should cap at a certain speed where anything lower means the machine is outdated.

Optimal fps is in most cases, the lowest fps during the game. Anything higher, makes the game appear less fluid.

\$\endgroup\$
7
  • \$\begingroup\$ Calling ps a gave the list which contains hard-disks and not processes. \$\endgroup\$ Sep 30, 2012 at 11:11
  • \$\begingroup\$ I use it all the time - here is a link - cyberciti.biz/faq/show-all-running-processes-in-linux \$\endgroup\$
    – AturSams
    Sep 30, 2012 at 11:23
  • \$\begingroup\$ My distro is something other. (Comice 4). It's showing a very less number of processes from the System Monitor \$\endgroup\$ Sep 30, 2012 at 11:27
  • \$\begingroup\$ Wait are you upset because I couldn't guess distro you are using? Does top work on your distro? \$\endgroup\$
    – AturSams
    Sep 30, 2012 at 11:29
  • \$\begingroup\$ No. Only 14% of cpu and 62% of ram. On windows, 25% cpu and 52% ram. \$\endgroup\$ Sep 30, 2012 at 11:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .