| Crates.io | twors |
| lib.rs | twors |
| version | 0.4.0 |
| created_at | 2025-04-19 22:37:37.872531+00 |
| updated_at | 2025-05-10 17:30:56.303329+00 |
| description | A simple Rust 2D game engine based on canvas and WASM |
| homepage | |
| repository | https://github.com/vimlucid/twors |
| max_upload_size | |
| id | 1641193 |
| size | 108,469 |
Easily render 2D graphics in a canvas using WASM - entirely powered by Rust!!! 🦀
This tiny renderer is for people who:
WASM's use case is either the reuse of code written in another language or to offload heavy computations to the near-native execution speeds of WASM.
However this is not free - traversing the WASM boundary means going trough some glue code and copying data from JS to the WASM module memory and back. In the case of strings it's even more expensive - because JS strings are UTF-16 and Rust strings use UTF-8 any string passtrough needs to go trough a copy AND a re-encode.
twors doesn't have any complicated physics to offload to WASM at this point in time - neither
is it making use of some advanced pre-existing Rust library. So why Rust then?
⭐ Simply because Rust is the best!!! ⭐
twors you can run the examples/playground crate in this repo
git clone https://github.com/vimlucid/twors
cd twors
cargo install cargo-make
cargo make watch # this assumes you have the `cp` command - e.g. it won't work in Windows CMD
# edit the source code in examples/playground and manually refresh http://localhost:8080
twors to your own crate - check out the Installation and build guide✅ TwoRS's goal is to be simple. It provides:
❌ TwoRS does not currently have (and aim) to provide:
Compiling a WASM library is a bit more involved than simply executing cargo run, but
it's pretty straightforward if you know the steps.
We'll basically:
twors engineindex.html with some JavaScript (just enough to run our WASM library)Once we do this all of the remaining code can be written entirely in Rust!
You are of course free to mix and match as you like.
lib crateIn order to compile Rust into WASM via wasm-pack
(an amazing WASM compilation helper) it's necessary to have a lib crate first
cargo new twors-demo --lib
twors, wasm_bindgen and console_logcargo add twors
cargo add wasm_bindgen
cargo add console_log
twors engine.use twors::{Engine, Result};
use wasm_bindgen::prelude::wasm_bindgen;
use std::collections::HashMap;
use console_log;
// The "wasm_bindgen" attribute will generate glue both on the JS and on the WASM sides.
// Passing Rust types like `&str` from JS is thanks to the magic of `wasm_bindgen`.
#[wasm_bindgen]
pub fn entry(canvas_id: &str) -> Result<()> {
console_log::init().unwrap(); // Setup logger frontends to use our browser-capable logger.
// Pass a list of components to render on the canvas.
// We'll add an index.html file with said canvas later.
let engine = Engine::new(canvas_id, Vec::default())?;
engine.run()?;
Ok(())
}
Add a lib section to your Cargo.toml file (if you don't already have one) and set
the crate-type property to cdylib.
The wasm32-unknown-unknown compile target (what wasm-pack makes the Rust compiler use) will
detect this and produce a WASM library.
[lib]
crate-type = ["cdylib"]
wasm-pack and build your WASM libraryThe following wasm-pack --build command will produce a pkg folder in your crate's root -
this folder will contain the WASM library as well as the JS part of the glue code that's
needed for the WASM-JS communication.
cargo install wasm-pack
wasm-pack build --target web
examples/assets/index.html to the pkg folder in your crate's rootWe have compiled our WASM library - now we need to call it from JS. The example index.html
will:
entry method (that we created earlier) by passing it the canvas ID.# navigate to your crate root and execute the following
cp ./examples/assets/index.html ./pkg
NOTE: If you don't have the
cpcommand (e.g. if you are using Windows CMD) you can always copy theindex.htmlmanually.
pkg directory at the crate rootYou will need to serve the WASM library with the application/wasm MIME type or the browser
will refuse to run it. A great server that does this automatically is
miniserve
cargo intall miniserve
miniserve ./pkg --index index.html
Experiments and manual testing during development can be done in the examples/playground crate.
# convenience scripts - see "Makefile.toml" for full list of commands
cargo install cargo-make
# run local pre-commit checks - will be run on "build" automatically
cargo make install-git-hooks
cargo make build # build the "playground" crate as a WASM module
cargo make serve # like "build", but will also start a HTTP server
cargo make watch # like "serve", but will restart the server on changes
# other commands
cargo make test
cargo make clean
cargo make format
cargo make licenses # update licenses.html (run after dependency addition/removal)
wasm_assert! instead of assert! in non-test code to see error messages
in the browser console.