responsiveness of main game loop designs

Started by
38 comments, last by Norman Barrows 7 years, 11 months ago

>> [background=#fafbfc]If you accept the argument that there's no need to poll faster than the drawing rate[/background]


[background=#fafbfc]assuming you update no faster than you poll or render.[/background]

[background=#fafbfc]just cause you can only draw the screen once every 8 games turns doesn't mean you should let the computer move every turn and only let the user move every 8 game turns.[/background]

[background=#fafbfc]you have to preserve the fair play of "its my turn, ok, now its your turn, ok now its my turn again."[/background]

[background=#fafbfc]"i cant draw fast enough to show you whats going on - so you don't get a turn until i can" - that's just silly.[/background]

[background=#fafbfc]yet from what you say, it seems folks actually do this. no wonder games are such piles of crap these days.[/background]

We're talking about some pretty small time slices here. In my example, the sim is running at 480Hz and the user is seeing it at 60Hz, which is the limit of most people's monitors. It's literally drawing as fast as possible. Human high-level conscious thought, by latest research, only updates at approx 5Hz :lol: The simulation rate being higher than the display rate simply results in more fidelity -- e.g. integration of physics can be more accurate, not unfairness...
For example, in my racing sim, I can run the tire logic at 6000Hz to ensure that they behave realistically when cornering at 300MPH -- but I can also only allow the AI drivers to output new steering/acceleration/braking commands at 10Hz if I want them to appear human. My choice of tire simulation fidelity means nothing to AI vs Human fairness...

Moreover, a world-champion starcraft player, a professional athlete who trains full time, can manage about 400 actions per minute, which is impossibly high for us mortals. That's ~6.7 actions per second... or at 60Hz, that's one action every 9 frames, on average. So the best video game players in the world are already only getting approx one turn in eight, and can only manage to keep up with a computer "turn for turn" in a ~7Hz simulation... meaning that if you're running your update loop even at 15Hz, the computer is still getting twice as many "turns" as the player, which by your logic is grossly unfair???
No one would play a 7Hz action game these days, so obviously rendering at the user's input rate is not a good idea. Rendering as fast as possible makes the game more responsive for the user as the game-event->photon->cognition->motion->keyboard loop becomes shorter. At lower framerates, this whole loop gets longer, so the user is given a disadvantage -- even if they react as fast as humanly possible (about 200ms), they're given the handicap of the photons informing them of the event later than possible.

In my example I chose to poll at the rendering rate, but that's not required either. You could poll once per update, and still render once every N updates -- this would allow the user to input commands at the simulation rate, but only be able to see the results of them at the display rate. Note though that audio devices have pretty high output rates (e.g. in KHz instead of Hz :) ) so audio cues could still be output at the simulation rate.
Fact is that in general, a high framerate game will be more responsive than a low-framerate one, decoupling the simulation and rendering rates doesn't necessarily impact responsiveness, and decoupling rates doesn't have to impact the fairness of the game.

Anyway, in the OP you asked if it's possible to update faster than render, without harming responsiveness. And yes, you can, as long as you're ok with the sim having higher temporal fidelity than the user's monitor... In any case, responsiveness does not have to decrease- it can be the same as before.
In fact, responsiveness can actually improve in a decoupled simulation!
In a traditional loop running at 30Hz, the delay between a key-press occuring and being picked up by the poll is between 0 and 1 frames, or on average, 0.5 frames, or 16.7ms. There's then 33.3ms between the poll and when until the CPU finishes the next frame (which consumes that input), for 50ms average delay between a keypress, and the draw commands resulting from it being sent to the GPU:
0ms        33.3ms               66.6ms
| Frame 1  | Frame 2            |
 Key press | Poll,Update,Render |
In a decoupled loop where there's 3x Poll/Update pairs per draw, there's also less time between polling, so now we're polling every ~5.6ms, so a key-input waits an average of ~2.8ms before being picked up by a poll.
Events picked up by a poll now wait either 16.7ms, 11.1ms or 5.6ms (average 11.1ms) before the next draw starts, and 16.7ms until that draw completes, for 30.5ms average delay between a keypress, and the draw commands resulting from it being sent to the GPU:
0ms                16.6ms           33.3ms
|   Key Press     |                 |
| Frame 1 Sim     | Frame 2 Sim     |
| P,U | P,U | P,U | P,U | P,U | P,U |
| Frame 0 Draw    | Frame 1 Draw    |
| Draw            | Draw            |
So in a traditional loop, the input latency is one and a half frames on average, while in this particular decoupled loop it's actually less than one frame on average!
Of course, I have cheated by making the Update portion 3x faster in one example and not the other :lol: but the general idea is that: if you're bottlenecked by rendering, you might be able to increase your simulation rate to no ill effect (or even to positive effect).

There's also the opposite situation -- when you're bottlenecked by the simulation. e.g. in RTS games, it's common for the simulation to advance at something pitiful like 10Hz, while the renderer pumps out responsive 60Hz frames.
In this case, rendering at 10Hz would simply be unacceptable -- things like camera scrolling would be unnecessarily choppy and unresponsive. By increasing the display rate, not only do you keep the user happy with smooth animation, but you make all of the user interface elements much more responsive (as they don't have to be tied to the simulation rate). If the user clicks on a button, the UI code can start playing an audio response and changing the color of that button in around 25ms, whereas if it was tied to the simulation rate, the average response would be 150ms.
So again, in that different situation, decoupling the simulation/rendering rates can actually improve the user's feeling of responsiveness.
Advertisement

Human high-level conscious thought, by latest research, only updates at approx 5Hz :lol:

Even though human high-level conscious thought might update at 5Hz, conscious thought is not where most gaming that need high framerate takes place.

Which is a reason we do notice the difference with framerates as high as 144Hz.

Very interesting discussion in this thread, just had to comment on this detail :)

(even though it's probably obvious to most people here)

just cause you can only draw the screen once every 8 games turns doesn't mean you should let the computer move every turn and only let the user move every 8 game turns.

There should also get to be one human player for every core involved, or else the computer is ganging up on the player.

In extreme cases you could improve perceived latency by drawing some things after the main game/simulation graphics, like if your game displays a mouse cursor. Even if your normal simulation and rendering was done as usual you could delay your swap/present and draw the cursor with an updated position right before the image is sent to the display, possibly with input data received several ms after the simulation was last updated. You could even buffer a few rendered frames, then go back and draw the cursor on top right before getting the image ready for presentation.

For OpenGL there is https://www.opengl.org/registry/specs/NV/wgl_delay_before_swap.txt to achieve minimal latency.

>> There should also get to be one human player for every core involved, or else the computer is ganging up on the player.

only if you program the AI to do so. having the AI gang up on the player is the oldest form of "cheating" there is.

there are two kinds of games, those that provide a level playing field - and everything else.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

>> In extreme cases you could improve perceived latency by drawing some things after the main game/simulation graphics, like if your game displays a mouse cursor.

although not explicitly mentioned, this question is mostly with regards to realtime combat (IE FPSRPG type games) - so no mouse cursors.

if it doesn't have to be realtime - who cares?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

frankly, this revelation has put me into shock at what passes for "good engineering" in "professional" game development. and is making me seriously reconsider whether my time spent on this forum is time well spent.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

frankly, this revelation has put me into shock at what passes for "good engineering" in "professional" game development. and is making me seriously reconsider whether my time spent on this forum is time well spent.

Making games run faster, use modern hardware more efficiently, and feel more responsive to the user.... is bad?

There's no need to be rude just because you got an answer that contradicted your asserted preconception and gave you an opportunity to learn new techniques that are applicable to certain situations. If you're going to simply ignore anything that doesn't fit your preconceptions, and invent new self-contradictory reasons why you should ignore them, despite evidence disproving your objections, then no, you're not making good use of your time.

>> There should also get to be one human player for every core involved, or else the computer is ganging up on the player.

only if you program the AI to do so. having the AI gang up on the player is the oldest form of "cheating" there is.

there are two kinds of games, those that provide a level playing field - and everything else.

I'm pretty sure he was joking....

Which makes me wonder what you are talking about.

just cause you can only draw the screen once every 8 games turns doesn't mean you should let the computer move every turn and only let the user move every 8 game turns.

What do you mean with this? updates and frames is not the same thing as game turns... So this doesn't really make sense to me.. Is the computer "cheating" if the framerate is too high?

total max lag = max time between polls (polling lag) + time between present and input doing other things (other lag) + time from end of present til end of next present that shows results of input polled after the first present (response lag).

if you poll at 5 Hz, your max polling lag is 200ms. if you poll right after you present, your other lag is zero. if it takes 33ms to poll, update, and render the results of update, your max response lag is 33ms. for a total of 233ms max lag. for minumum lag, you lose the poll lag (IE assume they pressed the button on the very last poll), which would give you a minimum lag of 33ms (minus polling time) from button press after present through update, render, and present again.

i poll at 15hz, my max polling lag is 66ms. i poll right after i present. my other lag is zero. it takes 66ms to poll, update, render, and present, so my max response lag is 66ms, for a total of 132ms max lag. and thats on a single core at 1.3ghz and onboard graphics. the typical game ready PC is more like 4 core at 3+ ghz with a gtx 700 or 900 series card. i could easily goto 30 fps on such a machine, putting max lag at about 66ms, and min lag at about 33ms minus time to poll (which is negligible compared to render and update).

i think i'd take a lag range from 33 to 66 ms vs one of 33 to 233 ms any day. although it would not animate as smoothly at 30 fps as it would at 59-60 fps.

there seems to be this obsession with going faster. at some point surely we must be fast enough, and can stop trying to go faster, and can instead concentrate on trying to do more at the same speed.

back when the world was first addressing the issue of how fast is fast enough, movies ran at 24. some folks said 24, other said 30. i did some experiments to determine the answer. the answer i cam up with was 15 Hz. the entire simulation must run at at least 15Hz to be sufficiently responsive. 30 if you want it to be snappier (increased responsiveness) with smoother animation. most of the world at that time, doing graphics heavy shooters without much game under the hood, settled on 30 for nice animation. and they could get away with it given the sparse environments rendered and the limited depth of the simulations. i chose the easy way out and settled on 15. that way i have much more time to render and update before i must present. and the games are still playable. most folks don't even realize they run at just 15fps - until you tell them. and nowadays, PCs are fast enough i can kick that up to 30 fps and still have plenty of time to do everything required. maybe even 45 or 50 fps.

one must always be mindful of the impact of changes - even changes made in the name of speed.

>> I'm pretty sure he was joking....

see, things are so whacked in game development i couldn't even tell! i've seen some really crazy and stupid sh*t come down the pike over the years. i used to think its was only regular software development that was full of idiots. time has proven otherwise.

that's why i tend to favor this site, as sane engineering practices tend to prevail here. a rare thing. hard pressed, i might come up with perhaps half a dozen to a dozen similar sites at most - and none specialized towards game development.

>> What do you mean with this? updates and frames is not the same thing as game turns

i later realized what hodgeman meant. they poll at 5 hz and update for 200ms, so the player still gets a fair share timeslice. physics runs at faster speeds, similar to stepped movement for projectiles, for greater accuracy, but the overall timeslice length is the same (i assume).

as for turns, vs renders, inputs, updates, cycles, main-loop iterations, etc...

its gets a bit complicated once you unlink things. FPS is no longer the same as inputs per second, or updates per second. and FPS is no longer the same as the input-update-render-present cycle. i find the use of the term "turn" defined as: present, input, update, render results (immediately followed by the next present, beginning the next cycle) is hel[pful. whether these are serial or parallel, the time for a "turn" is whats important.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

This topic is closed to new replies.

Advertisement