That's true. However, in the two examples you posted on the TIG forum you let the user choose, before the application launches, if he wants to use Double buffering or not... right? o.O

Ohhh yes, you're right. Sorry, I'd forgotten that the stuff I posted on TIGSource is a little older; the build I'm currently testing on my own doesn't use Type 2 (Paint) anymore. I think Type 1 (BufferStrategy) should still be relevant, though, although I did refactor stuff a bit.

First of all, choosing the Paint option produces extremely smooth movement in all character ( unlike the laptop ).

Secondly, when I run it with double buffering, I get HORRENDOUS stuttering! However, when I close the application and open it again, I suddenly get smooth movements ( although still sometimes stutterring and overall worse than what I get without double buffering ).

So I decided to open up 5 windows of the game. That is, 5 games with double buffering running at the same time.

I noticed that some of the windows had smooth movement, and others had HORRIBLE and moderate stuttering. They were consistent with their stuttering by the way. The window with horrible stuttering was always stuttering, and the ones with less were moderately so consistently, and those without much stuttering also consistently so. I also opene up a game with no double buffering wich continued to produce extremely smooth movement - unlike the double buffered versions.

What could be the cause for this? I'm assuming that the start time of the applications comes into play. Ie System.CurrentTime() has something to do with this. I'm not sure however.

One thing to note however, when I ran 7+ games at the same time, they ALL had SIMULTANEOUSLY ( even the ones without double buffering ) a "heavy" stutter moment that would last like a ½ second. That is the screens would sort of freeze and appear in their correct positions as if the freeze had never happened.

2. Movies look somewhat fluid at 24 FPS because it is recorded. Consider how a camera works. It takes in light during a certain time and saves it to a film or a memory card or whatever, while your game provides a perfectly sharp image which is a snapshot of a single moment in time, like a camera with an infinitely short shutter time that takes images at a certain interval. If you have good motion blur and other effects, people will be more forgiving of low FPS, but it's still better to have higher FPS for less delay and better responsiveness. BTW, you know those cheap drama series that run at hours when nobody watches television that look "fake". They are shot with 30 FPS cameras. Newer TVs also do frame interpolation to increase the FPS by generating interpolated frames in between the video frames by predicting movement. The difference is very easy to see for me, even more so for anime where the image is sharp like games.

3. Your SNES never had this kind of random stuttering because it didn't have the same graphics pipeline as you have in a computer. And stuttering due to mismatched frame rate surely existed. Rendered at either 25 or 30 FPS.

It's an artifact of using nearest neighbor sampling for the sprites (= rounding errors like you said). The "problem" is related to sprites having integer positions and no texture interpolation. The game is experiencing the same amount of stuttering as the Cero's bouncing box demo in Java due to frames never being displayed, but it's hidden by the inherent choppy movement of the sprites.

Thank you for your feedback. You say "using double buffering"... Isn't that something that the programmer uses? Like, with the BufferStrategy class? Game Maker and my Java programs all should be implementing double buffering whether the player likes it or not...

That's true. However, in the two examples you posted on the TIG forum you let the user choose, before the application launches, if he wants to use Double buffering or not... right? o.O

Both paint and BufferStrategy use double buffering. BufferStrategy is meant for active rendering (repainting every frame, like in a game) while paint() (and Swing in general) is meant for GUIs that only need triggered repaints (mouse clicked a button, a window was shown, e.t.c). Both use double buffering to avoid flickering. BufferStrategy might use page-flipping though, which does the same as double buffering but avoids a copy from the back buffer to the front buffer.

That's true. However, in the two examples you posted on the TIG forum you let the user choose, before the application launches, if he wants to use Double buffering or not... right? o.O

Ohhh yes, you're right. Sorry, I'd forgotten that the stuff I posted on TIGSource is a little older; the build I'm currently testing on my own doesn't use Type 2 (Paint) anymore. I think Type 1 (BufferStrategy) should still be relevant, though, although I did refactor stuff a bit.

I would argue that the GM game and your Java examples with Double buffering produce the same quality of stuttering.

Wait, really? I guess this may be the case on my laptop, but on our desktop there seems to be quite a difference. Note: I still have yet to test on my university's computers.

I'd say the GM one stutters a lot more due to the position rounding. With antialiasing and/or texture interpolation it would stutter exactly as much as non-VSynced Java games. Why? Because your monitor is connected to your graphics card.

First of all, choosing the Paint option produces extremely smooth movement in all character ( unlike the laptop ).

Secondly, when I run it with double buffering, I get HORRENDOUS stuttering! However, when I close the application and open it again, I suddenly get smooth movements ( although still sometimes stutterring and overall worse than what I get without double buffering ).

So I decided to open up 5 windows of the game. That is, 5 games with double buffering running at the same time.

I noticed that some of the windows had smooth movement, and others had HORRIBLE and moderate stuttering. They were consistent with their stuttering by the way. The window with horrible stuttering was always stuttering, and the ones with less were moderately so consistently, and those without much stuttering also consistently so. I also opene up a game with no double buffering wich continued to produce extremely smooth movement - unlike the double buffered versions.

What could be the cause for this? I'm assuming that the start time of the applications comes into play. Ie System.CurrentTime() has something to do with this. I'm not sure however.

One thing to note however, when I ran 7+ games at the same time, they ALL had SIMULTANEOUSLY ( even the ones without double buffering ) a "heavy" stutter moment that would last like a ½ second. That is the screens would sort of freeze and appear in their correct positions as if the freeze had never happened.

I'd blame this on Java2D + garbage collection? I'm not a Java2D pro in any way, but a decent graphics library shouldn't do that. Try to measure the frame time of each frame (System.out.println the delta of each frame).Note that stuttering that lasts several frames is NOT caused by the graphics pipeline or your graphics driver if you don't exhibit this problem in other programs. It's basically Java's fault. Just use LWJGL. xD

Ah so that paint() is swing. Is it weird that Swing produces better graphics for games even though it's only meant for simple GUIs?

I've almost explicitly used Swing graphics in all my java apps that requires something to be drawn. That is, using JFrame and JPanel. And with those I've never experience stuttering. Albeit I've only done simple things. But the first application I did was have ball bounce from the sides of the screen and in that app I used only awt with my own implementation of double buffering and did experience stuttering.

That's what Cero's example uses, right, and it still causes stuttering. Is it better than Java2D? I don't think we've determined that quite yet. Also, would Slick2D be a suitable equivalent option?

Java2D is slow. LWJGL is a native binding to OpenGL, which means you can directly access the graphics card. Slick2D has a Java2D-like API but uses LWJGL underneath, so it's fast for relatively small games.

OpenGL has several hundred times more performance than un-accelerated Java2D (the OpenGL acceleration for Java2D is unreliable in my experience). It also gives you access and control over the only thing that will solve the stuttering that you experienced with Cero's example, VSync. You'll also have to use something more accurate than Display.sync(60) though, but that's a wheel that has already been invented.

Java2D is slow. LWJGL is a native binding to OpenGL, which means you can directly access the graphics card. Slick2D has a Java2D-like API but uses LWJGL underneath, so it's fast for relatively small games.

OpenGL has several hundred times more performance than un-accelerated Java2D (the OpenGL acceleration for Java2D is unreliable in my experience). It also gives you access and control over the only thing that will solve the stuttering that you experienced with Cero's example, VSync. You'll also have to use something more accurate than Display.sync(60) though, but that's a wheel that has already been invented.

I see. Well, if I can't use Java2D and can't use Display.sync(60), what would the game loop look like with a fixed timestep? Would I just use Display.update() in the place of g.dispose() and strategy.show()? What if it still stutters? Any possibility of providing example code for a loop? I'm curious as to how you all go about doing this, because, if I remember correctly, when I tried LWJGL I got more stuttering than with Java2D.

Java2D is slow. Display.sync(60) is inaccurate (syncs to 63 FPS due to rounding the sleep time each frame from 16.6666667ms to 17ms). I wouldn't use them. xd

I assume you're converting from Java2D to LWJGL. Display.update() is equal to g.dispose() + strategy.show(). Take a look at this game loop article for some basics in implementing a good game loop:http://www.koonsolo.com/news/dewitters-gameloop/ The last "best" game loop with interpolation is probably waaaaay overkill. The "Constant Game Speed with Maximum FPS" should be good.

You can do syncing with an LWJGL Timer object or System.nanoTime() but you might want to still use the endless sleep thread fix. oth have good accuracy.

To implement sleeping, just measure the time it took to update and render the frame, and sleep for the remaining time of the frame time (frame_time = 1000 / frame_rate milliseconds). Be sure to prevent error build-up in the timing.

If the stutter is still unacceptable because you're wasting hours sitting with a high-speed camera recording a bouncing box running at 1 pixel per update through a microscope instead of actually making your game, you've done what you can on this side of the hardware, and the only thing you can do is enable VSync, which is just Display.setVSyncEnabled(true); =D

@Ra4kings game loop:Are you sure doing Thread.sleep(1) x times is more accurate than just a single Thread.sleep(x)? I mean, if Thread.sleep() has so bad accuracy, isn't it worse to try to sleep for even shorter times? And you shouldn't worry about the performance of doing 20 Thread.sleep()s per frame instead of one. It doesn't use any measurable amount of CPU time at all. Thread.sleep(1) is going to sleep thousands or even millions of times more cycles than it is spending going into and out of sleep.

Also: Thread.sleep() causes considerable jitter on most systems due to the vagaries of the thread schdulers on each. Thread.yield() gives better results but canes batteries on laptops. Doing a busy loop is the best option but is generally quite unfriendly

Thank you, ra4king, for your loop code, and thank you everyone in general for your continued feedback!

Well, I guess I will try implementing LWJGL again, then, but I probably won't be able to work on that for a while. In the meantime, please feel free to keep the discussion going! Perhaps someone else could try their own hand at producing a smooth "bouncing box" example using all of this new information?

If the stutter is still unacceptable because you're wasting hours sitting with a high-speed camera recording a bouncing box running at 1 pixel per update through a microscope instead of actually making your game, you've done what you can on this side of the hardware, and the only thing you can do is enable VSync, which is just Display.setVSyncEnabled(true); =D

I appreciate the hyperbole, but know that the stuttering seems to make the version of my test program with more than just bouncing sprites actually seem pretty legitimately unplayable on my desktop... (with GM still running just fine)

It should be noted that quite a few AAA titles do a busy loop. They are often forced to add a different mechanism in a patch later for laptops with the complaints they get and at least one game caused some video card to overheat. So even outside the java world it is clearly not that easy to solve.

I have no special talents. I am only passionately curious.--Albert Einstein

OpenGL has several hundred times more performance than un-accelerated Java2D (the OpenGL acceleration for Java2D is unreliable in my experience). It also gives you access and control over the only thing that will solve the stuttering that you experienced with Cero's example, VSync.

As I posted near the beginning of this thread, it is theoretically (and unofficially!) possible to request a VSynced buffer strategy in an AWT window using ExtendedBufferCapabilities. How well and when this works is another matter (and as my whole bloody desktop doesn't VSync, not easy to play with!)

Also see the code in SwingUtilities3 and BufferStrategyRepaintManager.

Thank you, ra4king, for your loop code, and thank you everyone in general for your continued feedback!

Well, I guess I will try implementing LWJGL again, then, but I probably won't be able to work on that for a while. In the meantime, please feel free to keep the discussion going! Perhaps someone else could try their own hand at producing a smooth "bouncing box" example using all of this new information?

If the stutter is still unacceptable because you're wasting hours sitting with a high-speed camera recording a bouncing box running at 1 pixel per update through a microscope instead of actually making your game, you've done what you can on this side of the hardware, and the only thing you can do is enable VSync, which is just Display.setVSyncEnabled(true); =D

I appreciate the hyperbole, but know that the stuttering seems to make the version of my test program with more than just bouncing sprites actually seem pretty legitimately unplayable on my desktop... (with GM still running just fine)

Well, Java2D < GM < OpenGL.

Use Slick2D. It should get you started much quicker than fiddling with glBegin()/glEnd() in pure OpenGL. I remember how hard it was to get texture loading and rendering to work in the beginning. The problem with libraries like OpenGL is that you get so ridiculously bad feedback from the code. If you're not doing something the right way (especially with textures) you're just going to get a black screen or a triangle without a texture, or something confusing like that. It's frustrating and time consuming so I really recommend that you start out with Slick2D, if only just for the built in texture loading, e.t.c. Move over to pure LWJGL if you feel that Slick is limiting you in some way, or you just want to take a peek under the hood.

It should be noted that quite a few AAA titles do a busy loop. They are often forced to add a different mechanism in a patch later for laptops with the complaints they get and at least one game caused some video card to overheat. So even outside the java world it is clearly not that easy to solve.

Because doing a busy loop on your CPU overheats your video card. That doesn't make much sense. I believe that most games use a varying time step. I know that all CoD games do, which in fact resulted in the extremely amusing floating point rounding error bug that makes your character jump higher if you reach a certain FPS, the same problem you see in Ra4king's climbing game if you disable sleeping. There is a reason why they limited the max FPS in CoD to 90. xD Mostly fast paced games that don't need determinism use varying time steps.

Most strategy games use a fixed time step though as they need determinism. For example, the game engine used in C&C Generals, LotR The Battle for Middle Earth and C&C 3 (and probably the later C&C games too) is having it's maximum rendering speed limited by its updating speed, which is usually as low as 25 FPS. Many people complained about the fact that it's not possible to get a higher FPS for more fluent movement in these games without having to actually increase the game speed (which means that the whole game goes faster). The problem could have been solved by implementing interpolation into the rendering process, which is exactly what the most advanced game loop implementation does in the article I linked before. So really, it's not like these AAA games are doing any magic here to neither prevent stuttering nor having good game loops. You've just never noticed it before.

Also: Rule no. 1 of overheating: It is NEVER EVER a game's fault that your computer overheats. Either the overheating component in your computer has insufficient cooling, or there is a software bug in the fan controller or something similar, but it can in no way be your game's fault. Consider this: You're drive up on a freeway with your new car, and when you reach 70 km/h your car explodes. Is it your fault? Of course not. You were using the car well within it's specifications. It shouldn't be possible for you to cause your car to explode in any way in the first place. Such a problem is obviously a hardware problem and not a fault of the one driving the car. Okay, maybe having the car explode is a weird example, but I hope you get the idea.

OpenGL has several hundred times more performance than un-accelerated Java2D (the OpenGL acceleration for Java2D is unreliable in my experience). It also gives you access and control over the only thing that will solve the stuttering that you experienced with Cero's example, VSync.

As I posted near the beginning of this thread, it is theoretically (and unofficially!) possible to request a VSynced buffer strategy in an AWT window using ExtendedBufferCapabilities. How well and when this works is another matter (and as my whole bloody desktop doesn't VSync, not easy to play with!)

Also see the code in SwingUtilities3 and BufferStrategyRepaintManager.

Because Swing is a GUI library, not a graphics library. If you want to use GUI items like buttons, menus, etc... then use Swing. Otherwise, it's an unnecessary overhead.

Is it? It seems to produce more stutterfree graphics...

I'd think it extremely unlikely that this has been enabled by default, but maybe Swing is VSyncing?!

PS. None of the above should in any way be regarded as advice not to use OpenGL!

I'm (pretty) sure that Swing by default is VSynced (including BufferStrategy) on my computer, but I'd love to be proved wrong. That way I can laugh more at how unreliable Java2D is and how good life is on the green OpenGL side of life. xD

I've been thinking about putting together a tutorial for detecting, diagnosing and preventing stuttering, both Java specific problems and general problems related to the graphics pipeline. I get the feeling my mile-long posts are being a little bit ignored here, so I'm wondering if anyone would find that useful, or think that someone else (newbies?) would find it helpful/interesting. I'm thinking of splitting it up into three main parts: Detecting stuttering (finding out if your program stutters), diagnosing stuttering (find out what causes it) and finally preventing/fixing it. Thoughts?

A yield does nothing, so then the next frame is rendered asap, there is more than one way to do a busy loop. Hence the rendering frame rate (not the display frame rate) could be very high. Thus it would tax the video cards far more than needed. As a results some poor machine setups and a buggy thermal monitor in some ATi cards meant they overheated and would shut down. The nvidias would just slow down. Even if that wasn't the case the fan would wind up to max, while other eye candy games this was not happening.

I totally agree that hardware should be able to handle what software can through at them (in this case, not like software defined radio etc). But that does not help your PR after the fact and the game forums where abuzz with negative feedback. Right on top of release that is bad karma no matter how you slice it.

Frame rates being attached to game rate is nothing new. Quake was like that, anything less that 120fps in the later days you couldn't make some of the map designed rocket jumps. Or even just plain jumps. The frame rate limiting is a bit hacky IMO. I would make the physics independent of the frame rate.

I do this in my current game in that the engine is decoupled from the view. The game rate is about 5-10 turns per sec. While the frame rate can be much higher. Thus the graphics code has less "work" to sync with. TBH i have not had huge problems with stuttering. Well none in fact. But then i have only tested on linux.

I have no special talents. I am only passionately curious.--Albert Einstein

A yield does nothing, so then the next frame is rendered asap, there is more than one way to do a busy loop. Hence the rendering frame rate (not the display frame rate) could be very high. Thus it would tax the video cards far more than needed. As a results some poor machine setups and a buggy thermal monitor in some ATi cards meant they overheated and would shut down. The nvidias would just slow down. Even if that wasn't the case the fan would wind up to max, while other eye candy games this was not happening.

I totally agree that hardware should be able to handle what software can through at them (in this case, not like software defined radio etc). But that does not help your PR after the fact and the game forums where abuzz with negative feedback. Right on top of release that is bad karma no matter how you slice it.

Frame rates being attached to game rate is nothing new. Quake was like that, anything less that 120fps in the later days you couldn't make some of the map designed rocket jumps. Or even just plain jumps. The frame rate limiting is a bit hacky IMO. I would make the physics independent of the frame rate.

I do this in my current game in that the engine is decoupled from the view. The game rate is about 5-10 turns per sec. While the frame rate can be much higher. Thus the graphics code has less "work" to sync with. TBH i have not had huge problems with stuttering. Well none in fact. But then i have only tested on linux.

PR... I thought this was a game programming forum, not a game marketing forum. xD xD xD My game will have a setting called "Stupid Artificial Slowness", which when enabled pops up a confirmation screen where you must agree to the terms of use which basically say that I have the right to ridicule you for driving an exploding car. Yeah, that will be awesome.

Concerning your own game, do you not do any interpolation of the game state during rendering? If not, what is the point of redrawing the exact same frame over and over again?

It is fully interpolated. Its also a RTS where latency is less of a issue. At 10 game turns per sec you effectively have a ping on the order of 100ms. Of course i can make that higher. The nice part of the design is that the logic is very independent from the view. Also the separation made network support easier too.

As for stuttering, I have really had no problems so far and i have not being doing anything fancy. In fact i think i still have Thread.sleep loop. Again only on linux. Also i am not taxing my video cards.

I have no special talents. I am only passionately curious.--Albert Einstein

I'm (pretty) sure that Swing by default is VSynced (including BufferStrategy) on my computer, but I'd love to be proved wrong. That way I can laugh more at how unreliable Java2D is and how good life is on the green OpenGL side of life. xD

Huh? Was that meant to be "is not VSynced"? Otherwise, I'm confused why you'd love to be proved wrong! Having had a quick look at the source for Component, it also seems to try and automatically insert an ExtendedBufferCapabilities when creating a BufferStrategy, in certain circumstances. What exactly those are and when VSync should be enabled is hard to determine - it's spaghetti in there!

I'm (pretty) sure that Swing by default is VSynced (including BufferStrategy) on my computer, but I'd love to be proved wrong. That way I can laugh more at how unreliable Java2D is and how good life is on the green OpenGL side of life. xD

Huh? Was that meant to be "is not VSynced"? Otherwise, I'm confused why you'd love to be proved wrong! Having had a quick look at the source for Component, it also seems to try and automatically insert an ExtendedBufferCapabilities when creating a BufferStrategy, in certain circumstances. What exactly those are and when VSync should be enabled is hard to determine - it's spaghetti in there!

Nope, it's correct. I think I remember my BufferStrategy not being able to go above 60 FPS, but I might just be mixing things up. Maybe I was forcing VSync with my drivers? xD

I've been thinking about putting together a tutorial for detecting, diagnosing and preventing stuttering, both Java specific problems and general problems related to the graphics pipeline. I get the feeling my mile-long posts are being a little bit ignored here, so I'm wondering if anyone would find that useful, or think that someone else (newbies?) would find it helpful/interesting. I'm thinking of splitting it up into three main parts: Detecting stuttering (finding out if your program stutters), diagnosing stuttering (find out what causes it) and finally preventing/fixing it. Thoughts?

I would find it useful, but seeing as I, being kind of a noob, haven't quite gotten how to detect, diagnose and prevent stuttering after reading your posts (albeit in a rush), perhaps you could make your tutorial be a more concise and dumbed down version of your posts.

EDIT: Anyone care to demonstrate a smooth fixed timestep loop in either LWJGL or Slick2D?

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