The game loop

Hey guys! its been awhile 8)
So lets get into the meat of the problem as the title mention
I still didnt get it about making good game loop and heres the project

https://github.com/hadezbladez/DodgeThis_project/tree/master :point:

and heres the code

private void gameLoop(int loopingPreferences){
	long now = 0; long lastTime = System.nanoTime();
	long deltaTime = 0; long deltaFixComb = 0; long nanoSecond = 1000000000l;
	threadSleeping(1);

	while(running){
		if(loopingPreferences == COMBINE_updateAndRender){
			now = System.nanoTime();
			deltaFixComb += ((now - lastTime) * fps) ;
			lastTime = now;
			systemControls(); //<< this thing handle the input from system or controller
			
			if(deltaFixComb >= nanoSecond){
				updateMechanism(loopingPreferences, 0);
				renderMechanism(loopingPreferences, 0, false);
				deltaFixComb -= nanoSecond;
			}
			
			if(loop_memoryProcess_Model == memorySafe){threadSleeping(1); Thread.yield();}//<< doesnt cause frameRate drops
			threadSleeping(1);
		}
		else if(loopingPreferences == LIMITupdate_MAXIMUMrender){}
		else if(loopingPreferences == SEPARATE_updateAndRender){//using this does change fps
			//timings
			now = System.nanoTime();
			deltaTime = now - lastTime;
			lastTime = now;
			systemControls();
			
			updateMechanism(loopingPreferences, deltaTime);
			renderMechanism(loopingPreferences, deltaTime, false);
			
			if(loop_memoryProcess_Model == memorySafe){threadSleeping(1); Thread.yield();}//<< optional and causing frameRate drops
		}
	}
	
}

yes, i make the game loop that doesnt catch any decimal point. at first, I thought that thing are making the game lags but, it still didnt solve anything. The green box still can get jaggy and it did look like something was off. Was the problem the render itself, my computer specification, that was the limit of java or something? i dont know. at this point, i dont have any idea fix the jaggy box thingy ??? ??? ??? ??? ???

Sleep is very inaccurate depending on your operating system, if you really want very accurate sleep you need to spin-wait for the last few milliseconds. You probably don’t need sleep that accurate for your game though, but i added this method anyway so you can try it out.

And simplify some stuff, don’t over-complicate your loop, use some proper formatting, etc.

This is how a simple but accurate version could look like.

	private void gameLoop() {

		// http://lmgtfy.com/?q=1s%2F60+in+nanoseconds
		// The ideal time for one iteration of the loop in ns
		long tLoop = TimeUnit.SECONDS.toNanos(1) / fps;

		// The timestamp of the beginning of the loop in ns
		long tBegin;
		
		// The time that was spent in the previous iteration of the loop in ns
		long tDelta;
		

		// remember to make running volatile if you change it from another thread!
		while ( running ) {
			
			// We need one measurement at the beginning.
			tBegin = System.nanoTime();

			systemControls();

			updateMechanism(tDelta);
			renderMechanism(tDelta, false);

			// Sleep for the duration of the frame minus the time already spent rendering/updating.
			try {
				sleepNanos( tLoop - ( System.nanoTime() - tBegin ) );
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
			
			// The actual loop time can be calculated now as we have finished the loop.
			tDelta = System.nanoTime() - tBegin;
		}
	}

	// The accuracy of your sleep method could be around ~3ms - try some values!
	final static long SLEEP_PRECISION = TimeUnit.MICROSECONDS.toNanos(2500);
	
	// The approximate time it takes to return after yield, should be very small.
	final static long SPIN_YIELD_PRECISION = TimeUnit.MICROSECONDS.toNanos(500);

	// This will sleep if far away and spin near the target time, depending on your settings above.
	// Visit https://stackoverflow.com/a/2986919 for the source of this method and further info!
	public static void sleepNanos (long nanoDuration) throws InterruptedException {
		
        final long end = System.nanoTime() + nanoDuration;
        
        long timeLeft = nanoDuration;

        do {
            if (timeLeft > SLEEP_PRECISION)
                Thread.sleep (1);
            else
                if (timeLeft > SPIN_YIELD_PRECISION)
                    Thread.yield();

            timeLeft = end - System.nanoTime();
        } while (timeLeft > 0);
    }

TimeUnit outputs long values, do not use it to convert nanoseconds to milli/seconds, you’ll loose precision.

Check out this explanation of the effects of Thread.yield() vs Thread.sleep(): https://stackoverflow.com/questions/11480912/thread-sleep-or-thread-yield

If you really want to uncouple rendering and updating you need to do much much more work than this, they basically aren’t uncoupled (meaning: they don’t block each other) as long as they are running in the same thread. Don’t try it until you understand multi-threading and synchronization well enough, the gain to cost ratio is very low for a small game.

To enhance the waiting mechanism further you could use the previous delta value to fine-tune the next sleep cycle, but it should be good as it is right now. Another thing you could do is add some limits and checks to the values, to make sure times don’t go negative or super large.

I use sleep when for debugging since it takes less CPU usage on task manager and yes it might be the problem i try its not that thing that can get laggy.
Yes, i think my game-loop is too complicated i will manage it.

Thanks for the idea about a game loop ;D

In case you didn’t get the memo … i didn’t post this so you can be inspired ::slight_smile: this is so you can try out the clean version and see if your issue persists.

If this doesn’t fix it you have a problem elsewhere, maybe with vsync or with the code you use to move your box object.

A long time ago we had posts about a hack that would kick the clock into a higher gear, getting around the rather large granularity of the default clock used by Windows OS. Does this still pertain? Or has Microsoft upped the granularity of their default system clocking? It seems to me that Windows is now fine in this regard.

[Found this: http://www.java-gaming.org/topics/thread-sleep-in-gameloop/36423/msg/345479/view.html#msg345479]

For me, I’ve always preferred using timers. The “game loop” becomes a “TimerTask” or equivalent that is called repeatedly.

Even as far back as “Killer Game Programming in Java” the authors conceded that using the util.Timer (but NOT the Swing.Timer!) was as performant as the sleep methods being described.

Goetz’s “Java Concurrency in Practice” makes a good case for using ExecutorService in place of util.Timer. For non-JavaFX programs, this is my go-to choice. Among other benefits, you can configure the timer to execute as close as possible to the desired timing interval (i.e., it tries to correct itself if an iteration takes longer than it should).

My top preference is the JavaFX AnimationTimer. It is simple, clear, easy to code and works perfectly well imho. A drawback for some will be that it is set to 60 fps and I don’t know of any way to change that rate. But with so many monitors still refreshing at 60fps, I’m not clear what is gained by a faster game-loop rate that couldn’t be implemented at 60fps.