I decided to take on Vito's challenge and port Unreal Engine 1 to Emscripten.
You can see the results here. This is the final C++ source code to Unreal Tournament 1999, compiled to run in a web browser.
It'll use the hot new WebAssembly if your browser supports it, or asm.js if not, which works on most other things, presuming they can otherwise provide the needed functionality.
Game data gets downloaded to an IndexedDB, so you don't have to pull down the same 100 megabytes again if you reload it later.
I can't believe how quickly WebAssembly became feasible; Firefox and Chrome support it out of the box, Safari supports it in their current Technology Preview, and Microsoft Edge supports it as an experimental feature in the Windows 10 Creators Edition. Right now, an asm.js fallback makes sense for another few months until Safari and Edge flip the final switches, but wow, we're almost there already.
This flyby demo works on all the modern major browsers, and apparently even works on recent builds of Android. Mobile Safari crashes while starting up, presumably due to some memory limit. I don't know yet.
This port uses the ancient OpenGLDrv code, that Daniel Vogel wrote at Loki, with libRegal making the fixed function code look like OpenGL ES 2.0, which Emscripten turns into WebGL (...which some Windows implementations then push through libANGLE to turn into Direct3D...how do computers even work at all?). In addition, glDrawArraws and glDrawElements both failed for different reasons in this frankenstein configuration, so this is actually rendering in GL 1.0 immediate mode: glBegin and glEnd pairs. Seriously! There are so many rendering wins we don't have access to until this code is rewritten; this game should, even in a web browser, get 60fps without struggling, but that's not the fast path we're on.
Daniel Vogel once joked, about OpenGLDrv, that in modern times, it should just put the entire map in a single Vertex Buffer Object. It's not like we're hurting for GPU memory and the maps are tiny datasets in 2017. I think that would be an interesting experiment some day.
The immediate takeaways of Emscripten porting, for me, are this:
- Porting is way easier than you'd expect, with one exception:
- You can't block, on anything, or it won't work. So you might have to redesign some small things, or one gigantic everything, depending on your program, but most things work pretty well. Solving the blocking problem on the web browser end is the most important thing that can be done by Mozilla/Google/Apple/Microsoft/etc.
- OpenAL and SDL 1.2 are built in with Javascript reimplementations, and SDL 2.0 itself has an Emscripten target that Just Works. Basically anything that's been ported to Linux or macOS will probably take a week (or a weekend) to get running.
- New tech (like WebAssembly) can become ubiquitous pretty fast; we don't live in a world where we have to worry about Internet Explorer 6 anymore (or Internet Explorer at all, discounting the most unlucky developers). If someone is on Firefox or Chrome, you probably have the latest and greatest and will continue to get the latest and greatest, and if you aren't, you probably have the option to use Firefox or Chrome.
Enjoy!
--ryan.