If you live anywhere near me, you might have heard me yelling a few times in recent days. Between working on one YouTube video or another, I’ve been spending at least a couple hours a day, for the last week or so, trying to get HTML5 projects working on the Ouya. You might have even seen my proof-of-concept video using a Twine project over a week ago too.
There was a short amount of time when I first started into this, too, when I thought all the promised narratives of doing easy HTML5 development for the Ouya were going to work out quickly. I had some early successes side-loading some different code and, with the video, thought selling Twine projects on the Ouya was just out of reach. All I needed, I thought, was just to overcome some simple hurtles and I would have a complete solution that I could use and show others.
That was from the optimistic time. Last week.
Today, after spending many long days debugging code, digging through poor documentation, and generally feeling like giving up completely on this, I have finally started to understand the situation and, well, nothing about this is as easy as it was pitched to me from different people. (None of which, it turns out, have done any HTML5 development on the Ouya themselves. So that’s, you know, super annoying to learn.)
First, let me write, there is the Official Way of Getting HTML5 Working on the Ouya. This is, by far, the most ridiculously complicated solution I have ever read to solving the issue of making HTML5 projects. It involves dozens of steps, knowledge of compiler environments, and being comfortable editing code on the command line. Even reading through the steps myself, I got confused multiple times — and that’s before even attempting it!
As I now understand it, you create a virtual machine (or stand up another physical machine), install Ubuntu, download and configure some different dependencies, and then — and this is part that I find just ridiculous — download the entire Chromium source and compile your own version. That’s upwards of 80 GB of code and, of course, the potential of hours of compiling time!
So, for me anyway, that was completely out. I was not going to have my development environment outweigh my source code by several factors of ten in size.
Having decided that, then, I moved to CocoonJS a couple weeks ago. A solution not without its many problems too, I’ve learned.
CocoonJS is, more or less, a cloud compiling service that has taken the Chromium source (I think?), optimized parts, and cut out support for nearly everything but the Canvas itself. It is made running Canvas-based projects much faster as a result, but the cost of that is missing many common parts of HTML5 projects, like any DOM support, for example.
It comes in two modes: “System Webview” and “Accelerated Canvas/WebGL.” If you just want to deploy your already working web-based game as an app on most mobile devices, the “System Webview” is probably for you. It creates an instance of whatever the default browser is on the device, adds in some of its own APIs, and runs your code. It’s pairing your code with a built-in browser to make a single app.
The other mode, “Accelerated Canvas/WebGL,” is the one people struggle with the most, myself included. It is where the sped-up canvas, and missing DOM support, generally confuses most first-time users and where, I’ve found, many people stop after confronting the issues it presents.
Here is what I know from my testing on the Ouya:
- You must run in “Accelerated Canvas/WebGL” mode to get access to the CocoonJS extensions. It is through those where things like the gamepad and IAP (in-app purchases) get enabled.
This also means, at the moment anyway, that Twine games, at least not without a great deal of re-writing of its core functions, won’t be easily sold on the Ouya. You could probably release them for free, and I might even do this myself at some point, but you need the IAP support to sell anything. And Twine depends heavily on DOM support, which the mode with the extensions doesn’t have, so no full gamepad support either.
- It is vital to use a ‘screencanvas’ element.
Wherever you are creating your canvas element, change it to the following code:
var canvas = document.createElement(navigator.isCocoonJS ? 'screencanvas' : 'canvas');
That way, you are using the ‘screencanvas’ to draw instead of a ‘canvas’ element itself. (You can still use Canvas elements afterwards for buffers and image manipulation, but the main drawing area needs to be ‘screencavas’ for anything to appear.)
- Unless you really know what you are doing, or have some other program writing the code for you, you are better off avoiding WebGL mode right now.
The implementation of WebGL in CocoonJS falls victim to the non power of two (NPOT) problem when it comes to textures. If your images do not have dimensions of multiples of two, CocoonJS will probably not load them in WebGL mode. And, if those dimensions are not 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, or 2048, it will be bumped to the next largest dimension set with the remaining space in the images considered ‘wasted’ and taking up extra memory.
- The gamepad code for CocoonJS, and on the Ouya specifically, is different than the other browser’s implementations right now.
I am still working on this. I included how to enable support in my forum post for Phaser, but there are still some problems I’m trying to track down. Right now, for example, a polling approach (how most people address the gamepad API) often produces false positives. If the polling happens too fast, the input values don’t always show up.
I have a version of my own Gamepad code that seems to be working with a slower polling cycle, but plan to thoroughly test it within the next couple of days before working on patching it into Phaser maybe as early as next week. That should be the last major hurtle.
Assuming I can get all of this worked out, I am hopeful I can start writing a guide that walks through how to set up a testing environment using CocoonJS’ custom launcher on the Ouya relatively soon. Maybe within the next couple of weeks, depending on how far I get into trying to figure this all out myself.