I disagree. Handling input can’t be done asynchronously this way. In order to maintain logical flow, there is a very specific time and place where input is handled, and it is always within the logical loop.
if your FPS character is controlled by mouse, it is quite important that the mouse events are processed as soon as the arrive to change the characters orientation to get the feeling of responsiveness. Even if your simulation is running at 30 fps for example, you can update your player directions as often as you draw a frame.
Since it is inside the logical loop, people such as kunos are correct in pointing out that increasing the resolution of your logical update is one way to get increased “response” from your input handler, but it is the wrong way.
Of course increasing your logical resolution will invariably help to smoothen your input flow, but excessively sensitive input flow is only necessary in the most extreme cases, such as racing games or fighting games. Since 95% of all games are not this sensitive to input, stutter 95% of the time indicates that there is some kind of underlying problem with the input handler.
I didn’t want to go into this measure of detail until the topic-poster needed it, but the basic idea (again I am leaving out details until proved necessary) is that the logical process will happen every “certain amount of logical time” which has no correlation to real time, except that it can not go faster than real-time.
Because of that constraint, the amount of input that can be processed in a single logical update is also supposed to be limited.
For example, you see your game lagging and you start waving your mouse around. The mouse commands sent to the engine are as recent as real-time—that is there are enough mouse commands to handle from the start of the logical update (whatever time-stamp that is) until the actual real-world time-stamp.
It doesn’t make sense though to actually eat that whole buffer if the logical update is only a fraction of the way from its starting point to the real-world time.
Each input needs to have a timestamp, and each logical update should only consume as many inputs as were created during the span of that input.
In other words, it must be as follows:
-> Last frame ended at t=90, but the real-world time now is t=2,000.
The update interval is 30, so I need to perform 63 updates.
My first update goes from t=90 to t=120, but the input queue has inputs from t=90 to t=2,000.
If I eat them all in one update, I am obviously doing it wrong.
-> -> Request and process only inputs from t=90 to t=120. This is correct.
Within this same cycle I will be processed 62 more times, and I can eat inputs incrementally until then, at which point I will have gotten them all.
The resulting output is virtually the same no matter what your update speed is. Notice that I said “virtually” here. Every update speed will yield a new result, but humans can’t notice the difference in those results except in extreme situations such as racing simulations and in fighting games.
On the other hand, computers can notice these differences, so any networking games must absolutely ensure the same strict simulation on all platforms, which is again why it is bad to pick an update resolution that is any larger than it must be, and also one that is variable.
The update resolution should always be the absolute minimum necessary for proper functioning of the game (aside from my own suggestion, there is a citation on this, but I am annoyed to report that I can’t find it right now).
This was the basis behind my original controversial sentence that such-and-such update timings are not acceptable. You should always think critically as to whether or not you actually need X resolution, and generally you should have both smooth input and stutter-free graphics at almost any update resolution, so if you experience stutter or friends at any resolution you should probably be looking at other parts of your engine. Of course there are cases where the only solution really is to increase your update resolution, but these are fairly special-case and advanced, and anyone whose solution really is this should already know the concept of update interval very well, so this is not the case here.