Go on, ask me anything.

We use vsync as well, and back it up with a hi-res timer yield loop to be sure that vsync is working.

Cas :slight_smile:

Thread.yield() is the smoothest but HOGS the CPU like crazy!!
Thread.sleep(1) is the best tradeoff between smoothness and CPU usage.

I don’t care if it hogs the CPU as my game’s in the foreground. I gave up worrying about laptop battery life a while back.
I do provide a commandline option to use sleep instead, and also, I use sleep on single-core machines as well.

Cas :slight_smile:

can you post some code for this smooth loop?

It’s all here, look in net.puppygames.applet.Game.run().

Cas :slight_smile:

Awesome, thanks Cas.

Your games really are the showcase for Java gaming, and the techniques should probably be “canon” for those of us who want to code silky smooth action games.

What happens if the user’s monitor is set to something other than 60Hz? 75Hz is quite commons for LCD too. Does that affect your loop?

Nothing is affected. It’s just 5/4 of all your frames will be redrawn in the next screen refresh.

Why is there so little love for sleep(0)?

How does it compare to sleep(1) and yield()?
I always thought (guessed) that using sleep(x<5) more or less behaves the same.

Q for Cas…way back on Page 3 you mentioned you use the Server VM. What sort of performance improvement does that offer over the Client VM?

Roughly they mean, taking into account the old saying:

yield: I’m willing to give up the rest of my timeslices for any equal or higher priority thread that’s READY (and sometimes in WAIT) to run on this processor in this process.

sleep(n): I’d done with my timeslices, put me in SLEEP state for n+/-g (where g is the granularity of the used timer) then put me in READY for the scheduler. With sleep(0) special cased to go immediately into a READY state.

The reason I ask is 'cause sleep(0) used to be broken on pthreads and I can’t remember the status. And the JVM might be doing something funky under the hood.

About 20% or so maybe. Hard to accurately measure but it’s noticeable.

Cas :slight_smile:

the previous my question was left without an answer
here i go again:
how much is the fish?

About this much.

Cas :wink:

In my personal experience using ‘yield’ continuously in a loop hogs the CPU from all other threads on non-Vista/Win7 OS’s, including those for sound and other jobs. This is the main reason why I personally advise against it (although I presume Cas is doing something to mitigate that).

Indeed:


if (forceSleep) {
	try {
		Thread.sleep(1);
	} catch (InterruptedException e) {
	}
} else {
	Thread.yield();
}

where forceSleep defaults to true in single-core systems, false for multi-core (but can be overridden on the commandline)

Cas :slight_smile:

Oh wow I have never thought of diving both uses that way! Thanks :slight_smile:

That’s a clever approach, but are you doing that in one loop or in multiple ones? I’d expect if you have more then a couple of threads then you can quickly swamp a multi-core PC too.

In my example I had a thread per playing sound, and it was because of those that I had this issue.

That’s the main loop and the only one that needs to execute glassily smooth; all the other threads in the game use normal thread scheduling techniques. Remote call threads are at lower priority; the sound streaming threads are at higher priority (juddery sound is far more unpleasant than juddery graphics). Dualcore processors of course solve all problems neatly :slight_smile:

Cas :slight_smile: