"if your interface does not respond within a tenth of a second, the player will feel like something is wrong with the interface." - James Schell, The Art of Game Design: A Book of Lenses 1
Up to 1 second is the cut-off for a user's flow to remain uninterrupted, though they will not feel in control.
Ten seconds is the hard limit for keeping a user's attention focused. After that, they will want to do other things while waiting for the interface to respond.
You can try it yourself. Each button here will change color when clicked and respond in the time shown in the button text.
Which of them makes you feel in control of the button color? Which of them feels like the computer is in control? Which of them makes you want to rage quit?
There are many solutions to make an interface feel responsive, even when a delay is required to return results: animations, loading spinners, progression indicators, skeleton objects, etc.
Here's one idea to make the buttons respond immediately using a fun pulsing animation I found here.
Notice how you still feel in control even at the longest wait time for a change.
Though the exact solution you choose will likely come from a designer (if you're lucky enough to work with one), a developer's responsibility is to understand which parts of an interface are likely to need these solutions.
Only we know which interactions can return results straight from the client, which need to request results from servers, which requests are produced quickly from a cache or will require expensive processing.
It is up to us to review designs and give feedback on these interface problem areas.
For the development of the Splash game, since the response time for any call to a server is difficult to estimate, we follow a simple rule:
Any button press that triggers a server invocation we must first acknowledge on the client.
Usually we do this via a loading state. In code terms, we're doing this:
interface.onClick = function() toggleLoadingState(true) local response = invokeServer() displayResponse(response) toggleLoadingState(false) end
For some particularly long-running requests, we aim to do them in the background to allow the player to continue to enjoy the game while they wait.
See also the Goal Of A Game Interface.