This article was first written for Bevy 0.5. The release of Bevy 0.6, on the actual day I wrote this article, made it obsolete. Those b******** keep making their product better...
Bevy 0.6 added out of the box support for running their application for the web.
The first part of the article will describe how to deploy an application to the web with Bevy 0.6, the second part is what I originally wrote for Bevy 0.5.
Bevy 0.6
Originally, this article was part 14 of my Bevy Platformer tutorial. This time, I will use a simple Tic-Tac-Toe game example that can be found here. With a working web deployment here.
Prerequesites
First, you need to be able to compile to web assembly:
rustup target add wasm32-unknown-unknown
Second, you will need the wasm-bindgen-cli
:
cargo install -f wasm-bindgen-cli
Building the code
cargo build --release --target wasm32-unknown-unknown
wasm-bindgen --out-dir ./out/ --target web ./target/wasm32-unknown-unknown/release/tic-tac-toe.wasm
Running on the Web
First you will need an index.html
file:
<html>
<head>
<meta charset="UTF-8" />
<style>
body {
margin: 0;
background: linear-gradient(-45deg, #a6a6a6, #5ac05a, #262626, #a6a6a6);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
canvas {
background-color: white;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
</style>
</head>
<script type="module">
import init from './out/tic-tac-toe.js'
init()
</script>
</html>
Finally, you need to serve this HTML file:
npx serve .
And then visit http://localhost:3000
to confirm everything works fine.
Note that npx serve .
requires to have Node JS installed on your machine.
Original Content (with Bevy 0.5)
If you did not read the previous articles, you can start here.
This article will show how to deploy our project as a web application.
Most of the things covered here are explained in greater details in Bevy's Unofficial Cheat Book.
Prerequesites
First, you need to be able to compile to web assembly:
rustup target add wasm32-unknown-unknown
Second, you need to install wasm-pack
:
cargo install wasm-pack
Cargo Configuration
[package]
name = "platformer"
version = "0.1.0"
edition = "2021"
resolver = "2"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
wasm-bindgen = "0.2"
bevy_rapier2d = { version = "0.11.0", features = [ "wasm-bindgen" ] }
rand = "0.8.4"
getrandom = { version = "0.2", features = ["js"] }
# Dependencies for native only.
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
bevy = {version = "0.5", default-features = false, features = ["bevy_wgpu", "bevy_winit", "render", "x11"]}
# Dependencies for WASM only.
[target.'cfg(target_arch = "wasm32")'.dependencies]
bevy = {version = "0.5", default-features = false, features = ["bevy_winit", "render"]}
bevy_webgl2 = "0.5"
What was done here:
- Set the cargo resolver to version 2.
- Added
[lib]
tag with thecdylib
andrlib
types. - Added
wasm-bindgen
as a dependency. This is the crate responsible for the interoperability between JS and Rust. - Added the
wasm-bindgen
feature flag to rapier. - Splitted the bevy dependency in 2. One for the web, the other for native development. In both cases, the required feature flags are set.
- Added
bevy_webgl2
to the wasm dependencies. This crate provides webgl2 rendering support to Bevy.
Code Changes
Add a src/lib.rs
file that contains the following:
use bevy::prelude::*;
use wasm_bindgen::prelude::*;
mod game;
use game::GamePlugin;
mod main_menu;
use main_menu::MainMenuPlugin;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
enum AppState {
MainMenu,
InGame,
}
#[wasm_bindgen]
pub fn run() {
let mut app = App::build();
app.add_plugins(DefaultPlugins);
#[cfg(target_arch = "wasm32")]
app.add_plugin(bevy_webgl2::WebGL2Plugin);
app.insert_resource(WindowDescriptor {
title: "Platformer!".to_string(),
width: 640.0,
height: 400.0,
vsync: true,
..Default::default()
})
.insert_resource(ClearColor(Color::rgb(0.04, 0.04, 0.04)))
.add_state(AppState::MainMenu)
.add_plugin(MainMenuPlugin)
.add_plugin(GamePlugin)
.run();
}
This is the same code we had in our main.rs
, except that the main function was renamed to run
and adapted for the web.
Next step is to replace the content of src/main.rs
to:
use platformer::run;
fn main() {
run();
}
The code should now compile and run. To run locally on your machine, run:
cargo run
as usual, and to run for the web:
wasm-pack build --target web --release
npx serve .
And then visit http://localhost:3000
to confirm everything works fine.
Note that npx serve .
requires to have Node JS installed on your machine.
Possible Issues
You may encounter the following error:
the trait `__tracing_subscriber_Layer<Layered<EnvFilter, Registry>>` is not implemented for `WASMLayer`
To fix it, run the following command:
cargo update -p tracing-wasm --precise 0.2.0
The final code is available here. The most recent version of the game can be played here.
Top comments (1)
Why do i get the error:
in the dev console?
This line is the one thats getting it i think:
Any idea how to fix?