Gamasutra: The Art & Business of Making Gamesspacer
Programming Responsiveness
View All     RSS
January 23, 2018
arrowPress Releases
January 23, 2018
Games Press
View All     RSS






If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Programming Responsiveness


July 9, 2008 Article Start Previous Page 2 of 3 Next
 

So how long is the lag? It depends on how long a frame is (where a "frame" here is a complete iteration of the main loop). It takes up to three frames for the user's input to be translated into visual feedback.

So if we are running at 30fps, then the lag is 3/30th or one-tenth of a second. If we are running at 60fps, then the lag will be 3/60th or 1/20th of a second.

This calculation illustrates a common misconception about the difference between 60fps and 30fps games. Since the difference between these two frame rates is just 1/60th of a second, people assume that the difference in responsiveness will also be 1/60th.

But in fact, going from 60 to 30 does not just add a vsync to your lag, it acts as a multiplier, doubling the length of the process pipeline that's responsible for lag. In our ideal example in Figure 1, it adds 3/60ths of a second, not 1/60th. If the event pipeline is longer, which it quite possibly can be, it can add even more.

Figure 1 actually illustrates the best possible sequence of events. The button press event is translated into visual feedback via the shortest path possible, which we can clearly see in the sequence of events.

As a programmer, being familiar with the order in which things happen is a vital part of understanding why things act the way they do in the game. It's quite easy to introduce additional frames of lag (meaning an extra 1/60th or 1/30th of a second delay), by not paying careful attention to the order in which events occur.

As a simple example, consider what would happen if we switched the order of the Logic() and Rendering() calls in our main loop. Look at Frame 2 of Figure 1: here the GPU logic (rendering) happens after CPU logic, so input at the start of Frame 2 will affect the CPU logic and hence the GPU logic in the same frame.

However if GPU logic is performed first, then the input will not have an effect on GPU logic until the next frame, hence introducing an extra frame of lag. While this is a novice mistake, programmers need to make absolutely sure it's not happening.

Extra frames of lag can be introduced in a subtler manner as a result of the order of operations within the game logic. In our example, we are firing a gun.

Now perhaps our engine is set up to increment the position of the objects in the world using a physics engine, and handle events that are raised due to this update (such as collision events). In this situation, the sequence of input or logic looks like Listing 2.

Listing 2: Physics Update Is Followed By Event Handling

void Logic() {
HandleInput();
UpdatePhysics();
HandleEvents();
}

Event handling via messages is a very nice way of decoupling systems and a programmer might decide to use it for the player control events. To fire a gun, the HandleInput() function will fire an event telling the gun to fire.

The HandleEvents() function will take this event and cause the gun to actually fire. But because the physics update has already happened for this frame, the effect on the world state will not be incorporated until the next frame, hence introducing an extra frame of lag.

More Lag Causes

Lower level action ordering can draw out the lag even more. Consider a jump, for example. The feedback is the character actually moving. To make something move in a game, you can either set the velocity directly or apply a force to it, such as acceleration or, more likely, a momentary impulse.

There's a problem in this scenario if your physics engine updates positions before the velocity change is applied, a common condition in many introductory game programming tutorials.

Although the velocity of the jumping object is updated in the same frame as the one where the input event is handled, the object will not actually begin to move until the next time around the loop-on the next game frame-and so it introduces an additional frame of lag.

Remember, these are cumulative problems that can be difficult to discern in isolation, but the combined effect can make your game controls turn to mush.

Suppose you had made all three mistakes listed above: you do rendering before logic, you handle logic events after advancing the physics state, and you update position before velocity. That's three additional full iteration of the main loop, in addition to the three you already have built in-six frames of lag between the player pressing a button and seeing the result on screen.

At 60 frames per second that's 1/10th of a second, which is bad enough, but if the game is running at 30fps, the lag is doubled to an unbearable 1/5th of a second, or 200 milliseconds.


Article Start Previous Page 2 of 3 Next

Related Jobs

Insomniac Games
Insomniac Games — Burbank, California, United States
[01.22.18]

Engine Programmer
Insomniac Games
Insomniac Games — Burbank, California, United States
[01.22.18]

Director, Gameplay Programming
Insomniac Games
Insomniac Games — Burbank, California, United States
[01.22.18]

Director, Core
Remedy Entertainment
Remedy Entertainment — Helsinki - Capital Area, Finland
[01.22.18]

Senior AI Programmer





Loading Comments

loader image