[solved] Updating & Rendering in a timely fashion

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.

Thank you :slight_smile:
And not to be rude :slight_smile: but that link’s been posted earlier in this threads page XD

Thanks for your feedback though (:

[quote]using Swing or other “timers” is fine. all of them use System.sleep(1) anyway.
[/quote]
@basil_
Well, sort of. The util.Timer relies on native code implementing Object’s wait(long) method. It is set to a value that corresponds to the schedule of the next TimerTask on its internal queue. Thus the wait is probably larger than 1.

Thread.sleep(1) uses native code for sleep(long).

But both do make use of the System Clock which is either limited by larger of the granularity of the milliseconds input parameter, or by the minimum interval at which the clock is updated (about 16 millis for some older Microsoft OS).

I don’t think the util.Timer adds much in the way of overhead. The most significant addition is a very nifty queue implementation set up for the TimerTasks (I think it’s set to a simple array of 128 unique tasks), but it is a model of efficiency (written by Joshua Bloch). I would guess having a single wait(long) is probably better than multiple calls to sleep(1). But these are quibbles to your main point.

yes, that’s what i ment. on windows we’re stucked at 15-16 ms. no selfmade native can help here, System.nanoTime() already is.

at least instead of Thread.sleep(1) we can use

LockSupport.parkNanos(500000); // 0.5 ms

what works pretty good on linux.

anyway, that’s low level. for high level most java utils are useful in the end.

There is no specific reason or objection, but I don’t like them. I would like to quote Eli Delventhal’s Game Loops article.

That’s the only reason why I don’t like those Timers in game loops. Hope this helps.

If you’re going to use a Timer for the convenience, you might as well use a ScheduledExecutorService:


ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

scheduler.scheduleAtFixedRate(() -> {
    update();
    render();
}, 0, 16, TimeUnit.MILLISECONDS);

I still wouldn’t do this for a game however, as you cannot control what happens when update() and render() take more than 16 ms.

@SHC
I always found that quote from Eli to be very puzzling. So, util.Timer was not intended for heavy-lifting? How can a person tell this? It’s just code. Nothing in the API warns about this, nor anything in Joshua Bloch’s well-documented source code for the class. Code in the TimerTask runs the same as code in a game loop, as far as I can tell, though they rely on different native routines (wait vs sleep).

@BurntPizza
…doesn’t the exact same thing happens when update() and render() take more than the allotted time: the next iteration simply gets pushed back? This is the same with the ScheduledExecutorService (as you configured it), with util.Timer and with a game loop. Yes?

But if the NEXT iteration after that takes less than 16 millis, with either the scheduler or timer’s .sheduleAtFixedRate(), an attempt to recover the lost time, gratis, no extra coding needed.

I suspect that the poor reputation util.Timer has vs. coding one’s own timing mechanisms into game loops has an element of “herding behavior” to it or some sort of echo chamber effect. I have yet to read one rational explanation or see a concrete example that justifies the preference. I point out again, even “Killer Game Programming” from way back when gets the same performance with util.Timer as with their preferred game loops, and then says well, we are going to stick with writing our own game loops anyway. (The book does an excellent job of demolishing the swing.Timer, though!)

But this is okay. It probably doesn’t make a bit of difference, and my harping on this is an example of I don’t know what. I certainly don’t want to try and tell other people they should convert their game loops to TimerTasks.

How is a fixed time step not reliable? It’s the same idea but you never sleep the thread.

Edit: I suppose if you sleep the thread then you aren’t wasting cpu time doing nothing. Also, my bad reposting the link.

in a rendering loop a fixed timestep/sleep-duration is not taking the “payload” in count.

you might get a stable sleep but it would add to the cpu-time spend updating and rendering things.