The PlayStation Portable is a console with many nice features, but its long loading times are a bit of a disaster. This may seem like a bit of a trivial issue, but the loading sequence and opening menus are the first thing you see when you try out a new game and something you’ll see every time you play: a bad experience here can be hard to make up even if the rest of the game is good. The PSP’s loading times have prompted articles at Ars Technica and IGN, a hall of shame at GameSpot, and many YouTube videos, of which the best is this one contrasting the six-minute (!) load time of WWE SmackDown! vs. RAW 2006 with the one-minute load time of GripShift:
Amusing as this demonstation is, even the one-minute load time of GripShift is not exactly brilliant. So how did we get to this state of affairs?
The basic reason is Sony’s choice of Universal Media Discs (UMDs), a form of optical disc, as the medium for delivering games, instead of cartridges. The low cost and high capacity of optical discs make them very attractive to manufacturers, but this comes at the price of low data rate and high latency. This applies to all consoles: Nintendo held off switching from cartridges to optical discs for a generation longer than the other manufacturers—the Nintendo 64 was still using cartridges when the Sony PlayStation and Sega DreamCast had switched—partly because of the loading time issue. However, it applies especially to portable consoles, because of the casual use pattern of a handheld device (when you’re only playing for a few minutes at a time then loading times stand out more), and because the low power available from a battery means that the disc in a portable device can’t be spun or accelated very fast, reducing the data rate and increasing the latency.
However, Sony’s hardware design is far from the whole story, because although UMDs are slow, they are not slow enough to explain the actual observed loading times. You can see from these specifications that the PSP has a memory of 32 MiB, and that UMDs have a transfer rate of 11 Mbps, so it’s possible to completely fill the memory from disc in only 23 seconds. Anything noticeably longer than this is a sign that the developers could have done better.
Where does the time go and what can be done about it?
Seeking. A level of a game needs hundreds of assets—models, textures, animations, sound effects, fonts, localized text, and so on—and if the seek time to find and open a file is, say, 0.2 seconds, you’re wasting 20 seconds if you loading 100 assets from 100 files. This kind of performance may come as a bit of a shock if you’re used to hard disks with typical seek times of 0.01 seconds or less. By packaging all the assets for each part of the game into one file, you incur only one seek penalty. This may mean that some assets appear in several packages—for example, environment textures (walls, rocks, grass etc.) will probably be used in several levels—but UMDs have a lot of capacity (1.8 GiB) so for most games this isn’t a big deal.
Loading. Compress your data. The PSP can decompress Lempel-Ziv faster than the UMD can deliver the data, so you can win by the compression factor, which for typical video game data is quite high, 50% or more.
Initialization. Your graphical tools generally don’t produce assets in quite the right format to be used in the game, so there needs to be some post-processing, for example of texture formats, colour palettes, animation sequences. The easiest place to do this processing is at run-time in the game itself, but that’s a waste of time: any work you can do at build time saves your players, whom you hope will number in the millions, substantial time twiddling thumbs. So make your disk format for assets be very close to their format in memory, so that your initialization code after loading just needs to patch up some pointers (like a relocating loader, which does basically the same job that you’re doing here). So your build process might need to be a bit more complex. (And if you’re using dynamic languages like Lua you should restore an image with initialization complete, not start from scratch and run all your initialization code in the game.)
Reloading. In the case of assets that you’re not going to use right away, for example textures that aren’t yet being drawn, you can defer decompression until the asset is actually being used, allowing you to pack more assets into memory and reduce the need to go back to the UMD to get more assets later. Design your levels with the maximum capacity of main memory in mind. The game will play most smoothly if you can load all the data for the level at its beginning, and never revisit the UMD until the level’s over. This avoids any loading delays that might interrupt the flow of the level, and it means you don’t have to implement complex mechanisms for loading data while the game is playing (with all the problems of handling errors, e.g. if the UMD is removed).
Corporate logos and legal messages. Players don’t care, and they certainly don’t want to waste their time watching a spinning 3d nameplate every time they play the game, but unfortunately you’re contractually obliged to disappointment them. (Brave developers might put all the logos and legal text onto a single screen, perhaps saving the full logos for the credits or some other spot in the game. But who has that kind of courage?) So put this time to good use by loading something else while they are displaying.
Fancy front-end menus. If you can’t get to the game by pressing the cross button a few times then you’ve made the menus too complicated.
Cut scenes. Design your game so that cut scenes can be displayed using the assets for the level that immediately follows them. Or at least that the assets for the cut scene and the level fit into memory at the same time. That way, there’s no loading delay between the cut scene and the level.
None of these suggestions are technically difficult, especially when compared to many of the things that games do well.
So why do many games do so badly? I think there are probably three main reasons.
Lack of management oversight. In larger video game projects, the developers are divided into teams, by functional area (for example, physics, graphics, audio, toolchain, etc); and by section of the game (for example, gameplay, menus, cut scenes). This division of responsibility works well for aspects of the project that are specific to one of the teams. However, aggregate loading times are an emergent result of decisions made by several teams, and reducing them means coordinating their work. This is likely to cut across areas of management responsibility and so fall into the cracks because no one person is responsible.
Discovery late in the development cycle. The early focus in video game development is on getting the riskiest features in place: gameplay, graphics, networking. Stuff that is less risky (background music, sound effects, menus, adjusting difficulty, graphical polish, framerate) can be left until later. This means that with the early focus on functionality, loading times don’t become clear until very late in development. But at this late stage it’s too risky to make big changes like number 3 in the list above.
People don’t care enough to do anything about it. This is an issue of resource allocation in development: in order to improve loading times (or any other aspect of a game) you have to allocate someone’s time and effort, which could have been allocated somewhere else. There’s always hundreds of things about a game that can be improved, so you have to take a view about which ones are most important. I think there’s a tendency among some developers to take certain “sexy” features—numbers of polygons, realism of character models, complexity of AI—more seriously than they deserve, because these are the things that get commented on in magazine reviews, and they are easy to show off in demos and screenshots. Issues like loading times, ease of use of menus, saved game management are not very exciting, can’t be made very appealing or shown off to the public. And yet they make a big difference to the quality of a game.