1
\$\begingroup\$

So i was wondering how games handle input so that the input is still handled even in cases of the frame rate being really low. Assuming the input logic is in the same thread as the rendering in the main thread. If the input is handled by some popular API (SDL/SFML/etc) the code will look something like this as a simple example:

if(KeyIsDown(keyCode))
{
    // do stuff
}

If the game is lagging then the above solution won't be able to catch the input cause the code won't be reached cause it is running behind. I notice in some games though when the framerate is low some games are still able to capture input. So if pressing Esc while the game is lagging eventually the key press will be registered. Is there any implementation of how this might work?

\$\endgroup\$
  • \$\begingroup\$ Even if your framerate goes down to 5fps, it means your condition is still checked 5 times per second. Lagging and a short drop in fps, though undesirable, doesn't mean nothing works anymore. If your program grinds to a halt because it can't catch up a fps drop you have more than input problems. \$\endgroup\$ – ElDuderino Aug 13 '15 at 10:47
  • \$\begingroup\$ I'm talking sub 1 fps, if it takes 3 seconds for a frame or more. Even at 5 fps, 200 ms is a long enough time for a button press. \$\endgroup\$ – user240713 Aug 13 '15 at 10:49
2
\$\begingroup\$

There are two options for receiving input, generally.

The first - and most common in general applications - is to use the OS event queue. This is PeekMessage/WaitMessage in Win32, or SDL_PollEvent/SDL_WaitEvent in SDL2, and so on. With this model, it doesn't matter how slow your application becomes, as the input will be put into the queue and the app will eventually see it.

The second method - common in games - is to poll input devices directly. This would be how XInput works in Win32 or SDL_GetKeyState in SDL2, for instance. In these APIs, you only see input in its current state, so if you don't poll frequently enough you might miss the user pressing a key or the like.

Each have advantages and disadvantages. The OS messages often don't have precise timing information nor do they support high-resolution devices or low-latency devices, but they work well enough for quite a few games. The polling methods are more difficult to use correctly but if used right are more accurate.

In either case, your application's frametime shouldn't affect input. Don't render or do game logic on the same thread that reads input. The game should be run in a separate thread from your main thread (the one reading OS events), which is a good idea anyway (the main thread should poll the OS queue and call the Present function for your graphics API and that's about it). If you're doing polling, consider offloading that to an input thread. Alternatively, just sample input more often in a frame, e.g. read the OS event queue or poll input devices more than just once per game loop.

\$\endgroup\$
2
\$\begingroup\$

There's a pretty simple explanation to this. When a game is lagging, it means the entire system is under stress, and as such, lagging as well (while in the game at least). So when you hit an input, the OS registers it, and sends it to the game. But if the entire system and thus the OS are lagging and behind, the input will be queued up, and then once reached, it will be executed. Usually this effect doesn't show up on small, non-extremely-graphically-intensive games until sub-5 or 10 FPS, and most prominent once under 1 FPS, because the OS and the game have so much to deal with.

So, simply, there usually is no solution to this. But in all the laggy games I have dealt with, every single one eventually turns up the input key I pressed. Unless of course it is a Triple-A game that once it lags enough discards buffers.

On the other hand, if you are talking about a stock game engine such as Unity, if the FPS drops below 1, and such Update () and FixedUpdate () are both called less than one time per second, there is nothing to do really other than hope that the OS is queuing up your inputs.

In the case of Unity, there is a way around this problem, but it requires you go outside Unity to a native library to get your input. There are some more advanced input handlers out there on the Unity Asset Store such as Rewired but that really comes down to preference.

\$\endgroup\$
  • \$\begingroup\$ For the most part whenever games lag i think it is due to a GPU bottleneck so usually the OS is free. But yes i get what you are saying if it's a CPU bottleneck, odds are even the OS will miss input and that can't really be avoided. \$\endgroup\$ – user240713 Aug 13 '15 at 21:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.