LWJGL Timing problem

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):


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:


private long getTime() 
	{
		return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}

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


// 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 :slight_smile:

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,

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

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

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:


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?

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.

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.


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.

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!