Bringing Doom 3 BFG Edition to the NVIDIA SHIELD
Doom 3 BFG Edition is a re-mastered version of Doom 3 for the Xbox 360, PS3, and PC that was released in 2012. NVIDIA worked with id Software and Bethesda to bring it to the SHIELD Tablet and SHIELD Android TV. This article highlights some of thing things that went right as well as wrong.
What Went Right?
The Doom 3 BFG Edition renderer was using OpenGL on the PC, and since the Tegra K1 and X1 chips support full OpenGL, porting that over was trivial. There are no changes to the renderer from the PC version. The only thing we had to do was switch from using WGL (the Windows GL interface) to using EGL (the Embedded GL interface). We also had to dynamically fetch the OpenGL entry points at startup (using eglGetProcAddress) since they cannot be statically linked on Android.
Doom 3 BFG Edition was originally developed using Visual Studio 2010. It used a single solution for all 3 platforms (PC, PS3, 360). AndroidWorks made it extremely simple to add a 4th platform for Android. Having all the platforms in one Visual Studio project made it easy to keep the other platforms working for comparison. Being able to edit, build, deploy, and debug for all platforms all within a single IDE was a dream compared to messing with Makefiles and GDB or having to use a different IDE for each platform.
Doom 3 BFG Edition made extensive use of SSE intrinsics for calculating shadow volumes. Converting all that code to use ARM Neon intrinsics would have been time consuming and error prone, so instead we wrote a translator that could convert the SSE intrinsics to Neon intrinsics. The automatically translated code was significantly faster than the C version, and only marginally slower than the code we had initially translated by hand. The game ran at 60fps after this, so further optimization was not necessary.
The original game was distributed using a resource file for each level. The total size of all the resources put us well over the 4GB limit for apps on the Google Play Store. It was done this way to improve load speeds on the consoles, but flash memory has much faster random access rates than reading from an optical drive, so splitting the resources by level is not necessary for the Android version. Merging all the resources into one was just a few megabytes over the 4GB limit, and placing a few resources in the APK itself brought our expansion files below the 4GB limit.
The in-game videos and intro videos were using Bink on the other platforms. Rad Game Tools had a version of the library for Android that just worked without any problems.
Bethesda and id
Working with Bethesda and id Software was great. They were always just an email or phone call away, and delivered anything we needed in a short amount of time.
Using the standard input handling code from android_native_app_glue and mapping that to a generic input format that Doom 3 expected was straightforward, however we were getting ANRs (App Not Responding) during load screens because Doom 3 performed loading on the main thread and didn’t process input while loading. To fix this, we created a background thread which attached to the input queue and stored input events in a buffer for the main game to process at its leisure.
The Doom 3 BFG Edition sound system had back-ends for XAudio (for Windows and Xbox) and Multistream (for PS3). Neither option works on Android, so we needed to create a new audio back-end. OpenSL doesn’t support all of the features that the Doom 3 sound system uses, so we looked at using a middleware solution for software mixing. We narrowed it down to FMOD and Miles, both of which have nice APIs with great support. Ultimately, we chose FMOD because it had support for low latency audio on Android (Rad Game Tools tells us they are planning to add this to Miles). Rewriting all the sound code for Doom 1, 2, and 3 and re-encoding all the wave files took more time than anticipated.
Since Doom 3 uses a lot of memory, Android tends to kill it when it goes to the background. We auto-save the game, but it’s not a very good user experience to have to restart the game after accidently pressing the home button. To prevent accidental button presses, we added a confirmation prompt which is enabled by adding this line to the manifest:
< uses-permission android:name="nvidia.permission.DOUBLE_CHECK_HOME_PRESS" />
What Went Wrong?
Move to SD Card
The initial version released on the Google Play Store was missing the manifest entry to enable the “Move to SD Card” functionality. Since the game is 4GB, this caused many customer complaints. This was an oversight on our part and corrected in an update. Games should always add this to the manifest:
< manifest ... android:installLocation="preferExternal" />
Third Party Controllers
We only tested the SHIELD controller and the Google Nexus controller, and wrongly assumed that all other controllers would work the same. After release, we received customer complaints that other 3rd party controllers were not working correctly. We purchased as many Android controllers as we could find updated the game to support all of them.
We used Google Play Games Services for implementing cloud saves. Unfortunately, they don’t work if the user is not connected to the network. This isn’t a huge problem for SHIELD Android TV, but is a big concern for SHIELD Tablet. We received a number of customer complaints about this, so we updated the game to support saving locally and synchronizing with Google Play Games when the network connection is restored.
Support for Older OSes
When the game was released, it only worked on the latest version of Android. There was no reason it wouldn’t work on earlier versions, but some misconfiguration in the manifest caused it to show up as “Incompatible” in the Google Play Store. This was fixed in an update.
Doom 3 is an extremely violent game. After filling out the content rating survey in the Google Play Developer Console, the USK (German ratings board) refused classification, which means we could not distribute the game in Germany. Doom 3 was classified as 18 on the other platforms, but ratings are done per-platform. We had to appeal the decision and get it rated as 18 on Android as well, but this was not completed before launch. We received approval and were able to release in Germany a week after the rest of the world.
To learn more about developing for NVIDIA SHIELD go here.
Doom 3: BFG Edition is the definitive version of id Software’s horror-themed FPS hit.