> Build and publish an HTML5 game for iPad

This is the first of a series of posts about a project/experiment I’m currently working on. The challenge is to build a pure HTML game (no canvas) for iPad and publish it to the Apple Store. Here you’ll find my day to day experience, suggestions and pieces of code.

Japanese translation (thanks to Yuji Ichikawa)

The purpose of this experiment is to develop an HTML game built on DOM and not inside a full screen canvas. I want to find out if you can get a decent game that feels 100% native using just HTML. Also I want to keep the door open to Android devices and older iDevices and iOS versions, and none of them are particularly good at canvas.

I choose a game because they tend to be more complex than standard applications. Basically if you can do a game you can do anything.

The game will be submitted to the Apple Store and will be sold in the $0.99 range. I know I’m not going to sell much, but sales statistics are part of the experiment.

The app is not finished yet, but at this stage I feel comfortable at reporting the first steps of the development process.

Step 1: Game idea and technical limits

I am not using native code, so the idea must be simple and mustn’t require too much processing power. Notably I wanted to avoid action games with too many sprites, effects and complex physics. I opted for a puzzle game and specifically a word puzzle. A quick search on the iTunes store revealed a plethora of such games but only one with the same logic and sincerely it’s not even worth a mention.

Initially it seemed the perfect idea… It wasn’t. Word games are obviously based on a dictionary, and dictionaries have the bad habit of being huge. Words are injected into a web sql database and sqlite queries are slow, at least they are not game-fast. You can reach decent performance with a well indexed database, but 2mb of terms easily becomes 8mb of indexed db, well beyond the web sql 5mb limit.

Please note that mobile Safari can go over 5mb –even though an user confirmation is required– but I’m going to embed the app into a WebView and to my knowledge there’s no way to overcome the 5mb limit in this scenario. The solution might be to build a wrapper for the native sqlite database in object-c, but it wouldn’t be a pure HTML game that way, and I’d loose Android compatibility.

It was too late to change the game idea so I decided I would have solved this with pre-calculated schemas and reduced AI (more on this in the next post).

Step 2: Callback (aka PhoneGap)

The app will be submitted to the Apple Store so I need to wrap it inside a native app. I didn’t want to use PhoneGap, at the end all I need is an uiWebView, but I found myself investing more time on Object-C than on JS, and that’s not good for an HTML game.

Audio is the mobile browser chimera, there’s no way to use native <audio> tag if you need responsive multiple channel sounds. This is a defeat for HTML5 and the main reason why I took the PhoneGap’s path with the added benefit of being able to go multi-platform. PhoneGap automatically wraps the native audio elements into easily accessible JS methods. Waiting for more reliable HTML audio, this is a great compromise.

The canvas alternative

In the hunt for alternative solutions I’ve found AppMobi. This is a very interesting project, from what I understand they’ve built a custom Safari compatible browser that gives hardware acceleration to the <canvas> element. They claim a 5x performance enhancement in canvas games compared to default WebView (it may seem a small upgrade but it means 50fps instead of 10!). Together with Impact framework it is a powerful tool in the hands of the web developer.

I briefly tested AppMobi and I don’t feel comfortable with it. The Chrome plugin, connected to some Java service, is a little unstable on my Mac and by the way my project goal was to use plain ol’ HTML.

I promised myself I’d take it for a second spin for the next project.

Step 3: JS framework

For such a targeted application I see no reason on Earth to use a bloated JS framework. It’s useless to uber-optimize the game logic if the foundation is a hog.

I’ve already talked about it, I have nothing against jQuery and company, they serve an important cause, but on mobile applications I see them as cumbersome luggage.

I’ve built a light core framework that I can shape to my needs. Remember that we are dealing with a game, every spared CPU cycle counts.

Just to make an example the following is my way to apply a property to a set of nodes:

function forEach (el, fn) {
	el = document.querySelectorAll(el);
	for (var i=0, l=el.length; i<l; i++) {
		fn.call(el[i]);
	}
}

Fast and furious.

Step 4: Random Number Generator

At the very bottom of game development there’s a good Random Number Generator. It’s something I rarely see mentioned in JS game dev tutorials, but the default Math.random() has two major flaws: 1) it can’t be seeded; 2) the output is not evenly spread inside the range. #1 is crucial if you want to regenerate the same game schema between sessions. #2 is important to avoid the annoyance of having the same number repeated 10 times in a row. I’ve being said that this behavior is actually “random”, but this is not what I need for the game.

Fortunately you can find lots of resources about random number generation in javascript, I suggest you to start from the very good piece wrote by Johannes Baagøe.

Step 5: Debugging

Don’t develop under X Code and don’t debug inside the PhoneGap wrapper, unless you’re desperately looking for daily migraine.

70% of the application is done on desktop browser, Safari or Chrome. 20% on the actual device (iPad in this case). The remaining on PhoneGap. This means that you need to hook to both touch and mouse events, believe me, it’s a small sacrifice that you won’t regret doing! And who knows, you may want to release a desktop version sooner or later.

Ready to go!

Hope you enjoyed this introductory tutorial. Next time I’ll cover more technical aspects, so stay tuned and prepare for beta testing.

/Share the joy

/Reactions