//If for some reason an update takes forever, we don't want to do an insane number of catchups.//If you were doing some sort of game that needed to keep EXACT time, you would get rid of this.if (now - lastUpdateTime > timeBetweenUpdates) {lastUpdateTime = now - timeBetweenUpdates; }

Saucer, your Slick2D example doesn't make much sense for the idea of Slick IMHO. Way too complicated.

Slick basically works by calling update() and render() in a loop. The time spent between the previous and the current update call is passed in milliseconds as delta. That's it. Update your positions by multiplying with a factor and the delta and you're done.

You can finetune Slick by switching on vsync, setting a target frame rate, delta smoothing, minimal and maximal update time and so on.

But basically I would start simple.

Give the games in my signature a try: they are all done with Slick, the source code to all those games is available on my website or part of MarteEngine. See if they stutter that much that you consider them unplayable or annoying (stuttering wise, not gameplay ).SpiderTrap is completely based on calculations using the delta value. Back to the past and StarCleaner use a target frame rate of 60.

Saucer, your Slick2D example doesn't make much sense for the idea of Slick IMHO. Way too complicated.

Slick basically works by calling update() and render() in a loop. The time spent between the previous and the current update call is passed in milliseconds as delta. That's it. Update your positions by multiplying with a factor and the delta and you're done.

You can finetune Slick by switching on vsync, setting a target frame rate, delta smoothing, minimal and maximal update time and so on.

But basically I would start simple.

Give the games in my signature a try: they are all done with Slick, the source code to all those games is available on my website or part of MarteEngine. See if they stutter that much that you consider them unplayable or annoying (stuttering wise, not gameplay ).SpiderTrap is completely based on calculations using the delta value. Back to the past and StarCleaner use a target frame rate of 60.

Don't overcomplify things - try to get some games done

Cheers,Tommy

Thank you for your advice, Tommy, but I'm specifically trying to avoid using that style of updating. Do you know the distinction between fixed and variable timesteps, or about making the physics framerate independent? I'm trying to implement fixed timesteps (independent physics), and that's (sorta?) what's causing the stuttering.

EDIT: I guess I could try to fix the delta on Slick's terms--- as, after further consideration, I think you may be suggesting--- by using various features such as minimal and maximal update time, but I feel that that would be too indirect; in other words, although the raw code seems more complicated, in the end it sounds to me like trying to incorporate a fixed timestep directly would be a lot simpler than trying to force Slick's internals to make a fixed timestep out of a variable timestep.

Somehow I get the impression that setting both the min and the max to what I want (and thus achieving fixed timesteps?) will be a little less robust than directly doing it myself, but that remains to be seen. Also, I wonder if those functions only take integers...? An update rate of 60 updates per second corresponds to an interval of not exactly 16, nor exactly 17, right... I guess I'll still have to try similar things with LWJGL, but without Slick.

Saucer, I even wrote a tutorial (!) about a gameloop using fixed timesteps for updates and required tweening for rendering.Unfortunately it's for BlitzMax but of course the principle works the same regardless of the programming language (and BlitzMax has most OO features you'd require).

The code can easily be converted to Java and Slick. I would suggest you create your own AppGameContainer subclass where you implement your own game loop using the mechanisms above.I guess this would be the cleanest way to introduce a different update/render behavior into Slick.

Saucer, I even wrote a tutorial (!) about a gameloop using fixed timesteps for updates and required tweening for rendering.Unfortunately it's for BlitzMax but of course the principle works the same regardless of the programming language (and BlitzMax has most OO features you'd require).

The code can easily be converted to Java and Slick. I would suggest you create your own AppGameContainer subclass where you implement your own game loop using the mechanisms above.I guess this would be the cleanest way to introduce a different update/render behavior into Slick.

Hope that helps,Tommy

Ah, my apologies. Thank you for the tutorial! If I remember correctly I've seen this tutorial before, but I didn't look too closely at it because it was for BlitzMax. If I find an opportunity, I'll see if I'll be able to convert it to Java successfully, and report back with results!

So currently I know of at least 10 different versions of the fixed timestep loop--- all from various sources, some of those sources being examples of code that people have submitted here--- so I prepared three different versions of the LWJGL example Cero posted, each of which incorporates one of the different fixed timestep code examples.

I've bundled together those examples in a single download, along with some other example programs (like a similar Game Maker example) and the source for all the different examples. You can download it here: box.com download

Note: example_simple.jar and example_variabletimestep.jar are examples without fixed timesteps; they're there for comparison.

There are various settings you can toggle within the JARs, like vsync and the usage of Thread.yield and Thread.sleep. More details are contained in the included readme file.

Here's what I discovered:

-With certain settings, the stuttering can be improved pretty well on all tested computers (at least one school computer, our desktop, and my laptop).

-Rendering as fast as possible seems to yield fairly smooth graphics, but it seems that our desktop and my laptop have difficulty with that kind of rendering (I can't tell if it's difficult for the computers at my school).

-I finally saw that LWJGL's vsync actually does have an effect, and yields some of the smoothest rendering I've seen yet! (That is, with Java.) ...However, although this smooth rendering was achieved on a computer at school, it doesn't seem to work on our desktop or my laptop. In fact the API documentation for LWJGL says:

Quote

[About Display.setVSyncEnabled:] This call is a best-attempt at changing the vertical refresh synchronization of the monitor, and is not guaranteed to be successful.

That being said, I think at least one particular setting on one example may yield suitably smooth rendering all around: example_delventhal.zip without Display.sync, with yield and sleep, and without frequent yield and sleep. It still stutters with those settings, but, if I'm not mistaken, it only stutters a little more than does the Game Maker example.

Admittedly, I don't know how this setting fares on a computer on which vsync works; it may have to be turned off on such computers. But then again, on such a computer, vsync might yield smooth rendering on its own.

EDIT: I guess it's also possible that the smooth rendering that seemed to be achieved with vsync on the computers at my school could only have been achieved with the speed of those computers (they seem pretty fast).

Just another thing worth mentioning: not all monitors run at 60Hz - some will be 72hz or 75hz etc. This will screw your timing unless you change the display mode to 60Hz.

Cas

Ooh, good point. I think I do know of a way to get the default refresh rate, though; I wonder if that will be enough to accommodate this issue. Also, I found something you posted at lwjgl.org in 2010, Cas; it's contained in the following forum thread:

EDIT: That's strange, for some reason I can't get the link to work... The title of the thread is "Timer Comparison."

Would it be alright if I made a new example (as in, add another new member to my examples download) based (heavily) on your method?

Link worked from me in the email sent by JGO on my Android phone Yeah that's the loop all my games use now. Uses double floating point precision to calculate how many frames it should have ticked at by a given time, resets every now and again for sanity, and vsync takes care of fullscreen timing nicely but otherwise it seems to render nicely enough in windowed mode. I don't care much about windowed mode though. Proper games run fullscreen for that immersive experience

That being said, I think at least one particular setting on one example may yield suitably smooth rendering all around: example_delventhal.zip without Display.sync, with yield and sleep, and without frequent yield and sleep. It still stutters with those settings, but, if I'm not mistaken, it only stutters a little more than does the Game Maker example.

Looks like I spoke too soon:

I had already known that, sometimes, our desktop (which usually yields the most visible stuttering) runs the Java programs I've been testing pretty well for some reason; but only for a while, and in a currently unpredictable manner. Even the Java2D builds run smoothly in this situation! It seems that this had been the case when I was testing my LWJGL examples earlier, because yesterday they seemed to yield lots of stuttering... Looks like I might try to give Cas's method a go!

EDIT:

Quote

Admittedly, I don't know how this setting fares on a computer on which vsync works; it may have to be turned off on such computers. But then again, on such a computer, vsync might yield smooth rendering on its own.

Looks like the program runs just fine under these particular settings, at least as far as I can tell.

By the way: currently, the only way I know how to test if vsync has an effect is to turn off Display.sync (and frequent yielding and sleeping) and see if toggling vsync does anything. On my school's computers the FPS drops from several hundred (without vsync) to 60 (with vsync), whereas on our desktop and my laptop the FPS seems to stay at several hundred regardless of the state of vsync reported by the program.

Also, I'm still not really sure about the following point:

Quote

I guess it's also possible that the smooth rendering that seemed to be achieved with vsync on the computers at my school could only have been achieved with the speed of those computers (they seem pretty fast).

In other words, I don't know if my programs might still yield stuttering on other computers for which vsync has an effect; it could just be that, as usual, the main reason my programs run smoothly on my school's computers is that they're fast (or more powerful in some other fashion).

The L indicates the value is a long integer (64 bits).The bit-and operation sets the sign bit to zero, assuming that the long is signed. Thus the getTime value is guaranteed to be positive. Maybe you knew that and the question is why it would be necessary to reset the sign bit?

The L indicates the value is a long integer (64 bits).The bit-and operation sets the sign bit to zero, assuming that the long is signed. Thus the getTime value is guaranteed to be positive. Maybe you knew that and the question is why it would be necessary to reset the sign bit?

No, I didn't know that; thank you for the explanation. Again, I'm kind of a novice... Please bear with me!

So is it basically a faster way of doing abs(x), or something along those lines?

The mask causes the time to wrap around and restart at 0 instead of Long.MIN_VALUE. This is important if you want to be able to generate consistent non-negative timestamps at some point after the heat death of the universe.

More observations (although... note that most if not all of my observations throughout both the TIGForums thread and this thread are basically subjective...):

Recently I seem to have observed that the GM example actually stutters more than I had thought. I think it's usually better than the Java examples and all around GM's the most consistent, but currently I suspect that:

-When GM stutters it can be more noticeable than some Java implementations? Especially on (only on?) those computers on which LWJGL's vsync can take effect.

-GM usually tends to run smoothly for longer periods of time than the Java examples, but not? on those computers for which the Java examples don't stutter (i.e. my school's computers). Furthermore, on those computers GM seems to alternate between no stuttering and stuttering more frequently than the Java examples.

Also, another issue: While the simple GM example stutters on those school computers, I had difficulty detecting any stuttering (there was some stuttering, but very little of it) with the demo for a game of mine, Platform Battle 2. In fact I think this might also have been the case during some trials on our desktop (although Java stutters on it). This may have something to do with the implementation:

-With the simple example, nothing is scaled and the box is moved at 2 pixels, whereas, in PB2, although the object I observed (a moving platform in the tutorial) still moves at 2 pixels, the graphics are scaled to two times its "actual" size by a method by ChevyRay.

-PB2 uses a sprite for the platform and has a patterned background. (I do, however, think that I looked pretty closely...)

I updated the box.com download with a new example. If I understand correctly, it's a sort of hybrid between Cas's example and Eli Delventhal's. I'm not sure if it's any smoother than any of the other Java examples, but there's at least one new thing being done here.

I noticed that Cas's example can loop many times without CPU problems. I think this means that, even if one of these example programs loops many times, the CPU only starts groaning if it also renders very fast (although it seems that the CPU still starts groaning if the looping is too fast). I tried looping like this in the hybrid example because it seems to me that, since the program checks the time more often, the timing would be more precise.

Also, I incorporated Eli Delventhal's timing method but applied it not only to logic updates but also to the rendering, which amounts, if I understand correctly and if I'm using the right terms, to making logic and rendering almost completely independent of each other in a sense. Put another way, they're each sort of on their own schedule.

Again, I can't really tell if all this allows the program to run any better than any of the other examples, but there it is anyway.

a) You know, I think I'm just going to incorporate the "extra sleeping thread" fix; with it, at least three of the Java examples seem to work just fine, as far as I can tell so far. The Java examples still stutter on my laptop, but so does the Game Maker example. Note: the download has not yet been updated.

I still feel that this solution is a bit inelegant, though. The extra thread forces the program to use a more precise (?) timer, right? Does that mean that functions like System.nanoTime() become more precise, that Thread.sleep becomes more precise, or both? I'd like to think that it's Thread.sleep; it would be nice to know that the timing, at least, is always reliable.

Does anyone know why the reliability of Thread.sleep would be so conditional (?)? Will they ever make it so Thread.sleep always behaves as it does with this solution?

b) Before incorporating that solution, though, something strange happened on my laptop: it started acting like our desktop for a moment! That is, the Game Maker example seemed to run more smoothly than usual, and some if not most of the Java examples were less smooth than usual and couldn't maintain 60 FPS. The programs started to behave as normal after I restarted the computer; this sometimes works on my desktop. Thus, it seems to me that there are (at least) two common computer settings, one in which Game Maker and Java behave similarly, and one in which Game Maker gets less stuttering than usual but in which Java gets more. What could be the cause of this?

Thanks for the input, Cero! It's been a while since I've visited this topic, ha ha.

Have you tried the "extra sleeping thread" method? It seems that the fix:

- has no effect on computers that yield little stuttering anyway,- reduces most stuttering on the computer I tested that yielded the most stuttering, and- has no effect on my laptop, on which the GM test program and my programs all stutter.

Note that I haven't updated the downloads with this fix.

By the way, although I had known about that fix from when this thread was started, it seemed too inelegant. Eventually, I decided to incorporate it into my programs.

Also I have to add. the stutter, in general, seems to happen more often when there is not a much going on.For example in m game, when I'm just walking and there is nothing fancy going on, its more likely to happen than when there is more going on.This would also explain why my simple cube example is so very vulnerable to this, and seems to stutter somewhat in all game loop examplesSo my guess is that, why a game would run at a very high FPS normally, like > 600 or something, slowing it down to 60 can cause stutters way more likely than slowing it down form like 200 fps or 100 fps to 60.

so I guess this is the bottom line: The higher your fps WOULD BE, the more the slowing down has to be done, the higher the chance of stuttering is.This doesn't seems to apply for fullscreen Vsynced.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org