Expand description
A plugin for the Bevy Remote Protocol that exposes remote methods to Wasm/JavaScript.
§Setup
-
Add
bevy_remoteto your dependencies, andbevy_remote_wasmonly forwasmtargets.[dependencies] bevy = "0.18" bevy_remote = { version = "0.18", default-features = false } [target.'cfg(target_family = "wasm")'.dependencies] bevy_remote_wasm = "0.1"Don’t depend on
bevy/bevy_remote(bevy = { version = "0.18", features = ["bevy_remote"] }) because it enables the defaulthttptransport, which does not compile on Wasm target (until this fix is merged and released).This is why it is recommended to depend on the separate crate
bevy_remotewith no default features (sobevy_remote/httpis not enabled). -
Add
RemotePluginto yourApp, and addRemoteWasmPluginonly when compiling for Wasm.use bevy::prelude::*; use bevy_remote::RemotePlugin; let mut app = App::new(); app.add_plugins((DefaultPlugins, RemotePlugin::default())); #[cfg(target_family = "wasm")] app.add_plugins(bevy_remote_wasm::RemoteWasmPlugin); app.run(); -
Build for the
wasm32-unknown-unknowntarget, then generate the JS bindings withwasm-bindgendirectly (wasm-bindgen --target web --out-dir <output_dir> target/wasm32-unknown-unknown/debug/<crate_name>.wasm) or through a tool such aswasm-packor Trunk. -
In JavaScript, load the generated JS module, call
init(), then awaitgetBridge():import init, { getBridge } from "/example.js"; await init(); const bridge = await getBridge(); const response = await bridge.main["rpc.discover"](); console.log(response.info.version);The generated module path and
initfunction depend on your build tool, but the initialization order does not: initialize the Wasm module first, then await the bridge.getBridge()may be called as soon as the JS module loads, but it resolves only after Bevy publishes the bridge during app startup, which, depending on your setup, may take some time.The
wasm-bindgenoutput also includes TypeScript declarations for the root bridge (BrpBridge) and the default remote methods (BuiltInBrpBridge):import type { BuiltInBrpBridge } from "./example.js"; const bridge = await getBridge() as BuiltInBrpBridge; const response = await bridge.main['world.query']({ data: { option: 'all' } }); // Enjoy docs and autocompletion for built-in methods! -
Serve the generated HTML, JS, and
.wasmfiles together from a web server or bundler that supports Wasm imports.
§Wasm API
The plugin builds a bridge object with app-scoped method maps based on the methods registered with
RemotePlugin, more specifically through the RemoteMethods
resource. Each time this resource is updated, the bridge is re-published with the new methods. The getBridge()
function must be called again to get the updated bridge.
For Bevy 0.18, the bridge exposes only the main app. Method keys inside that namespace use the BRP method names
directly, so call them with bracket notation such as bridge.main["world.query"] and
bridge.main["world.list_components+watch"].
- Instant methods (run once, return a result):
// Call the instant method with params but without callback.
// Returns the result wrapped in a Promise.
const result = await bridge.main['world.query']({ data: { option: 'all' } });
console.log(result);
// Call the instant method with params and a callback that will be called with the result.
// Returns `undefined` wrapped in a Promise.
await bridge.main['world.query']({ data: { option: 'all' } }, (result) => console.log(result));- Watching methods (stream results):
// Call the watching method with params and a callback that will be called on each result.
// Returns a closer function wrapped in a Promise.
const close = await bridge.main['world.list_components+watch']({ entity: 123 }, (result) => console.log(result));
// Stop the stream.
close();Structs§
- Remote
Wasm Plugin - Add this plugin to your
Appto allow “remote” connections over Wasm to inspect and modify theWorld. It requires theRemotePlugin.