Bevy is a free and open source, data-driven game engine written in Rust. It is built around an ECS (Entity Component System) architecture: game state lives in components, and plain Rust functions ("systems") run over them in parallel. Bevy has no visual editor — projects are pure Cargo crates — which makes it a natural fit for a Makefile + CI workflow. First-class WebAssembly support means the same code base runs natively and in the browser.
Website: https://bevyengine.org
This Makefile provides a simple, reproducible workflow for building Bevy projects natively and exporting them to the web (WASM via
wasm-bindgen). It is designed for indie game development with automated version management and CI/CD deployment support.
The workflow is based on four core ideas:
cargo build; web builds target wasm32-unknown-unknown and run wasm-bindgen to generate the JS glue (game.js + game_bg.wasm)index.html) is downloaded from the tools repository at export time, so every game ships the same loadermetadata.json or git commit hashThe templates live in the bevy-tools repository: copy example-makefile.make to Makefile and set PROJECT (it must match the crate name in Cargo.toml).
Version pinning: the wasm-bindgen CLI and the wasm-bindgen crate compiled into the game must be the same version. Pin the crate in Cargo.toml:
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "=0.2.100"
and keep WASM_BINDGEN_VERSION in the Makefile in sync. The CI builder image (git.teletypegames.org/internal/bevy-builder) ships the matching CLI — rebuild it with the new --build-arg WASM_BINDGEN_VERSION when bumping.
| Variable | Description | Default |
|---|---|---|
PROJECT |
Project / crate name (used in output filenames) | bevydemo |
WASM_BINDGEN_VERSION |
wasm-bindgen CLI version (must match Cargo.toml) | 0.2.100 |
BIN_DIR |
Directory for the native binary | bin |
DIST_DIR |
Directory for exported artifacts | dist |
VERSION_FILE |
File storing version for CI/CD | .version |
INDEX_HTML_URL |
HTML shell downloaded at export time | bevy-tools web/index.html |
make build
cargo build --release and copies the binary to bin/$(PROJECT)make run
cargo run)make wasm
wasm32-unknown-unknown in release modewasm-bindgen --target web producing dist/game.js and dist/game_bg.wasmrustup target add wasm32-unknown-unknown and the wasm-bindgen CLI (cargo install wasm-bindgen-cli --version 0.2.100)make export VERSION=1.0.0
VERSION variable.index.html, and packages everything into a versioned ZIP: bevydemo-1.0.0.html.zipmake watch
src/ (requires fswatch)make clean
bin/, dist/ and the Cargo target/ directoryThe tools repository also contains an example-tasks.json that can be copied to .vscode/tasks.json. It provides Run (cargo run, default build task, Cmd+Shift+B), Build & Run, Build WASM and Make build.
make ci-versionmetadata.json (if exists) or uses git short commit hashmain or master, prefixes version as dev-<version>-<branch>.versionmake ci-export.version and runs make export with itmake ci-uploadmetadata.json to bevydemo-<version>.metadata.jsonDROPAREA_SSH_PASSWORD, DROPAREA_PORT, DROPAREA_USER, DROPAREA_HOST, DROPAREA_TARGET_PATHmake ci-update$(UPDATE_SERVER)/update?platform=bevy&name=$(PROJECT)&version=<version>UPDATE_SERVER, UPDATE_SECRET| File | Description |
|---|---|
bin/bevydemo |
Native release binary |
dist/game.js, dist/game_bg.wasm |
wasm-bindgen output (packaged, then removed) |
bevydemo-<version>.html.zip |
Packaged web build, ready for deployment |
make, git, jq, zip, curlcargo, rustup) with the wasm32-unknown-unknown targetwasm-bindgen CLI matching WASM_BINDGEN_VERSIONfswatch (only for watch mode)sshpass and scp (for ci-upload target)This document describes the Woodpecker CI pipeline used to build, export, upload, and publish a Bevy game project.
The pipeline logic is almost entirely encapsulated within the Makefile, which is called by each pipeline step. The pipeline performs the following steps:
make ci-version (alpine) — version from metadata.json or git.make ci-export in the git.teletypegames.org/internal/bevy-builder image (Rust toolchain with the wasm32-unknown-unknown target and the wasm-bindgen CLI preinstalled, built from builder.Dockerfile in bevy-tools) — builds and packages the ZIP.make ci-upload — scp to the droparea (vps.teletype.hu:2223).make ci-update — calls the teletypegames /update endpoint with platform=bevy.Copy example-woodpecker.yaml to .woodpecker.yaml and add the droparea_ssh_password / update_secret_key secrets in Woodpecker.
Note: a cold Bevy release build compiles several hundred crates — expect the build step to take considerably longer than the other engines' pipelines.
bevy-demo is the reference project using these templates: an animated "TELETYPE GAMES" wave text (the same demo as ebitengine-demo), built on Bevy 0.16.