Before I joined Microsoft, I had never heard the term “test cost”.
(cue joke about how this is because I used to work in game development, and game developers never bother to test anything 🙂
But of course I tested my work. Every good developer has an instinctive understanding of how to design code that will be robust and easy to test. I just didn’t have a name for this concept. Names are powerful things: they give solidity to abstract concepts and make them easier to discuss with other people.
“Test cost” refers to the idea that some features are easier to test than others. If a design is easy to implement but impossible to test, it may not be such a good design after all! Sometimes it may be worth spending more time on the implementation, or cutting a feature even though you had time to implement it, in order to make sure your product is thoroughly testable.
Which brings me to the topic of overscan.
Overscan refers to the fact that most televisions do not actually display the entire picture they are given. They usually crop off some amount around the edges. So if your game draws important graphics at the very edge of the screen, these will not be visible to many players. To make sure everyone will be able to see them, all graphics created for TV (including things like DVD menus and news coverage as well as console games) are expected to keep their important material within the inner 80% of the screen. This is referred to as the safe area. For more details, see this sample (and the doc that comes with it).
Myth: “Overscan only happens on crappy old standard definition CRT hardware. My game runs in 1080p, and is optimized for high definition plasma screens, so I don’t have to worry about this obsolete problem”.
Unfortunately this is just not true. Some modern HD displays have no overscan. Others have lots. Likewise some crappy old CRT displays had no overscan, while others had lots. Overscan is very much alive and well, so the safe area remains with us for the foreseeable future.
What to do about all this? We could keep important graphics away from the edge of the screen, but then what about people who happen to have no overscan on their particular TV? Maybe we should make this configurable? And what about people who want to run in different resolutions, or choose when to use widescreen mode? That’s an awful lot of different options to support.
Join me while I travel back in time to the murky depths of 2002…
We supported many display options in MotoGP:
- On Xbox, we used an 80% safe area for things like the speedometer
- On PC, we had no safe area so these things were drawn at the very edge of the screen
- We could use a standard 4/3 aspect ratio
- Or we could run in 16/9 widescreen mode
- We had a single player mode
- And we had splitscreen mode with 2, 3, or 4 players
- The player could choose whether the 2 player split was vertical or horizontal
Splitscreen plus safe area was a particularly awkward combination. For instance, when drawing the top left portion of a 4 player split, we had to apply the safe area to the top and left of the viewport for that player (to make sure everything would be visible to them), but not to the bottom or right (so as not to leave a ridiculously large gap between each viewport).
Here’s how we made this work:
- For 3D rendering, we just drew to the entire viewport for each player, regardless of safe area. It didn’t matter if some of the edges got cropped off, since the camera would keep the important gameplay action in the middle of the viewport.
- To keep the aspect ratio correct, the 3D projection matrix had to take into account whether we were in 4/3 or 16/9 mode, and whether we were using a vertical or horizontal 2 player split.
- To keep everything looking good, we had to tweak the camera field of view differently for every combination of aspect ratio and split screen.
- For 2D overlays such as the speedometer and lap counter, we computed a modified version of the viewport for each player, which took the safe area into account. In 4 player split mode, this would remove some space from the top and left of the first player, from the top and right of the second player, etc.
- All 2D overlays were positioned relative to this modified viewport rectangle. For instance we drew the lap counter at the top left of the safe viewport, and the speedometer relative to the bottom right, using a bottom-right alignment mode so it would always align exactly to the edge of the safe region.
This system was very flexible. We could change the region computations any way we liked for each platform and display mode, and all our UI components would automatically adjust their position to take this into account. As long as we didn’t make the viewport too small, anyway, in which case UI elements from opposite sides of the screen would collide with each other 🙂
Our design worked well, did everything we needed, and was quick and easy to implement.
But it was a nightmare to test. There were so many different options, it took forever to try them all, and we would often write code, check it in, then go weeks before we noticed a problem that only occurred in, say, widescreen 16/9 with a vertical 2 player split on PC, but not Xbox. We also had many different game modes, each of which had different UI components, so it was incredibly laborious to make sure all the possible permutations worked as intended and looked good.
If you really need that much flexibility, by all means pay the cost (I still think it was the right choice for MotoGP) but make sure you consider the test cost as well as implementation cost when making this decision!
If you are creating an Xbox LIVE Community Game, you have a simpler option:
- Always use 1280×720 (720p) resolution
- Always use an 80% safe area for your important graphics
- Always construct your projection matrices using a 16/9 aspect ratio
If you program this way, your game will run correctly on every Xbox and TV. The Xbox will automatically scale or letterbox the image if the TV has a different resolution or aspect ratio, so you don’t need to bother handling these things yourself. And because we already tested the system scaling features, what’s your final test cost for all this?
That’s a zero…