Editors note: This is a guest post by Alon Zakai of the Mozilla Emscripten team. Thanks Alon!
Me & My Shadow is an open source 2D game, with clever gameplay in which you control not one character but two. I happened to hear about it recently when they released a 0.3 version:
Since I’m looking for games to port to the web, I figured this was a good candidate. It was quite easy to port, here is the result: Me & My Shadow on the Web
You can also get the source on GitHub.
For example, if the C++ code has
SDL_BlitSurface(sprite, NULL, screen, position)
then that means to blit the entire bitmap represented by sprite into the screen, at a specific position. Emscripten’s SDL implementation does some translation of arguments, and then calls
ctx.drawImage(src.canvas, sr.x, sr.y, sr.w, sr.h, dr.x, dr.y, sr.w, sr.h);
which draws the sprite, contained in
src.canvas, into the context representing the screen, at the correct position and size. In other words, the C++ code is translated automatically into code that uses native HTML canvas operations in an efficient manner.
There are some caveats though. The main problem is browser support for necessary features, the main problems I ran into here are typed arrays and the Blob constructor:
- Typed arrays are necessary to run compiled C++ code quickly and with maximum compatibility. Emscripten can compile code without them, but the result is slower and needs manual correction for compatibility. Thankfully, all browsers are getting typed arrays. Firefox, Chrome and Opera already have them, Safari was only missing
FloatArray64until recently I believe, and IE will get them in IE10.
- The Blob constructor is necessary because this game uses Emscripten’s new compression option. It takes all the datafiles (150 or so), packs them into a single file, does LZMA on that, and then the game in the browser downloads that, decompresses, and splits it up. This makes the download much smaller (but does mean there is a short pause to decompress). The issue though is that we end up with data for each file in a typed array. It’s easy to use the BlobBuilder for images, but for audio, they need the mimetype set or they fail to decode, and only the Blob constructor supports that. It looks like only Firefox has the Blob constructor so far, I’ve been told on Twitter there might be a workaround for Chrome that I am hoping to hear more about. Not sure about other browsers. But, the game should still work, just without sound effects and music.
Another caveat is that there is some unavoidable amount of manual porting necessary:
Aside from that, everything pretty much just worked. (The sole exception was that this code fell prey to an LLVM LTO bug, but Rafael fixed it.) So in conclusion I would argue that there is no reason not to run games like these on the web: They are easy to port, and they run nice and fast.
About Chris Heilmann
Evangelist for HTML5 and open web. Let's fix this!