[solved] Updating & Rendering in a timely fashion

Hello JGO members, I wanted to create a basic game and I wanted to accomplish the following:
#1: Update (Every 16ms if possible, 16ms = windows minimum cpu time?)
#2: Render (Every 60ms if possible, 60ms = refresh rate)

I don’t know how to go about doing this as the update and render times will vary depending on what is being called in those methods.

If it’s possible I would like to do this on 1 thread, if anyone advises against that please tell me why, and how I should go about doing it? :slight_smile:

Thanks JGO, looking forward to any feedback :slight_smile:

Do you really want to render at 60ms intervals? That’s only 16 FPS.

In regards to decoupled game loops on one thread (read: easiest, safest way): http://gafferongames.com/game-physics/fix-your-timestep/

Thank you, I didn’t even think about that.
I had just read somewhere to repaint upon the screen being refreshed.
Oops, thank you again :o

My game isn’t going to have any physics involved so I don’t know if I should follow through with a fixed timestep/delta time.

What do you think?
(Garden type of game, growing plants, simple animations if any at all ^__^)

You’re confusing refresh rate (frequency) with the time between refreshes. They are the inverse of each other.

60FPS (60 Hz) = 1 / 60 second (1000 / 60 = ~16 milliseconds)

Thank you for that info :slight_smile: I’ll take it into account.

One more question :slight_smile:

I didn’t want to jam up my application and overwork it by doing the following like so (pseudo-code):


while (condition) {
    update();
    render();
}

Should I involve a minimum sleep time?
Possibly update/render at a fixed rate?
(Once again, no physics involved :o)

I’m just stuck XD
Thanks for any help, overlooking the page you posted now.

Yes, as it stands that loop runs as fast as it can, which will be different for different things happening in the update and render methods, and even across different computers.

Try this:


int desiredFPS = 60;

long nanosToSleep = 1000000000L / desiredFPS;

while (condition) {
    long startTime = System.nanoTime();

    update();
    render();

    // wait until it's time to do next frame, making sure it's been nanosToSleep since we started this frame
    while(System.nanoTime() < startTime + nanosToSleep)
        Thread.sleep(1);
}

Where you said:

I don’t quite understand o:
If you have the time could you explain what’s happening?

Is it waiting just to be in sync & call the ‘update/render’ @ 60 times a second?

__< Sorry if I’m a newb XD

int desiredFPS = 60;

//  amount of time between frames that corresponds to desiredFPS
long nanosToSleep = 1000000000L / desiredFPS;

while (condition) {
    //  what time is it right now (start of this frame)
    long startTime = System.nanoTime();

    //  do game stuff, this will take an unknown and possible varying amount of time
    update();
    render();

    //  it is now some time after startTime, but, assuming we're not behind schedule
    //  (update and render aren't too slow), we still have time until the next frame
    //  should be started.

    // so we...
    // wait until it's time to do next frame, making sure it's been nanosToSleep since we started this frame
    while(System.nanoTime() < startTime + nanosToSleep)
        Thread.sleep(1);

    //  it has now been nanosToSleep time since we started this frame, loop back and do the next one
}

Thanks alot :slight_smile:

Going to implement a FPSCounter and see how the framerate is.

Thanks for everything BurntPizza, but I seem to only be getting 59 frames per second?
NOTE: The update/render methods are empty at the time being.

Is this normal or did I not program my fps counter correctly?


	protected static void startGameThread() {
		gameThreadRunning = true;
		gameThread = new Thread() {
			@Override
			public void run() {
				super.run();
				frameStartTime = System.nanoTime();
				while (gameThreadRunning) {
					final long startTime = System.nanoTime();

					if ((System.nanoTime() - frameStartTime) / 1000000 >= 1000) {
						fps = frames;
						frames = 0;
						System.out.println("FPS: " + fps);
						frameStartTime = System.nanoTime();
					}

					// Update
					update();

					// Render
					render();
					frames++;

					while (System.nanoTime() < startTime + nanosToSleep) {
						try {
							Thread.sleep(1);
						} catch (final InterruptedException e) { }
					}
				}
			}
		};
		gameThread.setName("GameThread01");
		gameThread.start();
	}

Thanks for any feedback :slight_smile:

It’s probably truncating and you’re actually getting 59.999 fps.

Also remove the if frameStartTime==-1 statement. You’re causing an unnecessary branch every frame. Just in it frameStartTime to nanotime before you enter the loop.

Thanks, I’ll see if its truncating. :slight_smile:

EDIT: It’s not truncating the frames :confused:


FPS: 50.0
FPS: 59.0

In this section:


    while (System.nanoTime() < startTime + nanosToSleep) {
        try {
            Thread.sleep(1);
            } catch (final InterruptedException e) { }
        }
    }

…I’m not sure the Thread.sleep(1) command actually does what one thinks it should consistently on all systems. The sleep command depends on the system clock, which is a different time source than that of System.nanoTime(). (API for nanoTime() and Thread.sleep() elucidates this.) If you are on an old version of Windows, it might actually be sleeping longer than that.

Can also try the following:


// import java.util.Timer
// assumes also a reference to the "game"

    Timer timer = new Timer();
    TimerTask task = new TimerTask();

    timer.scheduleAtFixedRate(task, 0, 16);   

    class GameLoopTask implements TimerTask
    {
        game.update();
        game.render();
    }
}


It might be interesting to put in a counter to check the actual frame rate and compare.

Thanks :slight_smile:

Actually ended up using the TimerTask for the first time to repaint a few panels on my Main Menu in the background.

Never, Never use Timer and TimerTask for game loops, they are mainly designed with Swing in mind and may not work well for a gameloop. A decent game loop should run as fast as it can, decoupling logic and rendering. (Don’t go multithreading yet, that sounds nice in the start, but cause a lot of troubles if written incorrect)

I use a Fixed Timestep GameLoop and I set it up like this.


public void run(int desiredUps, int desiredFps, int frameSkip)
{
    long now = System.nanoTime();
    long logicTime = System.nanoTime();
    long renderTime = System.nanoTime();

    long frameLogicTime = 1000000000 / desiredUps;
    long frameRenderTime = 1000000000 / desiredFps;

    int skippedFrames = 0;

    while (true)
    {
        if (Display.isCloseRequested())
            break;

        now = System.nanoTime();
        skippedFrames = 0;

        while (logicTime + frameLogicTime < now && skippedFrames < frameSkip)
        {
            update();
            
            skippedFrames++;
            logicTime += frameLogicTime;
        }

        while (renderTime + frameRenderTime < now)
        {
            render();
            renderTime += frameRenderTime;
        }
    }
}

If you use this, make sure that frameskip is atleast 1. I recommend to give a reading to the following articles.

Hope that helps!

[quote]Never, Never use Timer and TimerTask for game loops, they are mainly designed with Swing in mind and may not work well for a gameloop.
[/quote]
SHC – Could you be more specific about your objections to the util.Timer? I’ve never had a problem with them, and there is nothing that I know about them that is specific to Swing. AFAIK, you can put any commands you want in them. You’re not confusing the util.Timer with the Swing Timer, are you? I would agree that the Swing.Timer is not good for game programming due to performance issues arising from the potential EDT bottleneck.

Eventually, one can graduate to an Executor Service with a fixed schedule–that might be slightly preferable. But that would be a lot to learn for a Newbie. Better to get on with entity management, movement physics, collision detection, etc., imho.

I’m only using a Timer/TimerTask to update 2 panels in my MainMenu, it repaints both of them (panel.repaint()) and updates a Integer that handles my scrolling news bar.

I’m handling my GameLoop on a thread :stuck_out_tongue: TimerTask is ran in the background to update versionAndInfoPanel and my HeaderPanel (No logic but newsX–)

using Swing or other “timers” is fine. all of them use System.sleep(1) anyway.

just coming along with more stuff that you dont need for a game-loop. so it’s not “clean” to use them but also totally fine.

on the other hand … imo they’re all wrong. a proper time/clock in java is a pain in the butt. my current approach comes more from measuring and profiling :

public class clock
{
  private double hz; // desired fps
  private double interval; // nanosec
  
  private double delta; // in millsec  
  private double start;
  private double last;
  public double currentHZ; // current fps

  public clock(float desiredHZ)
  {
    this.hz = desiredHZ;
    this.inverval = 1.0e9/hz;
  }

  public void begin()
  {
    start = (double)System.nanoTime();
    delta     = ( start - last )*1.0e-6;
    currentHZ = 1000f/delta;
    last = start;
  }  

  // usually you would use this which yields the same result as using any java Timer class.
  public void end()
  {
    double now = (double)System.nanoTime();
    while(now - start < interval)
    {
      Thread.sleep(1);
      now = (double)System.nanoTime();
    }
  }

  // but to get it more precise we can use Thread.yield()
  public void endYielding()
  {
    double now = (double)System.nanoTime();
    double t;
    while(( t = now - start ) < interval)
    {
      // switch to expensive yield when remaining sleep time is less then a threshold.
      // ideally this would be 1 ms when sleep(1) would actually be a 1 ms sleep, what it never is.
      if(( interval - t ) < 1.4e7) Thread.yield();  // magic number 1.4e7, works for me tho. higher = more precise + higher cpu usage
      else Thread.sleep(1);
      now = System.nanoTime();
    }
  }
}

in a game loop :


public void init()
{
  clock = new clock(45.33f); // 45.33 
}

public void update()
{
  clock.begin();

  // paint things 
  // swapBuffers

  clock.endYielding(); // sleep
  System.out.println("current FPS : " + clock.currentHZ);
}

i’m not able to program a more precise timer in java :frowning:

Since everyone is using Thread.sleep(), which I think looks rather bad, I thought I’d just leave this here…

that’s related to game physics, not to reliable loop frequency.