I'm implementing a GUI system to look around a 2D tile-based world. At the moment, I'm updating it every time the mouse moves (which happens to be per frame, since that's when it polls for events). However, I'm wondering if implementing it per-update (by taking all input events, averaging them out, then deferring them for processing until the next update) would be better. I figure it would make the GUI feel more consistent but at the cost that it may not be as responsive (since I can't interpolate the movement without the controls feeling "sticky"). In terms of creative a better interface, which should I go with? What do games normally go with?
2 Answers
What's the context?
For UI, it's very sensible to poll per-frame, especially for cases where the UI and the game simulation have no good reason to be tied together, e.g. highlights when you mouse over a selectable object.
For control of a character or the like inside the game simulation, this advice can be flipped. Consider batching up all inputs for character control and then applying them during the next simulation update. This will be implicit in any physics-driven game, of course, since even if you set an input force at each frame, it won't actually have any effect on the simulation until the physics updates next.
Yet other inputs are "continuous" and don't really fall into the above states. Consider a joystick. You probably don't care at all about the events in yrou game and instead would just care about sampling the direction and magnitude of the stick's offset whenever it's time to try to apply input to the target object.
And then there's even the option of putting input polling and your main loop on separate threads so that you can sample input far more frequently, which can essentially nullify the entire question. This is common for more twitchy games that need to absolutely minimize all input lag.
-
\$\begingroup\$ Some games, like twitch shooters, have even been known to poll for mouse/gamepad input multiple times per frame to get latency as low as possible. \$\endgroup\$Nathan Reed– Nathan Reed2015-07-28 04:30:09 +00:00Commented Jul 28, 2015 at 4:30
-
\$\begingroup\$ @NathanReed: is that different than what I wrote in my last paragraph? Do you mean that they hard-code extra input polls in the game loop rather than using threads? \$\endgroup\$Sean Middleditch– Sean Middleditch2015-07-28 04:37:26 +00:00Commented Jul 28, 2015 at 4:37
-
\$\begingroup\$ Oh, for some reason I didn't see the last paragraph. :) But yes, there are sometimes multiple points in the game loop where input is accepted, e.g. once during update/simulation and again at the last moment before submitting rendering, to tweak the camera matrices for the latest movement. Actually I'm not sure what it would accomplish to put input polling on a separate thread, if the game loop only accepts input from that thread once per frame. \$\endgroup\$Nathan Reed– Nathan Reed2015-07-28 04:41:05 +00:00Commented Jul 28, 2015 at 4:41
-
\$\begingroup\$ It's more for time-sensitive stuff, e.g. "the button was held down for Y milliseconds" or for when you want to do your own accumulation of input mouse/joystick micro-movements. Polling in the main game loop limits your resolution of that kind of stuff. You're right though that the game needs to be ready to actually apply the input for it to be useful for affecting gameplay with less latency. :) \$\endgroup\$Sean Middleditch– Sean Middleditch2015-07-28 05:15:21 +00:00Commented Jul 28, 2015 at 5:15
It depends on what you want to do, whether it's GUI-like or game-like.
Most game situations only care about where the mouse is right now, so you go through all the mouse move events and simply act on the last one. This would be per-frame. One example is using the mouse to look.
However, there are some GUI-like situations where the intermediate mouse positions are all important. Consider drawing freehand curves using the mouse - your player could have fast hands and a high-frequency mouse, compared to your slow frame rate. If you only used the per-frame mouse positions, the output would be very jagged. This would be per-event (or what you call "per-update"). It's rare in games, but those using mouse gestures might be a good example.
So unless you have a GUI-like situation where freehand curves are drawn, stick with per-frame, except for press/release events, where:
- you should use the location of the press/release event, instead of the last mouse event, since they can be different
- if you're counting your own presses/releases, count every mouse down / mouse up event, since there could be multiple per frame