Porting Games to the Web with WebAssembly

How to port an Asteroids game from C to WebAssembly 🎮

WebAssembly is a new language for the web. Much like low-level assembly languages, however, very few people write WebAssembly by hand; instead, you can compile code written in other languages (e.g. C, C++ and Rust) to WebAssembly and run that code in the browser.

Let’s get started!

To compile this game, we’ll use Emscripten, a tool that helps you compile C and C++ programs to WebAssembly. As we’ll see, developing in WebAssembly is not easy, but Emscripten provides many tools and features that make it much easier.

Interestingly, if you try to compile this code as is to WebAssembly, your browser tab will crash because of the infinite loops in the code!

A series of unfortunate loops

Games often contain infinite loops that wait around for user input, mouse movement or an animation to finish. For example, you’ll see the following infinite loop if you dive into the Asteroids code (asteroids/main.c) — here’s the equivalent pseudocode:

int main() { <initialization>

// render loop while(quit == 0) { <main loop contents> }

<cleanup and exit game>}

While using infinite loops works in a desktop game, this won’t fly in the browser, where infinite loops will crash your tab (details here).

What this means is that we’ll have to restructure the while() loop above into something the browser can handle, i.e. running the contents of that loop periodically instead of continuously. In general, we can use Emscripten’s emscripten_set_main_loop() function in our C++ code to define a function to call periodically:

As you can see, there’s a fair bit of moving code around to adapt it to the browser. The final main.c is available here (see diff here).

Now that our game has been un-infinite-loop-ified — a valid scrabble word, I’m sure — we’re ready to compile our game!

Compiling the game

Let’s see how we would usually compile this game to binary, and then which modifications we need to compile it to WebAssembly. According to the READMEfile, we can compile the Asteroids game as follows:

Instead, to compile it to WebAssembly, we’ll use Emscripten’s gcc wrapper: emcc.

Like many games written in C/C++, Asteroids uses the SDL library, which is short for Simple DirectMedia Layer. In a nutshell, it’s a library with useful utility functions to handle user input via mouse/keyboard/joystick, play audio files, and more. Because SDL is so popular, it has already been ported to WebAssembly, and Emscripten provides special flags to support it out of the box; here’s what the emcc invocation looks like (differences in bold):

Ready for more?

If you’d like to dig deeper into how to port more interesting/complex games to the web such as Pacman (screenshot below), or if you want to learn how to get started using WebAssembly in your own web applications, check out my book Level up with WebAssembly.