This is an article summarizing my expeditions to rust frontiers. This will be a walkthrough in building my small game / (ideally) multiplayer app in Rust / JS. (Part 1)
In googling for articles that might help me both learn Rust and develop something interesting I came across a few expired examples. I was excited to just get going so I went down the "rogue-like" game after coming across this tutorial online: Roguelike Tutorial - In Rust published in 2019. Pretty cool tutorial but unfortunately it had a few broken links and repos that wouldn't compile.
I decided to follow this tutorial, and try to glue the spaces that we're broken by searching for a functioning version elsewhere and then jumping back. Cool, so section "1. Building for the web" talks about the tools we'd need to compile something from Rust into something consumable by the web. This means using WASM and its rust tools,
# This is needed to handle compilation to web assemply (WASM)
$ rustup target add wasm32-unknown-unknown
# the next to was wasm-bindgen-cli, note this was borked and the first deviation from the tutorial. It installs fine but doesn't compile later on.
$ cargo install wasm-bindgen-cli
# ... There were more steps to follow but at the point where I had to run
$ wasm-bindgen target\wasm32-unknown-unknown\release\yourproject.wasm --out-dir wasm --no-modules --no-typescript
# ... I had to pivot and find a repo that worked around the
# error "# How to deal with missing intrinsics" in my `case clone_ref`.
I couldn't get this to compile since I'm just learning rust and the manual solution, which were suggestions here https://github.com/rust-lang/compiler-builtins/issues/387 , seemed above my level for now. So, I continued to look for other solutions I could use to keep moving forward and started digging through this gitbook https://rustwasm.github.io/wasm-bindgen/ but ran into another issue here as well with the hello world. I was hoping to maybe find a similar command to the one above but with an explanation, but this wouldn't compile due to the flow it took when creating a www wasm-app. Seems like the webpack version just didn't anymore according to these:
1. [https://github.com/rustwasm/create-wasm-app/issues/215](https://github.com/rustwasm/create-wasm-app/issues/215) [↩](https://github.com/parrotmac/rust-wasm-hello-world?tab=readme-ov-file#user-content-fnref-1-0b7f6e7f3883b4e8cce02779a68ed92a)
2. [https://github.com/rustwasm/wasm-bindgen/issues/4251](https://github.com/rustwasm/wasm-bindgen/issues/4251) [↩](https://github.com/parrotmac/rust-wasm-hello-world?tab=readme-ov-file#user-content-fnref-2-0b7f6e7f3883b4e8cce02779a68ed92a)
3. [https://github.com/rustwasm/wasm-bindgen/issues/4211#issue-2598192238](https://github.com/rustwasm/wasm-bindgen/issues/4211#issue-2598192238) [↩](https://github.com/parrotmac/rust-wasm-hello-world?tab=readme-ov-file#user-content-fnref-3-0b7f6e7f3883b4e8cce02779a68ed92a)
4. [https://github.com/rustwasm/rust-webpack-template/issues/191](https://github.com/rustwasm/rust-webpack-template/issues/191) [↩](https://github.com/parrotmac/rust-wasm-hello-world?tab=readme-ov-file#user-content-fnref-4-0b7f6e7f3883b4e8cce02779a68ed92a)
5. [https://github.com/rustwasm/wasm-bindgen/discussions/4171](https://github.com/rustwasm/wasm-bindgen/discussions/4171) [↩](https://github.com/parrotmac/rust-wasm-hello-world?tab=readme-ov-file#user-content-fnref-5-0b7f6e7f3883b4e8cce02779a68ed92a)
But luckily @parrotmac was able to get a version ported to vitejs up and running here: https://github.com/parrotmac/rust-wasm-hello-world And it did compile and work.
At this point I felt like I need to get the first tutorial, building wasm for the front end done first. I started down wasm-game-of-life, using parrotmac's template to get a grasp on building files first before I move on to the more fun stuff.
I was able to update the deps for vite and other libs, and get the hello world example in my fork for https://github.com/alexortiz201/rust-wasm-hello-world .
First, I was recently on a trip and realized how important offline docs are, hence looking into https://rust-lang.github.io/mdBook/cli/index.html . This way I can work on this and use the mdbook
format to save the roguelike book at https://github.com/amethyst/rustrogueliketutorial.
Once I was ready to start loading my updated template repo as mentioned in the tutorial, I'm relying on wasm-pack build
inside the directory since wasm-bindgen
causes issues. I started with the simple terminal main.rs example for the roguelike. I figured I'll get this work and then try to pass this to the front end via WASM. I tried to get the rltk example going but after some time I ended up at the latest rltk crate where they had update the syntax for the game state implementation.
...(RADIO SILENCE)
Turns out after a ton of back and forth with chat gippty, I was finally able to get the the example working via WASM. What did it take you ask? Well let me tell you, first I started by exploring why it wouldn't compile. Turns out a major bump in the version of getrandom breaks when used in rltk. So I had to revert that to 0.2.15
to get it working. After that though, it wouldn't compile because main is not allowed to be called in lib.rs. So I learned main is for binaries and lib is for modules, all of which is a rust convention. Also, binaries can consume modules but not vice versa and rltk's example only shows what was built for the CLI (binary). It took me a long time to get to where wasm-build would compile for the web and cargo run could still run the binary, but I got it done. Eventually it was all building but WASM as panic'ing and all I would see was "Unreachable" in the console. This is where I was stuck for another day but was finally able to get it working by adding
#[cfg(target_arch = "wasm32")]
use console_error_panic_hook::set_once as set_panic_hook;
#[cfg(target_arch = "wasm32")]
use web_sys::console;
fn main() -> RltkError {
#[cfg(target_arch = "wasm32")]
set_panic_hook();
...
if let Err(e) = rltk::main_loop(context, gs) { // ✅ No unwrap()
#[cfg(target_arch = "wasm32")]
console::error_1(&format!("WASM Game Loop Error: {:?}", e).into());
}
}
Ok(())
to the main function in main.rs. This let me see the error panic'ing in the WASM which turned out to be a missing canvas HTMLElement, which rltk draws onto. Success!
Now,
# Would just work, inside of /www
npx vite
# this deploy to localhost:<PORT>/index.html