Thursday, April 1, 2010

GwtQuake: Taking the Web to the Next Level

Back in November of 2009, Joel Webber and I were at a GWT Summit focused on improving the Web and UI latency. Someone was giving a presentation on WebGL, and I saw Joel sitting in the back of the room looking seriously distracted. When I approached him, he said "Did you see this?" and swung his notebook around to show Jake2 -- Quake2 ported to Java running as a Java WebStart Application. I had seen this project years ago, but never knew it had gotten this far.

Right then and there, I knew what he was thinking, I almost didn't need to ask -- he was suggesting that we port Jake2 to the Web using GWT!


The Path to the Web


The idea that you could use GWT to compile something like Jake2 to Javascript seems straightforward, since GWT after all, compiles Java to Javascript, however there is still a lot of work massaging the code to compile, as well as mapping I/O to the appropriate Web APIs.

As you may know, GWT only implements a subset of the Java JRE, and Jake2 relies on many Java classes that GWT just doesn't have:

  • The LWJGL library for 3D

  • and java.nio.Buffer classes

  • java.net.* for networking

  • AWT for keyboard stuff

  • File system APIs for loading data

  • OpenAL for audio



More importantly, it relies on a synchronous API paradigm for doing I/O, and as we know, Javascript is built around event driven I/O.

Mapping I/O


Joel reorganized Jake2 I/O system around event driven pumping to load files. The first thing we did was get the level and model files loading, and rendering using a 2D <canvas> wireframe renderer (no WebGL). After that, 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.

Joel amazingly got multiplayer up and running on WebSockets and we had great fun play testing deathmatches between Atlanta, Mountain View, and even Sydney.

I went ahead and converted all of the sound to MP3 and implemented an initial sound renderer just by using the DOM Audio element. Later, I refactored the OpenAL code into a base class and provided an implementation of the OpenAL Inverse Distance Clamped sound model that adjusted volume gain of sounds based on 3D position, still, using nothing more than the audio.volume property.

Stefan added an implementation of RandomAccessFile based on LocalStorage to save game files, and an implementation of video playback using the <video> tag.

Most of the work was completed by January by part time contributions, but has been tweaked since then. Stefan, for example, went ahead and ported the entire single player game (no server needed) as static content.

A more detailed post-mortem will be presented during one of my Google I/O sessions, be sure to attend!

Is it slow?


I thought it would be, honestly, I never thought we would get this far, but it turns out that playable framerates are achievable. 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.

What this means for the Web


For years, people have assumed the browser was a poor platform for this kind of thing, and that you'd need something like Flash, Silverlight, JavaFX, or native code. While it is true that you should not expect the browser to rival triple-A titles like Far Cry or Call of Duty in the browser, there is no reason why lots of casual games that used to be implemented in Flash, or are now implemented in Objective-C on the iPhone/iPad can't be done using similar techniques we've used.

Moreover, because it's the Web, all you need to do to invite someone to your game, to share it, is to send a link. You could Tweet a link directly to your game, which when clicked, would make someone join the game in progress. No installs necessary. While this can be done in Flash, it just feels "natural" when it's in the browser.

I hope that this port encourages some people to become even bolder and crazier in the types of Web Apps they're trying to build, because if Quake2 is possible in Javascript using browser APIs, then even more amazing applications are waiting for you to develop, so get started!

The source code for our port is at: http://code.google.com/p/quake2-gwt-port

-Ray

19 comments:

Jeff said...

Even though this feels like an april fools joke, I am installing MacPort, etc. on my computer hoping this is true!

Ray Cromwell said...

Macs have had some issues running the build script. If you get an Out of Heap error, cd to maven-build/server and type ../maven/bin/mvn install

I'm trying to work around the problem.

Jeff said...

I got it to run without any work arounds. This is incredible! Nice job!

jopaki said...

OMG! How cool is this!

retro said...

This better not be an april fools joke. Ray when are you going to declare that this was april fools joke? It's almost 10 on east coast......you can let the cat out now.

Ray Cromwell said...

The best April Fools Jokes very hard to prove false. However, multiple people on the web have now compiler the source code and certified the result, so unless they're all accomplices.... :)

Kroc Camen said...

You are to be commended sir. I predicted that it would only be a matter of time before this happened http://camendesign.com/destination_internet and you have far exceeded my expectations.

I await a day that this can be played on official, released version of Chrome/Safari/Firefox :)

Daniel K said...

I am trying to pick up my jaw from the floor. You guys are amazing.

Thomas Broyer said...

OK, now I understand what this GWT + HTML5 can do what?! session at I/O will be about (and, oh, look at the list of speakers!)

Well, obviously you'll be talking about other things as well (Wave? Speed Tracer?), as it's tagged with "Enterprise".

I haven't yet looked at the code but the video is amazing!

Peter said...

If there was a nobel price for programming inventions, you guys should definitively get it.

dacresni said...

MAKE IT RUN ON APP ENGINE NOW PLEASE ! sorry, that was impolite. its just so plausible. It could be done and well!

Harry said...

Sounds amazing and certainly 10 years ago would have been an April Fools Joke. This could certainly make interactive MOO/MUD chat rooms a reality.

johndrinkwater said...

Why did you pick MP3 of all the codecs supported (or lack thereof)?

Legit Freebies Guy said...

OMg! I just checked out the video of this on YouTube and it's awesome! Can't wait to play it.

Ray Cromwell said...

Actually, both Ogg and MP3 support is included, but only MP3 is switched on. The reason was, there were some issues with Ogg and very small samples (< 1s) such as the machine gun bullet sound, these files ended up as zero bytes as output from the vorbis encoder.

The audio tag is still somewhat iffy, for example, you can't rewind/seek inside small audio files, which creates additional problems.

Julien Gouesse said...

Jake2 does not use only LWJGL, it was originally written with JOGL and the JOGL version is still working so please modify your webpage.

Ray Cromwell said...

That's true, but we concentrated on the LWJGL codepath for our port because it seemed easier.

Gord McLeod said...

This is outstanding. This is going to change the game industry landscape forever; a mighty big nail in the coffin of the dedicated hardware game platforms. Not yet, for sure, but now I'm 100% convinced that it's just a matter of time.

Just so I'm clear on what we're seeing here, this is without any sort of hardware acceleration?

Job said...

Really cool, thanks for stretching the envelope, opening doors, and all that.

I wonder if i can cheat using "javascript:". :)