Mozilla constantly asks this question, but their answer really doesn't tell us all that much. Yes, JavaScript has been getting faster and faster and the v8bench, kraken and sunspider benchmarks are a good indicator for that. Yet, they all miss some issues that are quite important for HTML5 Gaming.
One of these issues was made blatantly obvious when I finished work on the performance graph for the new debug menu in my JavaScript Game Engine: Garbage Collector pauses.
All JavaScript engines periodically run a Garbage Collector to release unused memory. In some cases this GC step can take several hundred milliseconds, in which the game comes to a complete halt. Even if that only happens every 600 frames, or 10 seconds, it's far more annoying than a game that runs at a lower, but constant framerate.
Performance Graph for Firefox 6 – the orange spikes indicate GC pauses
GC pauses have been a huge problem with Firefox 3.6 and Firefox 6 is still the worst offender here. Other browsers have shorter GC pauses, but there's still room for improvement. To gain some more insight, I constructed a new benchmark that essentially simulates a playthrough for a game level.
Give it a try at HTML5-Benchmark.com.
Now, to be clear, this benchmark is very “opinionated”. It's by no means a complete benchmark for all HTML5 features, but only tests one very specific use case: smooth running games rendered with the <canvas> element. It's a very real use case though; not an average for hundreds or thousands of small tests.
The score for the HTML5-Benchmark takes the total time the browser spent rendering frames and a big penalty for pauses into account (the exact formula is 1000000/(sqrt(totalTime) + lagTime * 0.1)). The benchmark automatically runs at a “reasonable” screen size - i.e. a screen size that makes sense for a game on the particular device. Thus, the final score is a real indicator for the browser's ability to smoothly run HTML5 games.

A score of about 1500 means the game is playable. Note that the benchmark actually runs a bit slower on mobile devices than the game itself. This is because the game utilizes a special pre-rendered background mode on mobile devices, but doesn't do so in the benchmark to keep the scores comparable.
It's almost comical how bad the Android's Browser performed in my tests: the Samsung Galaxy Tab 10.1 is actually slower than a four year old 1st gen iPod Touch. Firefox 4 on the same tablet performs a lot better though.
The desktop version of Firefox 6 still suffers a lot from the occasional GC pauses. This makes Firefox the last choice if you want to enjoy HTML5 games. The performance decrease from the stable Chrome 13 to the dev version of Chrome 15 is quite strange too. It may have to do something with the new hardware acceleration for Canvas' 2d context.

There are some things that the benchmark can't measure. Opera for instance has a very steady timing and never misses a frame. On my machine however, the benchmark still looks choppy - probably because the benchmark's timer isn't synchronized with the refresh rate of the display. Opera essentially renders frames that it never displays. The new requestAnimationFrame() could fix this, but it hasn't arrived in all browsers yet.
IE9's smoothness on the other hand is remarkable. Of all browsers and systems I tested, IE9 subjectively produced the best results. It seems to precisely synchronize JavaScript execution with the refresh rate: the benchmark runs at exactly 60 FPS on my machine, even though the timer is scheduled every 16 milliseconds, or 62.5 FPS.
This leads me to ask a few questions: shouldn't browser vendors concentrate on fixing setInterval() first, before implementing requestAnimationFrame()? And shouldn't it behave more like setInterval() instead of setTimeout()? That is – I don't want to call a function to schedule each and every frame I want to draw, but just call it once and let the browser schedule the frames.
requestAnimationFrame() looks good on paper, but it doesn't actually produce visually better results than setInterval() in those browsers that implement it.
On my machine, Chrome 13 and Firefox 6 awkwardly jump between 120 and 60 FPS when using it (it's disabled in the benchmark) and even without GC pauses there are noticeable hiccups, while IE9 is able to produce perfectly smooth animations without it. At the moment requestAnimationFrame() is truly worthless for games.
So, no – we aren't fast yet. But we're getting there.
Some weeks ago I released a compiled version of the JavaScriptCore library for iOS as part of my game engine. Since then I had many people asking for the project files necessary to build the library - and I promised to release them as well. But before I do so, let me just rant about Apple's politics real quick:
They suck.
You see, JavaScriptCore is an Open Source library. In fact the whole WebKit project is. It's licensed under BSD and LGPL licenses. The latter of which requires that if you modify the software you have to release your modified version – including the complete source – under the LGPL as well. Furthermore, it states: "For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library."
Yet the JavaScriptCore sources that you get from Apple's Open Source page come without a project file. So while you get the source code for the library, it's useless because you can't compile it.
Luckily you can also get the current JavaScriptCore sources directly from the SVN repository – and behold, they even come with an Xcode project file, ready to be build for MacOSX with the touch of a button. But – and here's the kicker – this project file curiously misses the iOS platform target. You can't build it for the iPhone or iPad.
Adding this iOS target to the project file is by no means a trivial endeavor, mind you. Especially not in Xcode. I ended up duplicating the MacOSX target, setting the Base SDK to Latest iOS, changing the Supported Platforms to iphoneos iphonesimulator and poking around in the project file with a text editor to change the productType to library.static, because you're not allowed to build a framework for iOS.
After some more changes that I can't remember (I'll be sure to document this next time I do it), I was finally able to compile the library for iOS. I submitted my game Biolab Disaster to the App Store only to see that it was rejected the next day.
JavaScriptCore utilizes the libicucore library to sort strings in a unicode fashion. Apparently libicucore is a "private" API on iOS – which is curious because I can add this library to my iOS project without any dirty hacks, I'm just not allowed to use any functions of it. So I compiled JavaScriptCore again, this time setting the UCONFIG_NO_COLLATION preprocessor macro to disable unicode sorting.
Did I mention Apple's politics suck?
Anyway, here's the statically compiled libiOSJavaScriptCore.a that you can use in your iOS projects and the source and project file if you want to build it yourself for whatever reason:
This all is based on the slightly outdated 534.27 version of JavaScriptCore, but at least this version seems to be AppStore compatible.
Using libiOSJavaScriptCore.a in your Project:
- Copy the JavaScriptCore directory with the header files from the ZIP to your project folder and add them to your Xcode project
- Copy the libiOSJavaScriptCore.a into your project folder
- Add the
libstdc++.dylib, libicucore.dylib from the list and the libiOSJavaScriptCore.a from "Add other..." like so
import <JavaScriptCore/JavaScriptCore.h>
Building JavaScriptCore from the Source:
- Select iOSJavaScriptCore iPhone as the active Scheme and build
- Select iOSJavaScriptCore iPhone Simulator as the active Scheme and build
- Navigate your terminal to the build directory: depending on your Xcode settings either
build/Products/ directly in your project directory or ~/Library/Developer/Xcode/DerivedData/JavaScriptCore-xxx/Build/Products/
- Combine the ARM6/7 and x86 (Simulator) libs into one:
lipo -create Production-iphoneos/libiOSJavaScriptCore.a Production-iphonesimulator/libiOSJavaScriptCore.a -output libiOSJavaScriptCore.a
Btw.: AppCelerator maintains their own version of JavaScriptCore that they use in Titanium, but I have no idea how to build it. Any hints are greatly appreciated!
If you want to support me, please consider buying a license of my game engine. It also makes a great gift ;-)
Less talk, more action – Apple just approved two of my JavaScript games for the AppStore: Biolab Disaster and Drop. Both are free; go check them out. You can also play them in your browser here and here.
Both games are pretty simple (the source for Drop is only 300 odd lines long) and written with my JavaScript Game Engine Impact.
These are certainly not the first games written in JavaScript to be available in the AppStore. Tools like AppMobi, PhoneGap or Titanium make it easy to bundle some HTML pages and JavaScript together in an App and display them in a UIWebView, which is basically just a browser window (correction: Titanium doesn't use a UIWebView but instead has some native bindings). Games written with Impact already work okay-ish in the iPhone's browser and thus also in AppMobi and PhoneGap.
So what's so special about these two games now? They don't use PhoneGap or Titanium. They don't even use a UIWebView. Instead, they bypass the iPhone's browser altogether and use Apple's JavaScript interpreter (JavaScriptCore) directly. All graphics are rendered with OpenGL instead of in a browser window and all sound and music is played back with OpenAL instead of… well, having no sound at all.
What makes this possible is a compatibility layer that mimics the HTML5 Canvas and Audio APIs but is implemented with OpenGL and OpenAL behind the scenes. Think of it as a browser that can only display a Canvas element and play Audio elements, but does not render generic HTML pages. A browser perfectly suited for HTML5 games.
This means you can take your JavaScript games written for Impact and run them on iOS with perfect sound and touch input and way better drawing performance than with Mobile Safari. Now, to be clear, I only implemented a bare minimum of the Canvas API - just enough to be able to run Impact. The whole thing is still in a very experimental state.
If you have a license for Impact you will find the complete source code for this all on your download page. I also wrote some basic documentation to get you started. In theory, you don't have to know anything about Objective-C to use this, but at this stage some Objective-C knowledge will sure come in handy. Again, this is very experimental. Don't expect it to work at all.
If you've been following this blog for a while, you might remember a post from October 2010 where I attempted the exact same thing. Back then I used the JavaScriptCore library that is already available on iOS and used by Apple in Mobile Safari. The problem was, that this library is "private", meaning that Apple does not want you to use it. And since you can't publish anything in the AppStore that uses private libraries I abandoned the idea.
However I recently revisited the project, because there was still a chance to make this work: JavaScriptCore is a part of the open source WebKit project. Instead of using the private library that comes with iOS, you theoretically could compile your own version of this library and bundle it together with your App. Which is exactly what I did.
Since Apple does not provide any project files to compile JavaScriptCore for iOS (presumably to annoy us) and JavaScriptCore itself uses some of iOS' private APIs, compiling this beast into a static library - in an App Store compatible fashion - took me a few days.
I also had to make a small sacrifice: JavaScriptCore uses libicu to sort strings according to a unicode locale. Sadly, libicu is also private on iOS and bundling it is not an option because of its size. So I got rid of libicu completely. This means that only ASCII strings are now sorted correctly (e.g. the umlaut "Ä" will come after "Z", not after "A" as it should). Other than that, the JavaScript library should behave exactly as the private one that comes with iOS.
Also, the JavaScriptCore library bundled with iOSImpact does not use the JIT compiler (Nitro). You can't allocate executable memory on the iPhone and if Apple doesn't lift that restriction, there's nothing I can do about it. However, Apple recently made an exception for Mobile Safari – if they would make their JavaScriptCore API public, they probably could enable the JIT for everyone. That's a big if though; I don't see it happening, because Apple loves native code (Objective-C) and hates scripting languages.
I was afraid Apple would reject the two games for some obscure reason, but they didn't. Which leaves me to wonder why the JavaScriptCore library that comes with iOS is private in the first place. Bundling JavaScriptCore with your App adds about 2MB in size – not much, but I fail to see how this can be in Apple's interest.
Anyway, the performance of both games is pretty good. I still get some occasional slowdowns (~20fps) on my iPhone3GS in Biolab Disaster when there are too many particles on the screen, but it remains playable at all times. It's also nice to have perfectly working sound on iOS now - something even some desktop browsers still struggle with.
Now that I've calmed down a bit after my The State of HTML5 Audio article, let's see if can actually write something productive.
Here's the deal: for a typical game you may have a sound effect that you want to play very often. In Biolab Disaster the sound of your plasma gun is such an effect. This particular sound has a length of 0.6 seconds, but you sure can mash the shoot button quicker than 1.66 times per second – so to not interrupt the plasma sound each time you press the button, but instead play a new sound we need to have multiple sound “channels”.
Read complete post »
When I started to work on my JavaScript Game Engine back in October 2009, the biggest problems I encountered were with the new HTML5 Audio Element. The Canvas Element already worked nicely in all browsers that supported it at the time, albeit some were a little slow.
Now, in 2011, the rendering performance for Canvas has been improved dramatically, audio however is still broken in large parts. I think it is time for a change in tone. Be warned, there's some profanity ahead because HTML5 Audio is still that fucked up.
Before we start, you may want to play a quick round of Biolab Disaster or Z-Type and have a look at a simple test case to experience the sound issues first hand.
Read complete post »
The Mozilla Gaming Blog just published a guest post by yours truly. I write about the creation process, graphics and gameplay aspects of Z-Type, complain about HTML5 Audio and, of course, advertise my JavaScript Game Engine Impact.
Please enjoy Game On Spotlight: Z-Type.
It has been a month now that I launched my JavaScript Game Engine. My decision to charge for licenses to use the Engine has been met with a lot of discussions to say the least. People told me I would sell thousands of licenses more, if I had "dual licensed" Impact under the GPL. Some told me I was doing the right thing and putting it under GPL would be a bad idea. Others called me a scammer for charging for something that I had previously advertised as free (which I did not).
So, with all this controversy how has it been going? Quite good actually! In the last 31 days I sold about 150 licenses for Impact. After the initial hype died down, I'm now selling 2 or 3 licenses a day.
In these 31 days I also made about 700€ from AdSense banners that I put on the Biolab Disaster page and later on the Z-Type page (the first few days after Z-Type hit Reddit's front page it was ad-free).
So here's an immensely ugly chart that I put together from Google Analytics, AdSense and my License database:

All the payments for Impact went through PayPal. I've read a lot about how PayPal likes to keep your money, closes your account for no reason and a number of other shenanigans. I also had my share of bad experiences with PayPal a few years earlier, when someone purchased a software of mine through a hacked PayPal account. This time however, I haven't had any problems at all.
Sure, the PayPal website is still as bad as it ever was. I need about 60 seconds to login in to my account each time. Every single page needs at least 10 seconds to load and I'm forwarded from paypal.com to paypal-deutschland.de and back to paypal.com again. PayPals Instant Payment Notification API is equally horrible, but what can I say – it works and there's no other viable solution here in Germany anyway.
On a lighter note: I've sent more emails in the last 31 days than in the 12 month before that combined (236 vs. 124). I got a lot of job offers and even decided to go through a phone interview with Facebook after they approached me (I failed). I also got a lot of "business offers" that I still don't know how to deal with – emails talking about "partnerships" but never with a concrete idea. Maybe I just don't understand marketing.
So all in all I'm very happy with the success of Impact and I will definitely continue development for it.
I planned for a while now to participate in Mozilla's Game On contest. I didn't want to submit Biolab Disaster as my entry, but instead make something new and fresh. After all, the deadline for the contest was still months away. When I read this tweet I realized it wasn't anymore.
At this point I started to work on a game I wanted to make for a long time. I always was a fan of Crimsonland's (a 2003 arcade game) Type-o-Shooter mode and recently discovered the Dreamcast classic Typing of the Dead. So the overall direction of the game was clear.
Today I finished Z-Type. Please Enjoy!
