|
| 1 | +# Building for the Web (WASM) |
| 2 | + |
| 3 | +--- |
| 4 | + |
| 5 | +***About this tutorial*** |
| 6 | + |
| 7 | +*This tutorial is free and open source, and all code uses the MIT license - so you are free to do with it as you like. My hope is that you will enjoy the tutorial, and make great games!* |
| 8 | + |
| 9 | +*If you enjoy this and would like me to keep writing, please consider supporting [my Patreon](https://www.patreon.com/blackfuture).* |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +Web Assembly is a cool system that lets you run code compiled from non-web-based languages and run them in the browser. It comes with a few limitations: |
| 14 | + |
| 15 | +* You are sandboxed, so you can't access much in the way of files on the user's computer. |
| 16 | +* Threads work differently in WASM, so normal multi-threading code may not work without help. |
| 17 | +* Your rendering back-end is going to be OpenGL, at least until WebGL is finished. |
| 18 | +* I haven't written code to access files from the web, so you have to embed your resources. The tutorial chapters do this with the various `rltk::embedded_resource!` calls. At the very least, you need to use `include_bytes!` or similar to store the resource in the executable. (Or you can help me write a file reader!) |
| 19 | + |
| 20 | +WASM is the tool used to make the playable chapter demos work in your browser. |
| 21 | + |
| 22 | +## Building for the Web |
| 23 | + |
| 24 | +The process for making a WASM version of your game is a little more involved than I'd like, but it works. I typically throw it into a batch file (or shell script) to automate the process. |
| 25 | + |
| 26 | +### The Tools You Need |
| 27 | + |
| 28 | +First of all, Rust needs to have the "target" installed to handle compilation to web assembly (WASM). The target name is `wasm32-unknown-unknown`. Assuming that you setup Rust with `rustup`, you can install it by typing: |
| 29 | + |
| 30 | +``` |
| 31 | +rustup target add wasm32-unknown-unknown |
| 32 | +``` |
| 33 | + |
| 34 | +You also need a tool called `wasm-bindgen`. This is a pretty impressive tool that can scan your web assembly and build the bits and pieces need to make the code run on the web. I use the command-line version (there are ways to integrate it into your system - hopefully that will be the topic of a future chapter). You can install the tool with: |
| 35 | + |
| 36 | +``` |
| 37 | +cargo install wasm-bindgen-cli |
| 38 | +``` |
| 39 | + |
| 40 | +*Note*: You'll have to reinstall `wasm-bindgen` when you update your Rust toolchain. |
| 41 | + |
| 42 | +### Step 1: Compile the program for WASM |
| 43 | + |
| 44 | +I recommend performing a `release` build for WASM. The debug versions can be *huge*, and nobody wants to wait while an enormous program downloads. Navigate to the root of your project, and type: |
| 45 | + |
| 46 | +``` |
| 47 | +cargo build --release --target wasm32-unknown-unknown |
| 48 | +``` |
| 49 | + |
| 50 | +The first time you do this, it will take *a while*. It has to recompile all the libraries you are using for web assembly! This creates files in the `target/wasm32-unknown-unknown/release/` folder. There will be several folders of build information and similar, and the important files: `yourproject.d` (debug information) and `yourproject.wasm` - the actual WASM target. (Replace `yourproject` with the name of your project) |
| 51 | + |
| 52 | +### Step 2: Determine where to put the files |
| 53 | + |
| 54 | +For the sake of simplicity, I'm going to use a target folder named `wasm`. You can use whatever you like, but you'll need to change the names in the rest of these instructions. Create the folder inside your root project folder. For example, `mkdir wasm`. |
| 55 | + |
| 56 | +### Step 3: Assemble web files |
| 57 | + |
| 58 | +Now you need to use `wasm-bindgen` to build the web infrastructure required to integrate with the browser. |
| 59 | + |
| 60 | +``` |
| 61 | +wasm-bindgen target\wasm32-unknown-unknown\release\yourproject.wasm --out-dir wasm --no-modules --no-typescript |
| 62 | +``` |
| 63 | + |
| 64 | +If you look inside the `wasm` folder, you will see two files: |
| 65 | + |
| 66 | +* `yourproject.js` - JavaScript bindings for your project |
| 67 | +* `yourproject_bg.wasm` - A modified version of the `wasm` output including the bindings required by the JavaScript file. |
| 68 | + |
| 69 | +I typically rename these files to `myblob.js` and `myblob_bg.wasm`. You don't have to do that, but it lets me use the same template HTML each time. |
| 70 | + |
| 71 | +### Step 4: Create some boilerplate HTML |
| 72 | + |
| 73 | +In your `wasm` folder, you need to make an HTML page to host/launch your application. I use the same boilerplate each time: |
| 74 | + |
| 75 | +```html |
| 76 | +<html> |
| 77 | + <head> |
| 78 | + <meta content="text/html;charset=utf-8" http-equiv="Content-Type" /> |
| 79 | + </head> |
| 80 | + <body> |
| 81 | + <canvas id="canvas" width="640" height="480"></canvas> |
| 82 | + <script src="./myblob.js"></script> |
| 83 | + <script> |
| 84 | + window.addEventListener("load", async () => { |
| 85 | + await wasm_bindgen("./myblob_bg.wasm"); |
| 86 | + }); |
| 87 | + </script> |
| 88 | + </body> |
| 89 | +</html> |
| 90 | +``` |
| 91 | + |
| 92 | +### Step 5: Host it! |
| 93 | + |
| 94 | +You can't run WASM from a local file source (presumably for security reasons). You need to put it into a web server, and run it from there. If you have web hosting, copy your `wasm` folder to wherever you want it. You can then open the web server URL in a browser, and your game runs. |
| 95 | + |
| 96 | +If you *don't* have web hosting, you need to install a local webserver, and serve it from there. |
| 97 | + |
| 98 | +## Help Wanted! |
| 99 | + |
| 100 | +I'd love to integrate this into `cargo web` or similar, to provide a simple process for compiling and serving your games. I haven't made this work yet. If anyone would like to help, please head over to [My Github](https://github.com/thebracket/rustrogueliketutorial) and get in touch with me! |
0 commit comments