Java-Gaming.org    
Featured games (78)
games approved by the League of Dukes
Games in Showcase (429)
Games in Android Showcase (89)
games submitted by our members
Games in WIP (468)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  LWJGL Timing problem  (Read 493 times)
0 Members and 1 Guest are viewing this topic.
Offline pixelprime

Junior Member


Medals: 3



« Posted 2013-02-19 15:19:57 »

Hey all,

I'm having some issues with the delta-timing in my game engine. I'm basing it from some tutorial code I worked through, but I've found some cases where it's bugging out a bit. Timing seems fine when there's no load on the engine and the framerates are high, but when there's a lot on the screen (during stress testing), the timing goes well out of whack.

For example, a movement along one axis of 1 unit per second somehow ends up as 50 units per second when the game is 'laggy' when under load.

Here's the two key methods. First, the main game loop (N.B. the 'delta' static member of the encompassing class, so I can access it from elsewhere):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
public void start()
   {
      lastFrame = getTime();
      lastFPS = getTime();
      delta = 0;
      gameState = startupState;
           
      // while the game is running we loop round updating and rendering
     while (!Display.isCloseRequested() && !AppWin.ref.isClosedRequested())
      {
         // calculate the frame delta (time elapsed since the last loop iteration)
        int _delta = (int) (getTime() - lastFrame);
         lastFrame = getTime();
         
         delta = _delta;
         
         // clear the display
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
         
         // ensure a constant update speed
        int remainder = delta % 10;
         int step = delta / 10;
         
         // run as many update cycles as we need to catch up to our render timing
        for (int i=0;i<step;i++)
         {
            update(10);
         }
         if (remainder != 0)
         {
            update(remainder);
         }
         
         // render the game
        render(delta);
         
         // refresh the display
        Display.update();
         Display.sync(60);

         // update the current FPS value
        updateFPS();
      }
     
      Display.destroy();
      System.exit(0);
   }


And the timing function:

1  
2  
3  
4  
private long getTime() 
   {
      return (Sys.getTime() * 1000) / Sys.getTimerResolution();
   }


Here's a typical example of how I use this delta value:

1  
2  
3  
// what speed are we moving at, based on the current delta?
// 'forwardSpeed' will be a fixed value, such as 10
speed = (forwardSpeed * GameLoop.delta) / 1000f;


I'm clearly doing something wrong here, otherwise my application of the 'speed' variable would be predictable, regardless of frame rate.

Thanks for any insight anyone can offer Smiley
Offline Jack Ammo

Junior Newbie





« Reply #1 - Posted 2013-02-19 17:02:47 »

1  
speed = (forwardSpeed * GameLoop.delta) / 1000f;


if you want the speed to be constant, than you shouldn't be multiplying it's value like that. Regardless of how much time goes by, the speed shouldn't change in your case. The position does. Which brings me to my next point, that speed*time = distance, not speed again. so if you replace the speed there with your position variable like so,

1  
position += (forwardSpeed * GameLoop.delta) / 1000f;

you would get your proper position even if your delta fluctuates from lag.


fading away until all that's left is but a distant memory
Offline pixelprime

Junior Member


Medals: 3



« Reply #2 - Posted 2013-02-19 17:12:33 »

Thank you for the reply, but I think you have have misinterpreted how I'm using the speed variable (which is perhaps more to do with me not furthering my example).

After the speed is calculated, it's applied to the current position:

1  
2  
speed = (forwardSpeed * GameLoop.delta) / 1000f;
position.x += speed;


It's essentially the same as your example. I'm aware of the need to adjust the amount of distance you need to travel based on timing, rather than ticks, which is why I feel that my problem is with my calculation of the timing, rather than the method I'm using to apply it.

In a normal run loop, having a movement speed of, say, 10 would produce wildly fast speeds (for my needs, anyway). That's why I use the 1000f modifier - to bring the final value back down to around the 0.xxxx range.

if forwardSpeed is 10, then the following applies:

N.B. Delta in this example is '10'
(10 * GameLoop.delta) / 1000f = 0.1

If the delta was '2' then the following is true:
(10 * GameLoop.delta) / 1000f = 0.02

Therefore, a faster update of '2', rather than '10' should yield a much slower update distance, correct?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Jack Ammo

Junior Newbie





« Reply #3 - Posted 2013-02-19 17:37:47 »

oh, my apologies. Other than wrongly assuming meaning based on your naming conventions, I don't see what's inherently wrong with your timing. Unless you're playing with the value of your delta in your update method or are somehow doing weird extrapolation in your render method, I honestly am not sure why that bug is happening for you.

fading away until all that's left is but a distant memory
Offline pixelprime

Junior Member


Medals: 3



« Reply #4 - Posted 2013-02-19 17:40:33 »

Thanks. I guess I'll just have to dig around some more and maybe do some separate tests.

Thanks for taking a look over the code, though.
Offline ctomni231

JGO Ninja


Medals: 71
Projects: 1
Exp: 7 years


Not a glitch. Just have a lil' pixelexia...


« Reply #5 - Posted 2013-02-19 22:17:26 »

1  
2  
3  
4  
for (int i=0;i<step;i++) 
{
     update(10);
}


If it is skipping around like that, it is basically because when the game lags, the time is going to pile up into one huge chunk of time. When it hits this part of the loop, it is going to update the field skipping a lot of the steps in-between. In order words, when your game lags it will cause your game to stutter and skip a bunch of frames. I mean, you could update and render at the same time, but it'll cause sections where your game fully speeds up when it lags.

So, it is just something you'll have to live with I guess. That is how many online games deal with lag.

The best way to deal with lag problems in any game is to reduce the amount of draw() calls. There is nothing wrong with your game loop. I know for me, the most important part of a game loop is to make sure the user has full control over the action regardless if the system lags.

Fixed time rate (what you are doing now,) guarantees a smooth experience. (Better for smooth graphics)
Variable time rate, what I prefer, forces all the update frames to be visible and goes choppy when it lags. (Better for keeping control)

It all depends on your game though, and what you believe is important. Just know that your game loop is running on optimal condition and there is nothing much else you can do to fight against the lag except probably attacking your update and render code.


Offline pixelprime

Junior Member


Medals: 3



« Reply #6 - Posted 2013-02-20 09:48:57 »

This was a tremendously useful explanation, thank you very much!

I'll have to adjust the code somewhat, in that case, but I'd much rather incur some laggy frames and retain full timing control than suffer the bane of weird movement artifacts when the game slows down.

Once again, your input is much appreciated, thanks!
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

theagentd (6 views)
2014-04-24 23:00:44

xsi3rr4x (83 views)
2014-04-15 18:08:23

BurntPizza (75 views)
2014-04-15 03:46:01

UprightPath (86 views)
2014-04-14 17:39:50

UprightPath (69 views)
2014-04-14 17:35:47

Porlus (86 views)
2014-04-14 15:48:38

tom_mai78101 (109 views)
2014-04-10 04:04:31

BurntPizza (169 views)
2014-04-08 23:06:04

tom_mai78101 (265 views)
2014-04-05 13:34:39

trollwarrior1 (216 views)
2014-04-04 12:06:45
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!