User Controls dependent on graphic rendering loop?

Hello everybody,
I have a straightforward question: Would you advise to keep reactions to key and mouse events in the same loop as the rendering or should it use it’s own loop?

Keeping it in the rendering loop makes it simpler to implement and prevents you from introducing concurrency problems because the rendering takes place before/after e.g. the player movement is done. However, if the rendering performance goes down for many possible reasons, the user controls would become wonky and unreliable. I know from some older 3D games that you couldn’t even reach the normal exit execution because the graphics went crazy.

To be more specific about what key/mouse controls should be possible: 1) simply holding the key for continuing effects (e.g. move forward), 2) detect how long an event was performed, 3) detect very short events. I yet have to have a deeper look into synchronzied methods/blocks/variables which might make stable concurrent programming less of a untouchable ghost :). None the less I am interested in more experienced opinions.

Use discrete time steps. Logic and rendering should be completely decoupled. It is not necessary to use separate threads to do so. Choose a graphics update rate (frame per second) and logic update rate (ticks per second). If TPS is greater than 30Hz or 20Hz, then just redraw every time you update. If TPS is less than 20Hz or FPS is at least twice as fast as TPS, then measure the time between updates (normalized to the range 0.0 to 1.0) to use for interpolation. I use complete integration of position, velocity, and acceleration when I need to, but linear interpolation works well enough. Interpolation may not be necessary at all if your FPS is high enough. The purpose is just to add extra frames if things do not look smooth. Whatever you choose, your rendering strategy should not affect the game’s logic.

A single loop is enough to do rendering and updates. Just check to see if the current time is later than the next scheduled render or update time. (Make sure to use a while loop that adds time to the previously scheduled time and not an if statement that updates once and adds to the current time, or else you will lose time and update less than your normal rate. See the topics here about game loops.)

If you buffer/log input events (look at the relevant classes in LWJGL JavaDoc for an example) then you can do any operation like measure how long a key was pressed, know how early it was pressed, and know how many times it was pressed and released. It’s a better solution than polling in your game logic. It can be done with Java2D as well since it is event based and gives you a timestamp of each event.

Your stuff is on its own loop (two if you have a lighting code or something that uses a lot of cpu time) and then have all the other stuff such as keylisteners left alone.

There are 2 methods for input handling : polling and listening.

Polling is the method where input is caught and stored and the store is made available for the main loop. This means a separate thread is listening to the input, putting events into a collection and then the render loop takes a look at the collection something like “input.isKeyPressed(W)” or “input.isMouseDown()”.

It is very simple to implement, You don’t have to deal with threading (since the inputs are available in the main loop). The caveat however is, that after each render, the input collecetion is cleared and the actual mouse button click might happen just before clearing, that means occasionally input events can be dropped, the more so, the lower is FPS (with a higher frame render time, there is a higher chance that the input happens during the wrong time)

This isn’t a problem if Your application is one where input is not continuous, like some clicks here and there, some key presses here and there. Or in places with constant input, like holding down a move key (since the key is always pressed, there is nothing to drop)

The other method is listening. This means that the game itself gets the IO events as soon as they happen. As the description suggest, this basically means You have to manage the IO thread and event management Yourself. This method is more precise, but because of that is also more complex.

This method is good for applications where You are dealing with rapid input, like maniacal clicking or key smashing. Basically places, where dropping an IO event is not acceptable.
Also with this, the IO events enter Your application in the order they were created. (With polling method, You either have the IO or not, there is no ordering)

In conclusion, polling is quite alright and sufficient for most games and with polling method, user controls do depend on rendering loop.
Listening method is more for UI, where it might be important to know in what order mouse buttons were pressed or key presses were made. However with listening, You have to manage the merging of events and gameloop Yourself.