Wednesday 30 January 2013

Voxel Invaders ported to javascript using emscripten

We just released a javascript version of our game voxel invaders that can run on any browser with webgl support.

Turns out the port was pretty easy, and I didn't have to write a single line of javascript.

So how did we do it? Since our game was written entirely in C, we used emscripten to compile our source code directly to JavaScript. For those who don't know, emscripten is an LLVM backend that generates JavaScript code, so if a project is written in a language that can be compiled by clang, then it is in theory possible to make it run on a browser.

Of course there are a few restrictions, and in our cases we had to make some changes to the code before we could have it running properly on a browser:

  • Emscripten has no support for client side arrays in OpenGL. Even though it has a pretty good support for OpenGL ES2 via webgl, using client side arrays is not supported. This is not really a problem: we just used array buffer everywhere we had client side arrays.

  • Some standard C functions are missing. The one that really hit me was strsep that we used in the levels parsing code. In that case I just modified the code to use strtok_r instead. As a bonus, it turns out the code using strtok_r was actually cleaner than the original one.

  • Sound. When doing a portable game, sound is probably the most complicated part. For the graphics, using Opengl ES2 pretty much works on every possible platforms, but for the sounds, there is still no clear standard library that can be used everywhere. So, as we already had an openAL and an OpenSL ES backends for the desktop and android versions, we created an other sound backend using SDL_mixer for the javascript version. [By the way, I always find it funny that OpenSL ES -that has been done by the same company behind OpenGL- is such a complicated mess compared to OpenAL].

All in all, it wasn't that hard to port the game to JavaScript. The performances are probably not as good as it would have been if we had rewritten the game manually in javascript, but the amount of work done was negligible.