This seems to be the perfect opportunity to finally post a blog entry I have been sitting on for quite while now -- and to provide some background and history of the port.
We knew that this undertaking wouldn't be feasible without significant code changes, as many Java libraries just weren't available in the GWT JRE emulation. Some APIs just weren't supported because of memory concerns and others -- such blocking network IO -- were just impossible to emulate in GWT in its existing form.
One option would have been to hack the code and just replace anything in Java that isn't available with JSNI. But that's not the route we took. If we would have changed the code to no longer compile with regular Java, we'd have lost a valuable testing platform that allowed us to check whether we had introduced a bug by converting threaded code to asynchronous callbacks -- or in our new graphics routines that map to WebGL. So we decided to go with emulations as far as possible -- and to do the conversion from threaded code and blocking IO to async in a way that would still be compatible with regular Java.
For the GL part, one of the problems was that Quake II was still using gl_begin / gl_end style calls, building up rendering data in a piecemeal approach, which in modern GL has long been replaced with handing over bulk data in one go. This meant that we weren't able to use too much of the emulation I had built for Google Maps for Mobile. A full emulation also would need to include texture mapping, which in turn required image loading — which at this point we still needed to be convert to async somehow. So in order to gauge feasibility, I went ahead and implemented a simple Canvas2d baed emulation that would just render wireframe images. I can't describe how happy I was when I saw the first recognizable Quake II scene rendered with green lines on a black background. It looked a bit like the "[Quake on an oscilloscope](youtube.com/watch?v=aMli33ornEU)" demo (which came out later IIRC). I must admit that I am still a bit sad that I haven't properly preserved the corresponding rendering code.
Unfortunately, at this point, the frame rate was something in the order of magnitude of 1 FPS, but we managed to improve it quite a bit before the April release.
Also, it's more easy to confirm that the modified source is actually executed and you are not looking at a stale browser cache. Now some people might suggest to use a proper logging framework instead of printf, but if debug printing is easily distinguishable from logging, it's also much more easy to remove, avoiding excessive log spam left in the code. For instance, at Google we have automated checks preventing code with print statements from getting checked in.
One thing I found quite irritating in some GWT libraries was that they provided a replacement for some system feature that couldn't be super-sourced for one reason or another -- but then the replacement wouldn't have a matching JRE implementation, so even if the corresponding functionality was available in both, GWT and standard Java, the user was left with bridging this gap in some form or another.
In terms of Java code sharing, there are generally three major options
I think option 2 is considered the clean default by most people working with shared code, but it has some significant disadvantages:
The main problem why we couldn't publicly launch a working web app (opposed to just the source) was that the Quake II source was open source, but the levels still are not. The typical way to work around this issue is to let the user provide a corresponding "wad" file, which is conveniently extractable from the shareware version that is still available on the web.
After finding a JS zip decompressor, I actually managed to add a download dialog to the WebApp and to launch it on AppSpot.
My next goal was to port the Game to the LibGDX cross-platform game library, as PlayN was never really intended for 3D games -- and some of the hacks we needed seemed to be an odd fit / maintenance burden for PlayN. In the same go, I wanted to check if it the code could work on Android, too. Unfortunately, the GL emulation fork in LibGDX is quite outdated. Resource management in LibGDX was built without the web in mind, and the way web support was added later proved to be quite incompatible with what we did for Quake. I got a prototype working (replacing the File API deprecated at that time with IndexedDB IIRC), but I kind of gave up when the Android built-in zip decode wasn't able to uncompress the shareware game executable.
Unfortunately, I have never back-ported all my LibGDX changes that were necessary to get the game running, so the LibGDX version currently compiles only with my outdated LibGDX fork.
Fortunately, Dimitrii has done this for the [NIO Part](https://github.com/treblereel/gwt-nio) now. ## Links