What is WebAssembly?
You picked up this book (thanks!) so in all likelihood, you have some idea of what WebAssembly is, but just in case, let's grab a definition from https://WebAssembly.org:
In other words, Wasm is a binary format that we can compile other languages to so that we can run them in the browser. This is different than transpiling or source-to-source compiling, where languages such as TypeScript are converted into JavaScript for running in JavaScript environments. Those languages are still ultimately running JavaScript, whereas Wasm is bytecode. This makes it a smaller download and parsing and compiling steps are removed when running it, which can lead to significant performance improvements. But let's be honest – you're not using Rust and Wasm for the performance improvements, which aren't guaranteed anyway. You're using it because you like Rust.
And that's okay!
Rust has a great type system, excellent developer tooling, and a fantastic community. While WebAssembly was originally created with C and C++ in mind, Rust is a fantastic language for WebAssembly for all the reasons you love Rust and more. Now, for most of the web's existence, writing applications to run in a browser meant writing JavaScript, and over the years, JavaScript has evolved into a suitably modern language for that purpose. I'm not here to tell you that if you like JavaScript you should stop, but if you love Rust, you should absolutely start compiling to Wasm and running apps in the browser.
Important Note
This book is focused on making web-based games with Rust and Wasm, but you can absolutely run Wasm apps in server-side environments such as Node.js. If you're interested in that, you can check out the book Learn WebAssembly by Mike Rourke, which can be found at https://bit.ly/2N89prp, or the official wasm-bindgen
guide at https://bit.ly/39WC63G.
Important Note
This book assumes some familiarity with Rust, although you do not need to be an expert. If at any time you're confused by a Rust concept, I highly encourage you to stop and check "the book", The Rust Programming Language, available for free at https://doc.rust-lang.org/book/.
So, now that I've convinced you to do what you were already going to do anyway, let's go over some of the tools you'll need to write a game for the web in Rust:
rustup
: Most likely you're already usingrustup
if you're writing Rust code. If you're not, you should, as it's the standard way to install Rust. It allows for easy installations of toolchains, Rust compilers, and even launches the Rust documentation. You'll need it to install the Wasm toolchain, and you can install it from the previous link. The code in this book has been tested on Rust version 1.57.0.- Node.js: I know – I promised you that we'd be writing in Rust! We will, but this is still a web application and you'll be using Node.js to run the application. I recommend installing the current long-term support version (16.13.0 at the time of writing). Older versions of Node.js may not work with the package creation tools as expected. If you're using Ubuntu Linux, be especially cautious when using the Debian distribution, which installs a very old version at this time. When in doubt, use tools for managing multiple versions, such as the Node Version Manager (nvm) tool for Linux/Mac or the corresponding nvm-windows tool for Windows, to ensure that you're using the long-term release version. I use the asdf tool (https://asdf-vm.com/) for managing multiple versions myself, although I don't usually recommend it to people that haven't used a version management tool before.
- webpack: We'll use webpack to bundle our application for release and run a development server. Most of the time, you won't have to worry about it, but it's there.
Important Note
The current template uses webpack 4. Make sure to check that when looking up documentation.
wasm-pack
: This is a Rust tool for building Rust-generated WebAssembly code. Like webpack, most of the time you won't know it's there, as it's managed by webpack, and your Rust application will largely be managed by Rust build tools.wasm-bindgen
: This is one of the crates you'll need to get to know to write Rust-generated WebAssembly code. One limitation of WebAssembly is that you cannot access the Document Object Model (DOM) that represents a web page directly. Instead, WebAssembly programs need to call JavaScript functions to do that, requiring bindings and serializing data back and forth. Whatwasm-bindgen
does is create those bindings and the boilerplate needed to call JavaScript functions from your Rust code, as well as provide tools to create bindings in the other direction so that JavaScript code can call back into the Rust code. We'll cover the details of howwasm-bindgen
works as we go through the book, but to avoid getting bogged down in details right now, you can just think of it as a library to call JavaScript from your Rust code.web-sys
: This is a crate made up of many pre-generated bindings, usingwasm-bindgen
, for the web. We'll useweb-sys
to call browser APIs such as the canvas andrequestAnimationFrame
. This book assumes at least a passing familiarity with web development but doesn't require expertise in this area, and in fact, one of the advantages of game development in Rust is that we can just treat the browser as a platform library that we call functions on. Theweb-sys
crate means we don't have to create all those bindings ourselves.Canvas
: HTML Canvas is a<canvas>
browser element, such as headers or paragraphs, only it allows you to draw directly to it. This is how we can make a video game! There are many ways to draw to the canvas, includingWebGL
andWebGPU
, but we're going to use the built-in Canvas API for most of this project. While this isn't the absolute fastest way of making a game, it's fast enough for learning purposes and avoids adding more technologies to our stack.
Finally, while googling web-sys
, web-bindgen
, or other Rust packages for WebAssembly, you are likely to come across references to cargo-web
and stdweb
. While both of those projects were important to the development of Rust as a WebAssembly source, neither has been updated since 2019 and can be safely ignored. Now that we know the tools we'll be using, let's start building our first Rust project.