Book Image

Game Development with Rust and WebAssembly

By : Eric Smith
Book Image

Game Development with Rust and WebAssembly

By: Eric Smith

Overview of this book

The Rust programming language has held the most-loved technology ranking on Stack Overflow for 6 years running, while JavaScript has been the most-used programming language for 9 years straight as it runs on every web browser. Now, thanks to WebAssembly (or Wasm), you can use the language you love on the platform that's everywhere. This book is an easy-to-follow reference to help you develop your own games, teaching you all about game development and how to create an endless runner from scratch. You'll begin by drawing simple graphics in the browser window, and then learn how to move the main character across the screen. You'll also create a game loop, a renderer, and more, all written entirely in Rust. After getting simple shapes onto the screen, you'll scale the challenge by adding sprites, sounds, and user input. As you advance, you'll discover how to implement a procedurally generated world. Finally, you'll learn how to keep your Rust code clean and organized so you can continue to implement new features and deploy your app on the web. By the end of this Rust programming book, you'll build a 2D game in Rust, deploy it to the web, and be confident enough to start building your own games.
Table of Contents (16 chapters)
1
Part 1: Getting Started with Rust, WebAssembly, and Game Development
4
Part 2: Writing Your Endless Runner
11
Part 3: Testing and Advanced Tricks

A Rust project skeleton

Important Note

These directions are based on the status of rust-webpack-template at the time of writing. It's likely to have changed at the time of reading this, so pay close attention to the changes we are making. If they don't make sense, check the documents for wasm-pack and use your best judgment.

At this point, I'm going to assume you've installed rustup and Node.js. If you haven't, go ahead and follow the instructions for your platform to install them, and then follow these steps:

  1. Initialize the project

Let's start by creating a project skeleton for your application, which will be the Rust webpack Template from the Rust Wasm group. It's found on GitHub at https://github.com/rustwasm/rust-webpack-template, but you don't want to download it. Instead, use npm init to create it, like this:

mkdir walk-the-dog
cd walk-the-dog
npm init rust-webpack

You should see something like this:

npx: installed 17 in 1.941s
 🦀 Rust + 🕸 WebAssembly + Webpack = ❤
Installed dependencies ✅

Congratulations! You have created your project.

  1. Install dependencies

You can install the dependencies with npm:

npm install

Important Note

If you prefer to use yarn, you can, with the exception of the npm init command. I'll be using npm for this book.

  1. Run the server

After the installation completes, you can now run a development server with npm run start. You may see an error, like this:

ℹ  Installing wasm-pack
Error: Rust compilation.
at ChildProcess.<anonymous> (/walk-the-dog/node_modules/@wasm-tool/wasm-pack-plugin/plugin.js:221:16)
at ChildProcess.emit (events.js:315:20)
at maybeClose (internal/child_process.js:1048:16)
at Socket.<anonymous> (internal/child_process.js:439:11)
at Socket.emit (events.js:315:20)
at Pipe.<anonymous> (net.js:673:12)

If that happens, you'll need to install wasm-pack manually.

  1. Install wasm-pack

On Linux and macOS systems wasm-pack is installed with a simple cURL script:

curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

Windows users have a separate installer that can be found at https://rustwasm.github.io.

  1. Run the server – take two

Now that wasm-pack is installed, webpack can use it, and you should be able to run the app:

npm run start

When you see wdm: Compiled successfully. , you can browse your app at http://localhost:8080. Okay, yes, it's a blank page, but if you open the developer tools console, you should see the following:

Figure 1.1 – Hello WebAssembly!

Figure 1.1 – Hello WebAssembly!

You've got the application running in the browser, but the Rust ecosystem updates faster than the template you used can keep up.

  1. Update the Rust edition

The latest Rust edition, with the most recent Rust idioms and conventions, is 2021. This is changed in the generated Cargo.toml file in the package section, as shown here:

# You must change these to your own details.
[package]
name = "rust-webpack-template"
description = "Walk the Dog - the game for the Rust Games with WebAssembly book"
version = "0.1.0"
authors = ["Eric Smith <[email protected]>"]
categories = ["wasm"]
readme = "README.md"
edition = "2021"

It is only the edition field that is changed here.

  1. Update the dependencies

The dependencies in the generated Cargo.toml file are not going to be the latest and greatest unless you happened to pull the template down the moment it was updated. Since neither of us is that lucky, you're going to want to open up that file and modify the dependencies to the following. Please note that the ellipses are just there to mark a gap in the file and are not meant to be typed in:

wasm-bindgen = "0.2.78"
...
[dependencies.web-sys]
version = "0.3.55"
...
[dev-dependencies]
wasm-bindgen-test = "0.3.28"
futures = "0.3.18"
js-sys = "0.3.55"
wasm-bindgen-futures = "0.4.28"

Those are the versions I used while writing this book. If you're feeling adventurous, you can go to http://crates.io and find the most recent version of each dependency, which is what I would do, but I am a glutton for punishment. You're probably smarter than me and will use the versions specified here so that the sample code works.

  1. Update console_error_panic_hook

console_error_panic_hook is a very useful crate during the development of a WebAssembly application. It takes panics in Rust code and forwards them to the console so that you can debug them. The current template attempts to hide it behind a feature flag, but unfortunately, there's a bug and it doesn't work. Remember to double-check your generated code; if it doesn't look like what I've reproduced here, the bug may have been fixed, but in the meantime, delete the following code (still in Cargo.toml).

[target."cfg(debug_assertions)".dependencies]
console_error_panic_hook = "0.1.5"

Then add the to the [dependencies] section, under wasm-bindgen is a good spot:

console_error_panic_hook = "0.1.7"

Later, we'll make this a conditional dependency so that you don't deploy it during release builds, but for now, this is enough progress. Who wants to continue messing with config files anyway? I want to draw stuff to the screen!

Tip

While this application uses an npm init template to create itself, you can use its output to create a cargo generate template so that you don't have to redo these changes every time you create an application, simply by creating a git repository. Of course, if you do that, you'll fall behind changes to the rust-webpack template, so it's a trade-off. If you're curious about using cargo generate to create your own templates, you can find more information here: https://bit.ly/3hCFWTs.