Practice your Go WebAssembly with a Game

By Adil H

A few days ago, I wanted to take Go WebAssembly out for a spin, but I wasn’t sure what to build. Maybe a game ? but I didn’t really want to build a game from scratch. So I remembered the Elevator Saga, a programming game by Magnus Wolffelt I stumbled upon a few years ago: The goal is to transport people up and down building floors by controlling elevators, writing the rules in Javascript. What if I modified it to accept WebAssembly flavoured Go instead of JS !

Meet the Go Wasm Elevator Saga. The github repo is available here.

Go Wasm Elevator Saga

I’ve forked the original repository for the purposes of this exercise.

The original JS game is written as a Javascript App that takes the user input as text, runs a js eval() on it to transform it to a JS object and displays the results on the screen, moving the elevators accordingly.

In order to accept Go WASM as input we’ll need to compile it server-side. I’ve built a small Go API service that sits behind an Nginx reverse proxy, takes the user input, creates a .go source file, compiles it to WASM in a new docker container via the Docker Go API and returns the output binary to the browser.

I’ve written a boilerplate main.go file that provides the setup required for the game to run and makes use of the functions Init and Updated that are provided by the user:

boilerplate go file

The default/starter user input displayed in the game is the following:

user input go file

The Init and Update functions above are the equivalents of the init and update functions required by the original game, as documented here

The API/build server takes care of 2 important steps:

  • Copying the main.go file and the input.go file (from the HTTP post request) to a temp folder.
  • Running a Docker container which will perform the build, passing the previous temp folder as input. The Docker run is done via the Docker API and not via the shell, allowing for safer error handling.
server go code

The Dockerfile in itself is very simple and equivalent to running the following command in the directory containing our source files:

GOARCH=wasm GOOS=js go build -o app.wasm .

The actual JS/WASM integration is done in this JS file :

JS integration

The JS code parses the server output, loads it into a WASM module and runs it.

We run the game by clicking on Apply and … it works !

Go Wasm in action !