There are no cave paintings warning of poor arcade conversions to the Atari 2600, but from a historical perspective there might as well be. Platform conversions have existed since the dawn of personal computers and gaming console systems. Whether a popular Apple game ‘ported’ to Atari or Commodore, or an arcade hit translated to the first gaming consoles, conversions have always been a part of the gaming industry. Some things haven’t changed from those early days; good conversions excite and delight players happy to have a popular game available on their chosen hardware. Poor conversions evoke a particular deep brand of distain. Decades later, the Atari 2600 port of Pac Man is still a poster child for the concept of a ‘shoddy port’. Nobody wants one of those!
They are coming to your platform, and they want 60 FPS!
At Trihedron, we have a long and extensive history of platform conversions, so it was an exciting opportunity to partner with Amazon and Yacht Club Games to bring Yacht Club’s critically acclaimed Shovel Knight to the new Amazon Fire TV. In many cases it can be a struggle to create a faithful adaptation of a game on a new system, whether due to technical challenges from hardware limitations or from trying to modernize an older legacy game on a new platform, enhancing without losing the original charm. There are plenty of conversion retrospectives which focus on detailing these issues, and exploring how various knotty problems were overcome. Shovel Knight was not one of those conversions! Instead, we will look at the factors that made Shovel Knight for Amazon Fire TV a relatively smooth conversion and why the desired end result was achieved without fountains of blood, sweat and tears. That Shovel Knight fit nicely on Amazon Fire TV wasn’t a happy accident, but rather a combination of solid technical foundations and being pointed at powerful hardware that fit the envelope of already optimized code.
One common challenge on conversions is that they are often done by developers other than the original creators, after the original project has been finished. This means that sometimes a complete project archive isn’t available and the port developers might be limited to working with the ‘run-time’ assets of the finished game, not having access to the ‘raw’ assets. This was not an issue with Shovel Knight, we made a decision at the beginning with Yacht Club to directly integrate the Amazon Fire TV version with the mainline development of all other versions of Shovel Knight. This greatly eases ongoing maintenance, since Yacht Club is still working on future content updates for the game which will make their way to the Amazon Fire TV version. It did require some extra care, however, since we were working on the same live trunk that Yacht Club was using for their development. We had to make sure that Amazon Fire TV changes didn’t introduce any problems as Yacht Club were working hard to finalize and submit the big Plague of Shadows update across several other platforms for both digital and physical release.
Integrating the Amazon Fire TV version of Shovel Knight as just another build target in the main Shovel Knight project was facilitated by a turn-key Android development package created by nVidia called AndroidWorks. AndroidWorks bundles the existing Google Android development tools in a unified installer along with some additional tools created by nVidia to assist Android development. Since the Amazon Fire OS is built on top of Android open source OS releases, AndroidWorks was directly applicable to Amazon Fire TV development. Perhaps the useful element of AndroidWorks is the Nsight Tegra plug-in for Visual Studio. Nsight adds MSBuild and debugger integration for Android into Visual Studio, which is a huge step up from wrestling with the stock NDK-Build and gdb tools included in the Android Native Development Kit (NDK). The ability to have Android (and thus Amazon Fire TV) be just another target in Visual Studio, identical to all of Shovel Knight’s other platforms, made project setup and maintenance much easier.
Setting Android project settings in Visual Studio with NVIDIA Nsight Tegra
The fact that Shovel Knight was originally intended to, and already did run on several other platforms was a major factor in the ease of porting it to run on the Amazon Fire TV. Code portability problems on conversions have two common root causes. For some projects, they might have started off as a game exclusive to a particular platform. Because of that, the code ends up tightly coupled to the hardware and/or software stack of that platform, either to squeeze out maximum performance or best take advantage of unique platform capabilities. The other common cause is a lack of concern for other platforms during initial development, or a focus on fastest/least effort which excludes consideration of systems other than the one currently being targeted. In this case, code tends to be tightly coupled to the platform the game was originally developed on not by implicit design, but because either no thought was taken in having it run on other systems, or that the time or effort required to write abstractions was viewed as unimportant or infeasible due to resource constraints or other factors.
Regardless of the reason, code that is tightly linked to a particular platform can involve significant effort to port, for example, a codebase that uses entirely Microsoft WIN32 API calls, or a project which has a graphics renderer written only for a custom graphics API specific to a particular gaming console.
For Shovel Knight, Yacht Club built the game on an internally designed custom game engine that was intended to support multiple platforms. The actual game code for Shovel Knight sits on top of this engine, which abstracts away the majority of platform-specific concerns. The engine also encompasses an asset build pipeline with the flexibility to build the game assets as appropriate for each platform. Because of this, porting Shovel Knight to Amazon Fire TV involved almost no interaction with the higher-level game code or the ‘raw’ game assets, but rather implementing Android target support for the Yacht Club game engine and asset build pipeline.
Specific functional elements that had to be implemented for the Android target included such building blocks as: file I/O, threading and memory management, graphics rendering, controller input and system event processing. In the case of graphics rendering, the Windows version of Shovel Knight was already using the Google ANGLE project as an OpenGL abstraction over Direct3D. Because of this, writing the Open GL ES renderer for the Android target was done by modifying the existing Windows renderer versus having to write one from scratch. The takeaway lesson is clear: unless you have a specific reason (whether technical or business) to tightly couple your code to an existing platform, building on a multiplatform framework is essential to efficiently publish your game on a variety of systems. While writing platform support for multiple platforms is a daunting task, there are a variety of open source and commercial engines which can reduce the amount of work required to have a multiplatform base for your project. Even if you are only starting out on one platform, the additional flexibility later on is worth the additional work.
The Amazon Fire TV Gaming Edition
As we have learned, having a project designed for multiplatform was one major factor in a smooth Shovel Knight conversion to Amazon Fire TV. Another was that the Amazon Fire TV hardware was a good fit for the existing Shovel Knight software. The Amazon Fire TV has a significant amount of CPU and GPU horsepower, and a healthy amount of RAM. Shovel Knight already had a well-defined performance envelope, which had to size to fit its ‘least-powerful’ targets, dedicated handheld gaming systems with less RAM, CPU and GPU performance than the Amazon Fire TV. Indeed, existing optimizations that were required for these less powerful systems helped ensure the game performed optimally on the Amazon Fire TV. Despite its raw horsepower, for example, the GPU in the Amazon Fire TV can still be bogged down. A prime example would be, when rendering at a 1080p resolution, if care isn’t taken in regards to certain performance limitations, such as alpha-blend enabled fill-rate. Shovel Knight already had optimization profiles to separate translucent (or more precisely in the case of Shovel Knight, transparent) and opaque sections of sprites and background layer art into separate drawing passes to maximize the amount of pixel rendering performed with blending off. These configurations were enabled for the Android target. For a game like Shovel Knight, where you never want to drop below 60 frames per second, especially during moments of crazy action, these optimizations provided welcome headroom in the rendering time.
There was one custom optimization implemented for the Amazon Fire TV version of Shovel Knight which wasn’t done for reasons of game performance, but rather optimizing storage space. Although the Amazon Fire TV Gaming Edition comes with a storage card which greatly expands the storage space of the device, on the original Amazon Fire TV, or the new Amazon Fire TV without a storage card, space on the device is at a premium. All of the game data was being bundled directly into the application package, which is in a compressed format. Because of this, the entire game could be installed monolithically, and only consume around 200 megabytes of space on the device. The asset loading pattern of the game didn’t really need fine-latency streaming support, so using the Android Asset Manager API to load assets by decompressing them out of the application package worked fine. With one exception: attempting to access streaming audio data in this manner can be prone to latency or sound glitches. Since the Amazon Fire TV was equipped with a healthy 2 gigabytes of RAM, the solution to this was straightforward. On application launch we extract all the audio files out of the archive directly into RAM and add I/O hooks to the sound library which allows accessing the cached audio files as if they were stored in a simple RAM disk. The alternative if RAM had been in short supply would have been upon the first launch of the game was launched to copy the files out of the compressed application archive to cache them uncompressed in the application data storage area. However, this would have greatly increased the storage requirements of the game, which is something we wanted to avoid.
Plague Knight has a potion to optimize application size
Since storage space can be at a premium, even though Shovel Knight has a pretty minimal footprint, it is quite possible that users might want to uninstall it to free up space and reinstall it later. The catch, of course, is that uninstalling the game also removes the save data. Amazon’s Whispersync for Games cloud storage system proved a useful solution to this dilemma. By incorporating Whispersync for Games support, we can push the user save data to the cloud, allowing it to be restored upon reinstall. When you are designing your game start flow in a cloud storage world, it is useful to take certain aspects into consideration. Traditionally, games usually assume file I/O is available very early in the initialization process and tend to check for save or settings data almost immediately. To support cloud storage means not making assumptions of immediate availability. Even if you initialize the cloud system as early as you can, you may still have to wait a while in computer terms (on the order of seconds) for a cloud system to report it is ready or that it has new data. This can be awkward to retrofit into startup logic if it wasn’t initially planned for. But the benefits of cloud storage support are well worth the added code design considerations.
To conclude, platform conversions don’t have to be arduous exercises in masochism! Conscious design decisions can greatly ease the effort involved in moving your game to new platforms. And, making sure that your project runs well on a least-common denominator target can help you avoid slipping into lazy habits that require later optimization. Since the group at Yacht Club Games was proactive on both fronts, bringing Shovel Knight to the Amazon Fire TV was a pleasant project to work on, and the end result should be pleasing to gamers everywhere.