How to make a game engine for WebAssembly: Part 1

Nuvo Bloggo
5 min readJul 1, 2022

If you want to learn how to make a WebAssembly game, you’ve come to the right place. But what is “WebAssembly,” and why would we want to make games using it? Let’s start by briefly discussing the history of multimedia on the World Wide Web.

Crash history of interactive multimedia on the web

When Tim Berners-Lee first described his hypertext markup language, he didn’t have interactive media in mind. Web pages were static, but the exploding popularity of the web created demand for web pages that could do more. Netscape’s JavaScript language provided a solution, and it became so popular that it was reverse engineered by its competitors, and later, adopted into the official web standard. However, its capability for playing multimedia content was somewhat lacking at first.

Java Applets were prevalent, but Flash Player was so popular that the term “Flash game” became synonymous with “Web game,” much to the chagrin of pedantic people such as myself. Unfortunately, Flash Player has been deprecated in all major browsers. Applets also aren’t supported anymore.

JavaScript got an upgrade which enabled it to produce fast 2D graphics, and later got support for its own variant of OpenGL. Hard working software engineers have also spent countless hours creating and refining JavaScript interpreters that can run JS programs at fast speeds. But could we use a different technology to run programs even faster?

Introducing WebAssembly and friends

WebAssembly is a “binary instruction format” designed for the web. As far as I’m aware, it’s the fastest program format available in web browsers, and it lets you write web programs in languages that aren’t JavaScript.

When I started making web games, I used JavaScript. But when starting work on 5 Step Steve, I decided to make the game in C++ and use WebAssembly to compile it for the web. I’m glad I chose to do so!

My tech stack ended up looking like this:

  • The game engine was written in C++
  • It uses SDL2 to interface with the operating system (or web browser)
  • I used Emscripten to compile my code to WebAssembly
  • LodePNG, GLEW, and GLUT were also used.

At the time, I had very little experience with any of these technologies (including C++,) yet I still managed to create a game in roughly eight months or so. It’s probably worth mentioning that I didn’t have a working build of the game for web browsers until roughly two months before release!

When I was piecing together my game engine, there was no comprehensive guide for making a game in WebAssembly. That might explain why I’m one of the few web game developers that have attempted this! With this guide, though, I hope to inspire more people to make their games using WebAssembly technology.

Prerequisites

This tutorial series assumes you know how to do the following:

  • Create and navigate files and folders.
  • Create and modify documents, and give them appropriate file extensions.
  • Write code in C++.
  • Install and run software.
  • Run commands inside a command prompt.

You’ll also need software to run a local web server. If you don’t have software to do so, I recommend installing Python 3.

Installing and verifying Emscripten

Emcripten already has instructions for installing Emscripten, so that’s one less thing I have to write in this tutorial. Follow the instructions provided by the link to install Emscripten. Then, run the following code in a command prompt:

emcc --version

If Emscripten is installed and set up correctly, it should print out some information on its version.

Our first program: “Hello, World!”

Now that we’ve verified that Emscripten is installed correctly, it’s time to start building our first program. When it starts, it will print out text, then stop. It’s a simple and cliché program, but that’s the point.

Find a place on your computer (such as your documents folder, or a folder designated for storing programs) and make a folder called WASM tutorial projects. Inside that folder, make another called Project 1, Hello world. Finally, inside that folder, make a file called “main.cpp”

Open main.cpp inside your text editor of choice, paste the code shown below, and save the file.

#include <stdio.h> //For printf
#include <iostream> //For std::cout
//Our main function.
int main(int argc, char** argv){

//Print our messages.
//There’s more than one way to print text in C++.
//Multiple styles are used to make everyone happy.
printf("Hello, sailor!\n");
std::cout << "Hello, world!\n";

//Exit
return(0);

}

Open up a command prompt and change its working directory to the location your file is in. In the command prompt, run this code to compile your project:

emcc ./main.cpp -o main.html

So, what happened? Assuming nothing crashed and burned, and assuming I haven’t made an error in the following synopsis, your command did this:

  • It compiled your main.cpp file into an object file that contains code for the project (By default, this file is not saved to the directory.)
  • It took the object file and converted it into a WebAssembly file (main.wasm.)
  • It generated a javascript (main.js) and html file (main.html) that will load and run the WebAssembly program when opened in a web browser.

At this point, you might try to open main.html in your web browser. But if you try to open it directly, it will most likely not work.

The reason why is complicated, and I won’t pretend to know all the details. The gist of it is that all documents loaded from “file://” URLs are treated as having different origins, and are thus restricted from certain types of accesses. When main.html tries to read main.wasm, it is prevented from doing so, and our WebAssembly app cannot run.

Thankfully, the solution is simple. All we need to do is start a web server that will transfer our files using http. There are many different options, but I’ll be showing you how to run a local web server using Python 3. If you have Python 3 installed, you can run this command in your project’s directory to start a web server (though depending on how Python is set up, you may have to type python instead of python3)

python3 -m http.server

You should get a message saying Serving HTTP on 0.0.0.0 port 8000. Then, you can go to localhost:8000 in your web browser. Hopefully, the page should display this text in its output area:

Hello, sailor!
Hello, world!

Congratulations! You’ve just finished your first WebAssembly application! Obviously, we’re still a long way away from a fully featured game engine, but we’ll get there. Eventually.

You can contact me if you run into any problems getting your WebAssembly program running, or have found an embarrassing mistake in this article. In the meantime, I’ll… be busy with a lot of stuff, but I’ll be working on getting part 2 made!

Next post: coming “soon”.

--

--