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:
- WebAssembly 2D game with Go. Part 2: First Steps.
- WebAssembly 2D game with Go. Part 3: Drawing character.
- WebAssembly 2D game with Go. Part 4: Moving character.
- WebAssembly 2D game with Go. Part 5: Docker stuff & Deploy
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.
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 firstname.lastname@example.org:michaelknyazev/golang-wasm-parcel.git
So, let's begin our adventure.
First of all, let's create simple boilerplate.
In this section we will
- Organize project structure
- Log "Hello World" using Go into console and build it to WASM
- Create main.js and connect our wasm file using wasm_exec.js from Go
- Create index.html and See our Hello World in browser console :)
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.
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
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.
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:
Now we can go to http://localhost:1234, open browser console and see our "Hello World" message.
Hooray! We arrived to our first git tag. You can check out all necessary code at this point using
git checkout boilerplate