Quake II Ported to HTML5

In November last year I stated that it would only be a matter of time before it happened. Also in November Joel Webber, a Google engineer had the inspiration to port Quake II to HTML5 from Jake2–a Java port of Quake II–using Google Web Toolkit; the same toolkit used for writing Google Mail | Maps | Wave in Java and compiling into JavaScript. With the help of two other Google engineers (Ray Cromwell and Stefan Haustein) in “20% time”, it works! Just!

How Does It Work?

“GWTQuake” took Jake2, and run it through Google’s Web Toolkit (a framework and compiler for writing web apps in Java) to convert it to a collection of HTML5 Canvas / Audio / Video and JavaScript. Jake2 however relies upon various Java interfaces that are not present directly in GWT or the browser, for example the networking, keyboard and file IO. Joel had to implement new mappings to get the Java code to correspond to browser technologies. For example Java uses asynchronous IO, but JavaScript is event driven (onkeyup, onkeydown etc.). “Stefan Haustein contributed new JRE classes to implement Java NIO Buffers around WebGL’s new typed javascript arrays, as well as a GL renderer based around WebGL.”

WebGL is an experimental technology to bring 3D to browsers using OpenGL ES, a cut-down version of OpenGL designed for embedded uses (The iPhone uses OpenGL ES 2.0 for its 3D API for example). Both Firefox and WebKit/Chrome nightlies currently support WebGL, but it may be some time before this technology reaches a release-ready state (the specification is still in flux, a draft was issued in December 2009).

WebGL revolves around the HTML5 Canvas element, which provides a rendering context that can be drawn into using JavaScript so that web pages may render images on a per-pixel basis. Canvas was originally invented by Apple for use in the widgets in the Dashboard feature as part of Mac OS X Tiger. The Canvas element has since been adopted and standardised by the HTML5 working group. Firefox, Safari, Chrome and Opera all support the Canvas element. It is not yet known if IE9 will support Canvas, despite committing to support for other HTML5 technologies like Video and Audio.

Another interesting HTML5 technology used is WebSockets. This gives the browser the ability to open a two-way TCP connection to a server for a communication channel. This is an improvement over AJAX, which is a synchronous request-response technology that has high latency, and much more robust than ‘Comet’, a hack to make AJAX behave more asynchronously. By using WebSockets, the web browser has the ability to channel data back and forth at high speeds and act more like a native application. In this case, GWTQuake uses WebSockets to provide networking between client and server so that GWTQuake can even be played multi-player! WebSockets, like WebGL are currently only supported on nightly versions of Safari/Chrome and Firefox.

Loading and saving of games in GWTQuake is done using HTML5’s Local Storage, it’s a key:value store for web apps to hold more data than what can be fitted into cookies. Google use this in their Mobile GMail web app for caching and offline access to data. Unlike cookies, the data is not sent to the server on each request and it persists after cookies are cleared. Therefore you don’t have to download or upload files to load and save your games in GWTQuake, you just open the URL and choose load from the menu!

How Can I Play It?

At the moment GWTQuake is only available by downloading and compiling the source code from the GWTQuake Google Code project site. Both the OGG Vorbis tools and Lame are required to convert the Quake2 data into OGG Video and MP3 audio for use in the browser.

There are numerous issues, depending on what platform you are, but I managed to cobble together the following instructions for Mac OS X from comments from others on Google’s instructions.

  1. Install HomeBrew, to get Vorbis and Lame (and Mercurial) easily:
    (Credit for these instructions goes to “64.brian”)

    sudo chown -R $USER /usr/local
    curl -Lsf http://github.com/mxcl/homebrew/tarball/master | tar xvz -C/usr/local --strip 1
    brew install vorbis-tools
    brew install lame
    #if you don’t have Mercurial,
    brew install pip && pip install mercurial
  2. Checkout the GWTQuake source (requires Mercurial):

    hg clone https://quake2-gwt-port.googlecode.com/hg/ quake2-gwt-port

    You may need to “cd” into the quake2-gwt-port directory now.

  3. Maven runs out of memory compiling on OS X, fix this by using this command:
    (Credit for this instruction goes to “redchris”)

    export MAVEN_OPTS=-Xmx512m
  4. Compile, download the Quake2 demo, and run the server:

    cp -r maven-build/server/target/gwtquake/war/gwtquake war
    ./run-dedicated-server 8080
  5. Play the game by opening http://localhost:8080/GwtQuake.html in your browser!

Browser Compatibility

At this moment, GWTQuake will only work on a nightly version of WebKit or Chromium. Sorry, no Firefox support yet. Apparently it is missing some feature that is required (I know that Firefox supports WebGL, WebSockets and everything required in theory here, so I wouldn’t know precisely why it doesn’t work without debugging it myself).

Google’s browser compatibility page provides download links for WebKit, Chrome, and what command to run to enable WebGL (which is off by default in both browsers).

Additionally, Chrome has to be run without the sandboxing otherwise it is very slow due to time wasted copying the framebuffer between processes.

Another major issue is that on most screens the game appears very dark. This is because the original game did gamma adjustment on the textures as it loaded them and this was not ported as such to GWTQuake for efficiency reasons (see the FAQ page).

For the screenshots I’ve included in this article, I’ve forced my screen’s gamma to be 1.2 so that the screenshots are more visible.

How Does It Play?

Surprisingly well, considering it’s in a web browser! There are a number of bugs. When I loaded the game, there’s just a black screen in Chrome, and the console text overprints itself. Just press enter to bring up the game menu.

One rather cool aspect of the web-ness of the code is that the data loads asynchronously. As you start a game, the textures load into view much like images in a regular web page!

In WebKit, I found that the objects in the game (gun / enemies / other interactive objects) flickered. In Chrome I didn’t get any sound, but the flickering was gone.

In WebKit it was reporting about 7-10 FPS, though to be honest it felt significantly smoother than that (nearer to 20 FPS maybe). In Chrome, I was only seeing 1–2 FPS. Ray Cromwell reports that “On WebKit/Chrome I can get 20-25fps on a MacBook, and on my Mac Pro desktop, I get about 45fps. Joel reports that a Linux notebook gets up to 60fps”.

Aiming can be sent a bit skewiff if your mouse pointer falls out of the browser window, so full screen is a must if you have any intention of playing properly.

Of course it should be understood that this is a) highly experimental, and b) highly-unoptimised. The FAQ page notes that:

The original Quake II code was straight C, written in the mid-90’s. The Jake2 port to Java was very direct, which preserved most of it’s C-isms, including giant bags of static methods where C functions used to be. In addition to this, we hacked and slashed our way through the code to get it going and reasonably optimized, but there was definitely some collateral damage along the way.

Considering that it was compiled from hardly ideal Java into JavaScript, it’s still impressive performance. If the game were written from scratch straight into JavaScript (or even better, using Native Client), I suspect that performance would be much better.

What Does This Mean?

It means that you should not assume that the web browser is just a document viewer, nor is it as slow as it used to be, and nor is it as incapable as it used to be.

However, none of the technologies in use here having left draft status. I would put it at around two years before this technology (and games using it) arrive in the hands of the public via mainstream releases of Safari, Chrome and Firefox. But those innovating will be ready to hit the ground running.

What this means for users in the long term is a great simplification and removal of many hurdles for users. This is a 3D game that you can play just by visiting a URL. No installation, nothing to download and install. You “install” the game by bookmarking it. As simple as that. URLs could even be constructed to point to specific rooms in multiplayer sessions, so that you could invite someone into a game in progress just by sending a URL through e-mail, IM or twitter and such!

There’s been a lot of debate about HTML5 vs. Flash, especially with the imminent release of the iPad (which despite complaints from some doesn’t seem to be having a problem getting some major users of Flash to jump ship to HTML5). Whilst HTML5 cannot fully replace Flash yet, the features are coming, and those features will even surpass what Flash can do. Mozilla have demoed WebGL running on a Nokia 900; they decided to disable Flash by default on Firefox Mobile stating “The Adobe Flash plugin used on many sites degraded the performance of the browser to the point where it didn’t meet our standards.”

Adobe have promised that Flash 10.1 will increase performance, but this won’t change the fact that neither the iPhone, nor the iPad include Flash. Once a web developer writes content in a standards based way to work on the iPhone / iPad, why would they choose not to serve the exact same content to desktop users, and redo it all again in Flash?

Quake II in HTML5 does not exist to somehow be a practical example of the technology. It is to inspire developers to push the boundaries of what’s assumed what browsers are capable of. Compelling, graphical games and experiences can be delivered to users with nothing more than a URL, with all the freedoms of distribution the web offers (compared to the App Store for example), across multiple OSes and multiple platforms and processors. It will take many years for the availability of this technology to trickle down to devices everywhere, and many more years for the development tools to become readily available to all levels of skill; but come they will, because the Internet is the new operating system.


  1. 2010-04-02 3:02 pm
    • 2010-04-02 3:14 pm
      • 2010-04-02 5:04 pm
        • 2010-04-02 10:42 pm
          • 2010-04-03 5:26 am
      • 2010-04-03 7:50 am
        • 2010-04-03 12:17 pm
          • 2010-04-03 12:32 pm
          • 2010-04-03 12:53 pm
          • 2010-04-05 6:39 pm
    • 2010-04-03 7:55 am
      • 2010-04-03 2:36 pm
  2. 2010-04-02 3:16 pm
    • 2010-04-02 3:22 pm
      • 2010-04-02 4:44 pm
        • 2010-04-02 6:00 pm
          • 2010-04-02 7:08 pm
        • 2010-04-03 7:59 am
          • 2010-04-03 12:31 pm
          • 2010-04-03 7:21 pm
    • 2010-04-02 4:30 pm
    • 2010-04-02 5:16 pm
    • 2010-04-02 11:15 pm
  3. 2010-04-02 3:48 pm
    • 2010-04-02 3:52 pm
  4. 2010-04-02 3:52 pm
    • 2010-04-02 3:55 pm
  5. 2010-04-02 5:24 pm
    • 2010-04-02 6:06 pm
      • 2010-04-02 6:07 pm
      • 2010-04-02 6:21 pm
        • 2010-04-02 9:48 pm
  6. 2010-04-02 5:25 pm
    • 2010-04-02 5:26 pm
      • 2010-04-02 6:00 pm
        • 2010-04-03 12:32 am
          • 2010-04-03 4:30 am
  7. 2010-04-02 5:57 pm
    • 2010-04-02 6:03 pm
      • 2010-04-02 6:19 pm
        • 2010-04-02 6:25 pm
          • 2010-04-02 6:36 pm
          • 2010-04-02 6:43 pm
          • 2010-04-02 6:55 pm
          • 2010-04-02 10:52 pm
          • 2010-04-02 7:17 pm
        • 2010-04-02 6:30 pm
          • 2010-04-02 7:28 pm
          • 2010-04-02 8:38 pm
          • 2010-04-02 11:43 pm
          • 2010-04-02 8:47 pm
          • 2010-04-02 9:03 pm
          • 2010-04-02 11:11 pm
          • 2010-04-04 10:15 am
      • 2010-04-04 10:08 am
        • 2010-04-04 10:22 am
          • 2010-04-04 10:30 am
          • 2010-04-04 2:27 pm
    • 2010-04-02 6:24 pm
      • 2010-04-02 6:29 pm
    • 2010-04-02 11:01 pm
    • 2010-04-03 12:13 am
      • 2010-04-04 1:36 pm
        • 2010-04-06 10:23 am
          • 2010-04-06 10:29 am
    • 2010-04-03 5:58 am
  8. 2010-04-02 10:23 pm
    • 2010-04-03 12:40 pm
      • 2010-04-03 5:09 pm
    • 2010-04-03 6:03 pm
  9. 2010-04-02 10:45 pm
    • 2010-04-03 5:56 am
      • 2010-04-03 2:52 pm
  10. 2010-04-03 10:13 pm