TL;DR

For those of you in a hurry: I made a version of the classic Pong game using Go and WebAssembly. I then embedded that game on my website. Warning: it works only on desktop now (no handling of touch). Here is the game, enjoy:

Why WebAssembly

WebAssembly is a relatively new standard on web browsers. From the Wikipedia page:

The main goal of WebAssembly is to enable high-performance applications on web pages, but the format is designed to be executed and integrated in other environments as well. (…) WebAssembly (i.e. WebAssembly Core Specification and WebAssembly JavaScript Interface) became World Wide Web Consortium recommendations on 5 December 2019 and, alongside HTML, CSS, and JavaScript, is the fourth language to run natively in browsers.

Although it can be used on other interfaces, the WebAssembly standard basically allows to run code written in another language than HTML or JavaScript, so long as it can be compiled into WebAssembly language, which can be seen as the equivalent as assembly code for any JavaScript virtual machine, but in particular web browsers. The output .wasm file of any WebAssembly project can be read and interpreted directly by any web browser following the WWW spec. The project was kicked off and first maintained by the Mozilla foundation. The documentation can be found on the official website.

Why Go

At Moona, our backend API server runs on go. I really like this language as it is simple to write, yet feature-rich and performant, with a large community and adoption by tech companies working on large-scale infrastructure and systems (Google, Amazon, Netflix, Docker, Cloudflare…). There should always be one “canonic” way to do one thing, which makes reasoning about code easier, freeing up some mental load. It’s a compiled, statically-typed language so it catches more potential errors upstream, it’s garbage-collected so no need to manage memory, it handles concurrency natively and it’s fast.

Why Pong

Pong is a classic game made popular by Atari systems, and was one of the first home video games ever commercialized. I wanted to try out WebAssembly with Go on a simple and classic game which can be played against an AI or another human to make it more fun.

Coding the game

At first I had written this game using the Go port of the SDL2 library, originally written in C, which allows to access audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D, in order to code native user interfaces (including games) easily. Credit goes to Jack Mott for his tutorial series Games with Go for the initial version, which was inspired from his videos and modified to fit my needs.

But while porting the game to WebAssembly, I looked for ways to simplify development. So I found this 2D gaming library named Ebiten by Hajime Hoshi which was perfectly suited for the job, as it handles game loop, 60FPS graphics, inputs, text, audio, sprites etc. and can compile to WebAssembly (!!!). I refactored the code to fit the new library.

The code is organized into:

  • package pong which contains all the game objects and structures (paddles, ball, text, colors, enums), as well as logic specific to these objects. The two paddles and the ball can be Updated and Drawn on the screen.
  • package main which contains the game loop and logic dependent on the game states
  • package server which is a super simple HTTP server for the WebAssembly version

The game has several states which are simple and grouped into a go struct as follows:

// there can be only up to 256 game states ¯\_(ツ)_/¯
type GameState byte

const (
	StartState GameState = iota
	ControlsState
	PlayState
	InterState
	PauseState
	GameOverState
)

The game logic is pretty straightforward. There are still some small glitches but overall it’s an easy piece of code, just for demo purposes. You can find it on my github here.

#go #webassembly #game-development

Making Pong with Go and WebAssembly
2.25 GEEK