I don't understand why this stutters?

Here are two game loops… one is of my creation, the other is the game loop from Minicraft

I can’t figure out why my update’s “stutter” and his are super smooth…

Here’s mine:


	public static final long nano_milli = 1000000L;
	public static final long nano_sec = 1000000000L;
	public static final long milli_per_sec = 1000L;
	public static final long ups = 32;

	long update_frame = 0;
	long update_frame_length = (milli_per_sec / ups) * nano_milli;
	private void gameLoop2() {
		while (running) {

			now = System.nanoTime();

			while (update_frame + update_frame_length <= now) {
				update();
				update_frame += update_frame_length;
			}
			
			render();
			try{ Thread.sleep(2); } catch(Exception e) {}
		}
	}

Here’s his:


	private void gameLoop() {
		long lastTime = System.nanoTime();
		double unprocessed = 0;
		double nsPerTick = 1000000000.0 / 60;

		while (running) {
			long now = System.nanoTime();
			unprocessed += (now - lastTime) / nsPerTick;
			lastTime = now;
			boolean shouldRender = true;
			while (unprocessed >= 1) {
				update();
				unprocessed -= 1;
				shouldRender = true;
			}

			try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }

			if (shouldRender) {
				render();
			}

		}
	}

Hello there :slight_smile:
I’m not sure if it’s legal to post that code… I mean, it has copyrights, right?

It’s legal. The source is freely available.

I think Notch released it as open source

The legality of Minicraft’s source is a nice conversation and all, but could we answer my question? I could have said it was from a friend and you’d have no idea it came from Minicraft, therefore its origin is irrelevant.

Thanks!

Your loops runs at 32FPS while his runs at 60FPS :wink:

In your code, the main inaccuracy I see is that you divide milli_per_sec by ups then multiply by nano_milli. It would be much more efficient and would result in more accurate update if you just divide nano_sec by ups.

In Notch’s code, that “shouldRender” variable looks useless because it’s always true, unless he has a bug where it should be set to false at first, only to be set to true when update() is called.

I never liked Notch’s loop. It is way too inaccurate due to counting by ‘ticks’ (unprocessed) instead of nanoseconds or milliseconds.

Ok, even at 60 FPS mine still has a “jump” every second or so it seems;

His shouldRender variable is actually useful because there are some stages of the loop where no update is necessary, therefore nothing is rendered;
It is set to false at the beginning of every loop, and if the math works out a certain way, shouldRender isn’t set to true;
It’s kind of tricky;

Anyways, I am using his loop with success for the time being;
It’s for a roguelike, so I don’t really need interpolation;

Oops you’re right, it is always set to true;

I think its supposed to be declared as false until proven true. I tried it and it worked;

I did what you said about changing the calculation and it fixed the problem! Wow thanks!

Setting shouldRender to false after updating just caps the game at 60 FPS. The only reason it is never set to false is because Notch forgot to change it; he kept it true to see how fast the game ran while he was coding it.

Honestly, I wouldn’t use Notch’s game loop from Minicraft as an example. It was created in a haste since he had a time limit of 48 hours when making Minicraft. There are plently of amazing game loop example on the forums here, just look in the “Articles and tutorials” section. :smiley:

That’s because you were losing 2/3 of a millisecond due to your innacurate calculation :slight_smile:

@Screem, you mean setting it to false on line 10, right before the while loop, and then setting it to true when updating :wink:

I have spent a week on game loops and ended up with either stuff I couldn’t understand (so I will not use it until I understand it, because I’m not learning),
or stuff that just either didn’t work or was too complex to get working in my lack of understanding…

I think the loop here is fine and simple for what I am doing. I am fine with strict limitations as well.

That said, I do agree that his loop was made in a hurry and probably isn’t that great. I’ve seen a lot of stuff on the web, and even own quite a few books about it… the truth is I’m still not very satisfied with what I’ve found. The only book that comes close is Killer Game Programming, but his end solution tries to sleep for some calculated amount of time which ends up being completely an unreliable amount of time slept.

if unprocessed isn’t greater than or equal to 1, then shouldRender will remain false (when the code is fixed)

Correct.

Check out Riven’s super simplified game loop and super accurate sleeping method..

Is there any way to use that without LWJGL?

My game runs as a JFrame and as an Applet with no dependencies.

Of course, just rip out that Sync class and don’t forget to include the license :slight_smile:

I am concerned about…


import org.lwjgl.Sys;
...
	private static long getTime() {
		return (Sys.getTime() * NANOS_IN_SECOND) / Sys.getTimerResolution();
	}

Hmm that looks useless. @Riven, what’s the point of multiplying by 1e9 then dividing by 1e9? That just returns Sys.getTime() :stuck_out_tongue:

EDIT: That looks like it could be a bug Riven, since it might overflow when multiplying by 1e9!

@Joey, just replace that with “return System.nanoTime()” for now.

Hey, I’m reading “MINIcraft” now, but earlier I questioned about being legal to post that, because I read “MINEcraft” (facepalm).
To clarify, MINIcraft’s code is open to everyone.
Sorry for my previous post if I offended anyone :slight_smile:

haha! That’s pretty close to the troll notch pulled on everyone.

One of the last secrets in the game MINECRAFT was a 1 and some-thousandths chance of it saying “MINCERAFT” at the title screen.

A lot of people didn’t catch it until he said something about it!