- Rust 92.2%
- Shell 7.8%
| .cargo | ||
| src | ||
| .gitignore | ||
| build-wasm.sh | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
| rust-toolchain.toml | ||
snake
A snake game in Bevy.
Run natively
cargo run # release-ish dev profile
cargo run --features dev # + bevy-inspector-egui world inspector
Platform backends (X11/Wayland/WebGL2) are all in one feature list in Cargo.toml -
each is inert on the platforms it does not apply to, since winit and wgpu gate
them by target cfg - so neither command needs a --features flag.
Build for the web
./build-wasm.sh
python3 -m http.server -d web # then open http://localhost:8000
Needs the nightly toolchain (see rust-toolchain.toml), the
wasm32-unknown-unknown target, wasm-bindgen-cli matching the wasm-bindgen
version in Cargo.lock, and wasm-opt (binaryen).
Iterating on the game? FAST=1 ./build-wasm.sh skips the std rebuild, LTO and
wasm-opt, which turns a ~2.5 min rebuild into ~5 s at the cost of a much bigger
binary. Drop the flag for anything you ship.
CONVERGE=1 spends extra wasm-opt passes for a last ~1-2%.
Shipping builds keep Bevy's logging and panic messages, so the browser console
names a failure instead of trapping on unreachable. That costs ~237 KB brotli and
is worth it: a silent build cost three debugging round trips once already. All paths
in those strings are trimmed by trim-paths = "all" in [profile.wasm-release], so
they read bevy_render-0.19.0/src/... and no $CARGO_HOME or $HOME layout ships.
The renderer is WebGL2. WebGPU builds are ~790 KB smaller but have no fallback: a
browser that exposes navigator.gpu while requestAdapter() resolves to null -
Linux Chromium and Firefox today - fails with "No available adapters" and a blank
canvas, and wgpu picks its backend from navigator.gpu alone, so compiling both
backends does not save it.
How the binary is kept small
| lever | where |
|---|---|
| Only the needed Bevy features (no audio/3D/glTF/animation/scenes/picking/gizmos/reflection registry) | Cargo.toml |
World inspector, its reflection registry and the only egui dependency behind an off-by-default dev feature |
Cargo.toml, src/main.rs |
No egui: the menu/game-over screens are bevy_ui + bevy_text, whose default_font is an 18 KB built-in subset |
Cargo.toml, src/main.rs |
opt-level = "z", fat LTO, one codegen unit, panic = "abort", symbols stripped |
[profile.wasm-release] |
No panic locations (-Zlocation-detail=none via rustflags) |
[profile.wasm-release] |
wasm-opt -Oz, name/producers/debug sections removed |
build-wasm.sh |
Serve the .wasm with Content-Encoding: br (or gzip) - it compresses about 5:1.