Bevy WASM

Mod your Bevy games with WebAssembly!

| | | | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | | bevy_wasm | | For games | | bevy_wasm_sys | | For mods | | bevy_wasm_shared | | For protocols |

See examples/cubes for a comprehensive example of how to use this.

Protocol

Our protocol crate defines the two message types for communicating between the game and mods.

toml [dependencies] bevy_wasm_shared = "0.9" serde = { version = "1.0", features = ["derive"] }

```rust use bevywasmshared::prelude::*; use serde::{Deserialize, Serialize};

/// The version of the protocol. Automatically set from the CARGO_PKG_XXX environment variables. pub const PROTOCOL_VERSION: Version = version!();

/// A message to be sent Mod -> Game.

[derive(Debug, Clone, Serialize, Deserialize)]

pub enum ModMessage { Hello, }

/// A message to be sent Game -> Mod.

[derive(Debug, Clone, Serialize, Deserialize)]

pub enum GameMessage { HiThere, } ```

Game

Our game will import WasmPlugin from bevy_wasm, and use it to automatically send and receive messages with the mods.

toml [dependencies] bevy = "0.9" bevy_wasm = "0.9" my_game_protocol = { git = "https://github.com/username/my_game_protocol" }

```rust use bevy::prelude::; use bevy_wasm::prelude::; use mygameprotocol::{GameMessage, ModMessage, PROTOCOL_VERSION};

fn main() { App::new() .addplugins(DefaultPlugins) .addplugin(WasmPlugin::::new(PROTOCOLVERSION)) .addstartupsystem(addmods) .addsystem(listenformodmessages) .addsystem(sendmessagestomods) .run(); }

fn addmods(mut commands: Commands, wasmengine: Res) { commands.spawn(WasmMod::new(&wasmengine, includebytes!("somemod.wasm")).unwrap()); commands.spawn(WasmMod::new(&wasmengine, includebytes!("someother_mod.wasm")).unwrap()); }

fn listenformod_messages(mut events: EventReader) { for event in events.iter() { match event { ModMessage::Hello => { println!("The mod said hello!"); } } } }

fn sendmessagesto_mods(mut events: EventWriter) { events.send(GameMessage::HiThere); } ```

Mod

Our mod will import FFIPlugin from bevy_wasm_sys, and use it to automatically send and receive messages with the game.

toml [dependencies] bevy_wasm_sys = "0.9" my_game_protocol = { git = "https://github.com/username/my_game_protocol" }

```rust use bevywasmsys::prelude::*; use mygameprotocol::{GameMessage, ModMessage, PROTOCOL_VERSION};

[no_mangle]

pub unsafe extern "C" fn buildapp() { App::new() .addplugin(FFIPlugin::::new(PROTOCOLVERSION)) .addsystem(listenforgamemessages) .addsystem(sendmessagesto_game) .run(); }

fn listenforgame_messages(mut events: EventReader) { for event in events.iter() { match event { GameMessage::HiThere => { println!("The game said hi there!"); } } } }

fn sendmessagesto_game(mut events: EventWriter) { events.send(ModMessage::Hello); } ```

Sharing Resources

Protocol:

```rust

[derive(Resource, Serialize, Deserialize)]

pub struct MyResource { pub value: i32, } ```

Game:

```rust App::new() ... .addresource(MyResource { value: 0 }) .addplugin( WasmPlugin::::new(PROTOCOLVERSION) .shareresource::() ) .addsystem(changeresource_value) ...

fn changeresourcevalue(mut resource: ResMut) { resource.value += 1; } ```

Mod:

```rust App::new() ... .addplugin(FFIPlugin::::new(PROTOCOLVERSION)) .addstartupsystem(setup) .addsystem(printresource_value) ...

fn setup(mut externresource: ResMut) { externresources.insert::(); }

fn printresourcevalue(resource: ExternRes) { println!("MyResource value: {}", resource.value); } ```

See examples/shared_resources for a full example.

Roadmap

| | | | --- | ------------------------------------------------ | | ✅ | wasmtime runtime in games | | ✅ | Send messages from mods to game | | ✅ | Send messages from game to mods | | ✅ | Multi-mod support | | ✅ | Time keeping | | ✅ | Protocol version checking | | ✅ | Extern Resource | | ✅ | Startup system mod loading | | ✅ | Direct update control | | ✅ | Mod unloading | | ✅ | Mod discrimination (events aren't broadcast all) | | ⬜ | Mutable Extern Resource | | ⬜ | Extern Query | | ⬜ | Custom FFI | | ⬜ | Synced time | | ⬜ | Mod hotloading | | ⬜ | Automatic component syncing | | ⬜ | Browser support |