Wind-up Knight has just shipped for OUYA. It runs great on the console and is really fun to play with a controller. If you have an OUYA, go check it out! If you don’t have one, $99 is totally worth the price of admission for a cheap, hackable, indie-focused Android game console.
Despite the title of this article, Wind-up Knight isn’t really a port. The binary we ship is almost identical to the one we distribute on Google Play. It’s trivially easy to take an existing Android game and boot it up on an OUYA, especially if you already have support for controllers. That said, getting Wind-up Knight ready to ship for the platform took a bit longer than I anticipated, so I thought I’d document some of the work required.
Wind-up Knight has had support for physical controllers since its initial launch. It supports the Xperia Play and is playable with Bluetooth HID controllers like the Nyko PlayPad Pro or MOGA. This support is based entirely on standard Android APIs, so even controllers that we never had access to during development, like the Japanese SMACON, work great. As an aside, the absolute best device to use for controller development is the NVIDIA Shield.
Because we already had support for controllers, Wind-up Knight was playable on our OUYA immediately. We just pushed our existing executable (the one distributed on Google Play) to the device with
adb install and it ran almost perfectly. Though OUYA provides a library to help with controller support, there’s no need to use it: the OUYA controller reports as a standard HID controller, and can be supported with existing Android KeyEvent and MotionEvent APIs. We ended up only using the OUYA SDK to do OUYA-specific things, which is pretty much just the billing API for in-app purchases.
Though Wind-up Knight was playable right off the bat, it wasn’t ready to ship. There were a number of controller-related issues to solve. First of all, two of the buttons on the controller were swapped, and the DPAD wasn’t working. After a lot of research, we tracked this down to a bug in Unity.
In order to support older devices, Unity’s Android controller implementation uses low-level Linux APIs to read button states. However, the mapping of buttons to Unity inputs is not guaranteed by these APIs. You can specify a Unity button called “joystick 1 button 1,” but there’s no guarantee that this button will be the same one that generates the Android key event for KEYCODE_BUTTON_X, which is what we would expect. You might have two controllers with identical button layouts that report identical key codes, and Unity may still map them to different buttons in its Input system.
To work around this we need to ensure that Unity is looking at the key code rather than actual hardware information. We do this by overriding Activity.dispatchKeyEvent() in our Java layer. This function is called as keys are delivered to the application, and provides a spot where we can transform (or even consume) key events before they reach Unity. In this function I look for KEYCODE_BUTTON_* and DPAD_* events and transform them into new events that map to keyboard buttons (e.g. WASD). This forces all controllers into a standard key mapping, which we can easily manage with Unity’s Input API. Synthesizing KeyEvents also clears the hardware reference information that comes with controller key presses, thus preventing Unity from using unreliable lower-level APIs to read the hardware.
With this change our controller mapping for all controllers, including the OUYA’s, is the same. Fortunately, the mapping of MotionEvents to analog sticks appears to be reliable across all controllers, so using standard Unity Input APIs for analog axes works fine.
Apparently there is some Unity plug-in specifically for OUYA controller support, but I don’t really see the point; I want a solution that works for all controllers and isn’t device specific. Our approach didn’t require any changes to our Unity game at all–it’s confined to Java land.
Once our controller support was sorted, the next step was to make all of our UI controller-capable. This is actually a lot more work than I expected. Though we use standard Android APIs for most of the menus in Wind-up Knight (I wrote about that system a few years ago), I still needed to go through all of them and ensure that buttons could be selected, that focus moves through multiple buttons in predictable ways, and that screens without obvious buttons (such as the Armory) had special case code to allow complete manipulation without a touch screen. Furthermore, in the bits of UI that are done within Unity (such as the level select screen), I needed to add code to support focusing in on things that one would normally just touch. I budgeted a week to do this work and it ended up taking me two; even with a relatively UI-light game like Wind-up Knight, going from a touch interface to a controller interface is a lot of work.
OUYA’s controller also supports a mouse pointer, and I assumed that I’d be able to fall back on that if absolutely necessary, but that plan didn’t work out. The pointer doesn’t actually simulate touch events at the Activity level, so while it can be used to click on buttons in normal Android UI, Unity doesn’t see it at all. I suspect this is implementation is the standard Android pointer implementation, and not something that OUYA invented, but either way it is unfortunately restricted.
Also important to shipping on OUYA was removal of most things that link to web pages. For example, we have links to Facebook, Twitter, and Google+ on the Wind-up Knight main menu. This makes sense on a phone or tablet, but not on a TV game console: the user probably isn’t interested in tweeting from his OUYA. Those buttons had to go, as did links to things that require Google Play (such as the Google Play game services button and links to Tapjoy offers).
Our first submission to OUYA was rejected because we had neglected to move some UI elements away from the side of the screen. The size of the visible area of the screen varies greatly from TV to TV, and to ensure nothing is cut off it is important to leave a 10% buffer of open space on all sides of the display. Fortunately it was pretty simple to pull all of the UI in (I just inserted a FrameLayout with a 10% margin into the root of my Android UI when running on OUYA), so this didn’t keep us down for long. But it’s definitely something to consider when developing for TVs.
Finally, the in-game HUD was hidden for the OUYA version. Normally the HUD indicates buttons where the player will place their fingers, and is completely unnecessary when playing with a controller on a TV. On the OUYA version of Wind-up Knight, we only show the buttons during tutorial sequences, and even then we show controller button images rather than the icons that are displayed on phones and tablets.
One last gripe about UI: the OUYA buttons themselves are annoyingly named “O U Y A” rather than the standard “A B X Y” format specified by Google. We had to create special graphics to indicate the correct buttons, which widened the size of our otherwise small OUYA-specific footprint.
The other bits required to finish off the OUYA version of Wind-up Knight, such as integration of the OUYA billing system and minor additions to the Android manifest, were extremely simple and straightforward.
One strange aspect of OUYA development is that the launcher requires an internet connection to correctly show development builds. If your internet goes down, you’ll get an error (and a nice exception in logcat) when trying to launch your game. We worked around this by using the
adb shell am start command to launch our development builds from the command line.
Bringing an existing Android game to OUYA requires almost no OUYA-specific work. There is work to support controllers, and significant work to convert touch-based UI to a controller UI, but none of this work is specific to the OUYA itself. Considering the plethora of other controller-based devices running on mobile hardware that have been announced this year, adding support for controllers and TVs to our games seems to make a lot of sense. For Wind-up Knight, we were able to make our game run great for OUYA with changes that are applicable to all kinds of other potential future devices.
For now, the OUYA is really the only device in its class, and Wind-up Knight is really awesome on it. Our hope is that it is the canary in the coal mine, and that it will usher in a new class of microconsoles that are easy to develop for and ripe for independent games. I’m really happy to be able to support this effort so easily with Wind-up Knight.