topheman / bevy-rust-wasm-experiments

πŸ¦€ A small video game developed in Rust with Bevy framework targeting both desktop and WebAssembly (browser)

Home Page:https://bevy-rust-wasm-experiments.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bevy-rust-wasm-experiments

Demo

This project is a proof of concept that aims to demonstrate how to code a video game in rust that compiles both to:

  • a binary executable on OS desktop such as MacOS, Linux or Windows ...
  • a web site, that you could access with any browser (via WebAssembly)

The web version is shipping with some features in addition, such as accelerometer support (if you load it on your smartphone πŸ“±), which should integrate seemlessly into the rust source code.

Previous work

In the last five years I've done a few projects involving rust and WebAssembly:

Ten years ago, I made a small video game in JavaScript that you can play on your smartphone's browser: topheman/bombs which inspired this current project.

Summary

Contributing

A Makefile is available with a list of tasks.

Prerequisites

  • node@>=18
  • rust@>=1.67.0

Setup

# If you haven't yet, wasm support to your rust installation
rustup target install wasm32-unknown-unknown

# Mandatory crates
cargo install wasm-bindgen-cli@0.2.86 # cli for wasm-bindgen implementation shipped in Cargo.toml
cargo install wasm-opt # cli that optimizes wasm payload

# Optional crates for development
cargo install wasm-server-runner # https://github.com/jakobhellermann/wasm-server-runner
cargo install cargo-watch # https://github.com/watchexec/cargo-watch

Folder organization

β”œβ”€β”€ assets (contains the images/fonts used in the app)
β”œβ”€β”€ dev.html (custom endpoint used for when running with wasm-server-runner)
β”œβ”€β”€ src (source code of the rust application)
β”œβ”€β”€ target
└── www (source code of the web part)
    β”œβ”€β”€ dist
    β”œβ”€β”€ global.js (bindings exposed to wasm-bindgen, used by both dev.html and www/index.html)
    β”œβ”€β”€ index.html (endpoint used in the final web server)
    β”œβ”€β”€ public
    β”‚   β”œβ”€β”€ assets -> ../../assets (symlink to the asset dir so that they will be picked by the bundler and expose to the browser)

Development

Desktop

cargo run
# `make desktop-dev` is an alias for πŸ‘†

You can compile in watch mode, thanks to cargo-watch and bevy dynamic linking feature:

cargo watch -q -c -x 'run --features bevy/dynamic'
# `make desktop-dev-watch` is an alias for πŸ‘†

WebAssembly

The following will compile the project in WebAssembly and make it available at http://localhost:3000/dev.html

WASM_SERVER_RUNNER_ADDRESS=0.0.0.0:3000 cargo run --target wasm32-unknown-unknown
# `make wasm-dev` is an alias for πŸ‘†

Web part

When you need to customize the html/js/css that will end up on the server, you will code in www.

The following code will compile the WebAssembly version, generate wasm glue code, build the www artefact and launch a server on http://localhost:3000

# compile WebAssembly version + generate wasm glue code + build the www artefact + launch a server
make www-build && make www-preview

You can launch a dev server for www:

make www-dev

Production

Same as make www-build, but wasm-opt is run on the wasm payload to make it lighter.

make www-build-opt

CI/CD

I'm using github-actions for the CI and I deploy to vercel from there (can't use vercel for the whole pipeline since we need the rust toolchain with WebAssembly).

On each pull request:

  1. the project is compiled from rust to WebAssembly
  2. the WebAssembly output goes through wasm-bindgen which generates the glue code between wasm and JavaScript (it also goes through wasm-opt to optimize the size of the wasm file)
  3. the output from the previous step is fed up to the vite pipeline which generates a static site
  4. finally, the website is automatically published to vercel
  5. a comment is left on the PR with the generated url of the deployment

https

Acceleremeter only works on secure origins, so when you will try to access the app on your smartphone via your local ip (like 192.168.1.1), it won't work, since the domain will be recognized as unsecure.

You'll need to tunnel the app with a utility like localhost.run or ngrok that will open an ssh tunnel and forward traffic on https. Please run the following one time:

make forward # with ngrok
make forward-fallback # with localhost.run

The public https temporary address will be outputted on your terminal (keep in mind you won't access your website through your local network but through the internet, which can take longer - use that only to test accelerometer on mobile devices).

Assets

Resources

About

πŸ¦€ A small video game developed in Rust with Bevy framework targeting both desktop and WebAssembly (browser)

https://bevy-rust-wasm-experiments.vercel.app

License:MIT License


Languages

Language:Rust 60.1%Language:HTML 14.5%Language:JavaScript 13.7%Language:CSS 6.9%Language:Makefile 4.5%Language:Shell 0.2%