Monday, December 26, 2011

Progress bars & load screens

Bad Game Designer, No Twinkie! has a new installment up at Gamasutra. As always it's pretty great! I agree with a lot of the criticisms made. However, there is one in particular that caught my eye:
Giant Internet Explorer's little circle goes 'round and 'round, telling me nothing. Yet the tiny, free xScope browser for my Android phone includes a progress bar that shows me how much of the page has loaded. It's invaluable.

[...]Put in a progress bar that fills up, once, until the load process is complete. It doesn't have to be perfect; if you load 2 files and one of them is 10KB and one is 10MB, but you allocate half the bar to the first one and half the bar to the second, that's tolerable. We don't really care as long as we can see movement.

The "donut" of the spinning progress circle gets a lot of shit. I just feel compelled to mount a brief defense of it, since the justification makes sense to me. If I were designing a loading screen, I wouldn't want to draw ire for making an entirely justifiable decision.

First, let's look at IE vs xScope to understand how a donut and a progress bar serve slightly different uses. Internet Explorer is normally on a desktop machine, whereas xScope is a mobile browser. It's safe to say that in the author's case Internet Explorer is more likely to be hooked up to a high-speed internet connection, while  xScope is most likely on a 3G mobile connection. The differences between the two are important. If IE listed out every single element on a webpage and calculated how long each would load, it would probably spend more time on those calculations than actually acquiring the data through its fat pipe connection. On a mobile device, however, two things are important: You send out a mobile useragent, which often gets you a simplified version of webpages, and you have a laggy, slow, fairly unreliable connection. Less elements + higher chance something will hang = better reason to do the calculations to show what's left in the loading process.

Now let's look at the suggestion to fake progress bars with the naive approach of grouping files into buckets and just showing rough estimates progress. In this example, the two files differ by four [Three? - ed.] orders of magnitude. Let's be unrealistic for a second to illustrate a point and assume that it takes 1 second to load a 10KB file. So, you sit at the loading screen, and after 1 second of watching an empty progress bar it goes up by half. Very nice!

Now, let's take our naive loading algorithm and assume that it is linear with regards to file size. 1 second for a 10KB file means to load a 10MB file would take... Oh.

(1 second / 10 kb) * (1000 kb / 1 mb ) * (10 mb) = 1,000 seconds.

After waiting for 1 second to see the progress bar move, you are now waiting 16 minutes to see it move again, according to our naive algorithm. The point is not "this would take 16 minutes to load", the point is that files can easily differ by orders of magnitude, so tying progress to file size means your progress bar will have gaps with orders of magnitude. An experience with large time gaps calls the conclusion ("we can see movement") into question, since the majority of time the progress bar is not moving.

Furthermore, there is user research  on the subject of progress bars - ever watch something hit 99% complete and sit there for a while? It's annoying. Much more annoying than, say, waiting for something to go from 0% to 1%. If you want to do loading "right", you need a non-trivial algorithm to display this information to the user.

So now we have two pieces of data from our thought experiment. One is that a naive approach to progress bars is ineffective and doesn't always give the user an assurance that their box hasn't crashed. The other is that users prefer certain algorithms to displaying progress. This is becoming a complicated issue! If you look at documentation, even the MSDN page for progress bars is full of caveats about usage.

Sims2: Pets loading screen. Progress bar with caption:
"Scolding Splines for Reticulating" [Source]

The reason for the spinning donut is simple. It doesn't give the user information to guess a time to completion, so the user can't be frustrated by that last 1% on a loading bar or a fake progress bar that has no relationship to actual completion. Progress bars, in the context of a game, don't really provide useful information to the user. Showing files and categories loaded might be interesting to some, but The Sims shows complete nonsense to the user and no one I'm aware of has ever complained that "reticulating splines" or "Dividing by zero" is misleading - so how useful can accurate information be? The user, as No Twinkie! cedes, is only interested in making sure their console hasn't crashed. So what additional benefit does a progress bar provide over a spinning donut?

My point isn't that progress bars are always bad. My point is that for progress bars to be effective, they need to be carefully considered in context and implementation. It's not just a matter of hacking together the first thing you think of. It's possible to implement load bars properly, but it takes time and effort and risks aggravating your load times even further. All that time and effort spent will need to be revisited when assets are added or removed. Why not just show a spinning donut instead? Users are always going to be frustrated by load times. A donut is not "accurate", but your loading bar isn't going to be accurate either. If you're working on a game, wouldn't you like to fix 5 or 6 more bugs instead of hyper-optimizing something for no benefit?

Edited to correct minor typos, including "an assurance that their box has not crashed" and an off by one on the orders of magnitude involved. Oops.