WebAssembly 2D game with Go. Part 1: Boilerplate.
3 min read

WebAssembly 2D game with Go. Part 1: Boilerplate.

Hello, and welcome to my small tutorial how to begin your adventure with WebAssembly using Go.

This is 1 part of 5. you can checkout other parts here:

We will use marvelous library Ebiten created by hajimehoshi as game engine, Parcel as local dev server and build tool for production. Finally, we will write multi-stage build Dockerfile and deploy it with Gitlab.

WebAssembly 2D Game: WASD controller character

I must say, this tutorial is not about game logic - we will focus only on wrapping all things together. The end result is just a "W-A-S-D" controlled character, with movement animation.

I will store all code at my GitHub, so you can easily navigate through using git tags, while reading this article. You can clone it with

git clone git@github.com:michaelknyazev/golang-wasm-parcel.git

So, let's begin our adventure.

Boilerplate

First of all, let's create simple boilerplate.

In this section we will

  1. Organize project structure
  2. Log "Hello World" using Go into console and build it to WASM
  3. Create main.js and connect our wasm file using wasm_exec.js from Go
  4. Create index.html and See our Hello World in browser console :)

Project structure

To keep things simple, let's create two directories: public directory for html/js and compiled wasm file, and src directory for our Go code.

WebAssembly 2D Game: Very first step

Also, let's init our go module and install Ebiten.

go mod init github.com/michaelknyazev/golang-wasm-parcel
go get github.com/hajimehoshi/ebiten/v2

Hello World

Let's create our main.go inside src directory, and write some code.

Now build it to WASM. To build Go code into WASM file, you must provide GOOS and GOARCH environment variables to go compiler.

GOOS=js GOARCH=wasm go build -o public/game.wasm src/main.go

Cool! Now we have our WASM file ready to go! Let's finish with HTML/JS part quickly to see our "Hello world" in console.

HTML/JS

To make all things work, we need 3 files:

  • wasm_exec.js, provided by Go team
  • main.js, to wrap all stuff together
  • and index.html

Let's copy wasm_exec.js from Go to our public folder (yes, its already on your computer, just copy it)

cp $(go env GOROOT)/misc/wasm/wasm_exec.js public

Great! Now, let's create main.js and connect wasm file using wasm_exec.js

Let me explain a bit what happening here.

First of all, to keep things clean, we imported wasm_exec.js directly to our main.js file to have single entry point for our bundler.

And because we are using Parcel as bundler, we imported wasm directly to our main.js as asset, with "url:" prefix.

After that, we wrote all necessary code to fetch and run our wasm file. Actually, you can just copy it from official Go example.

Hello World in console

That's it! All is left is index.html file and we are ready to enjoy our hello world in console.

Let's run index.html with parcel:

parcel public/index.html

Now we can go to http://localhost:1234, open browser console and see our "Hello World" message.

WebAssembly 2D Game: Hello World in Browser Console

Hooray! We arrived to our first git tag. You can check out all necessary code at this point using

git checkout boilerplate