MCPcopy Index your code
hub / github.com/bakcxoj/bevy_wasm

github.com/bakcxoj/bevy_wasm @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
145 symbols 190 edges 38 files 22 documented · 15%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Bevy WASM

Mod your Bevy games with WebAssembly!

CI MIT/Apache 2.0 Crates.io

Bevy

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.

Changelog

Protocol

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

[dependencies]
bevy_wasm_shared = "0.10"
serde = { version = "1.0", features = ["derive"] }
use bevy_wasm_shared::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.

[dependencies]
bevy = "0.10"
bevy_wasm = "0.10"
my_game_protocol = { git = "https://github.com/username/my_game_protocol" }
use bevy::prelude::*;
use bevy_wasm::prelude::*;
use my_game_protocol::{GameMessage, ModMessage, PROTOCOL_VERSION};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(WasmPlugin::<GameMessage, ModMessage>::new(PROTOCOL_VERSION))
        .add_startup_system(add_mods)
        .add_system(listen_for_mod_messages)
        .add_system(send_messages_to_mods)
        .run();
}

fn add_mods(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn(WasmMod {
        wasm: asset_server.load("some_mod.wasm"),
    });
    commands.spawn(WasmMod {
        wasm: asset_server.load("some_other_mod.wasm"),
    })
}

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

fn send_messages_to_mods(mut events: EventWriter<GameMessage>) {
    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.

[dependencies]
bevy_wasm_sys = "0.10"
my_game_protocol = { git = "https://github.com/username/my_game_protocol" }
use bevy_wasm_sys::prelude::*;
use my_game_protocol::{GameMessage, ModMessage, PROTOCOL_VERSION};

#[no_mangle]
pub unsafe extern "C" fn build_app() {
    App::new()
        .add_plugin(FFIPlugin::<GameMessage, ModMessage>::new(PROTOCOL_VERSION))
        .add_system(listen_for_game_messages)
        .add_system(send_messages_to_game)
        .run();
}

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

fn send_messages_to_game(mut events: EventWriter<ModMessage>) {
    events.send(ModMessage::Hello);
}

Sharing Resources

Protocol:

#[derive(Resource, Default, Serialize, Deserialize)]
pub struct MyResource {
    pub value: i32,
}

Game:

App::new()
    ...
    .add_resource(MyResource { value: 0 })
    .add_plugin(
        WasmPlugin::<GameMessage, ModMessage>::new(PROTOCOL_VERSION)
            .share_resource::<MyResource>()
    )
    .add_system(change_resource_value)
    ...

fn change_resource_value(mut resource: ResMut<MyResource>) {
    resource.value += 1;
}

Mod:

App::new()
    ...
    .add_plugin(FFIPlugin::<GameMessage, ModMessage>::new(PROTOCOL_VERSION))
    .add_startup_system(setup)
    .add_system(print_resource_value)
    ...

fn setup(mut extern_resource: ResMut<ExternResources>) {
    extern_resources.insert::<MyResource>();
}

fn print_resource_value(resource: ExternRes<MyResource>) {
    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)
Browser support
Extern Query
Synced time
Mod hotloading
Automatic component syncing

License

Bevy WASM is free, open source and permissively licensed! Except where noted (below and/or in individual files), all code in this repository is dual-licensed under either:

at your option. This means you can select the license you prefer! This dual-licensing approach is the de-facto standard in the Rust ecosystem and there are very good reasons to include both.

Your contributions

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Method 64
Function 47
Class 20
Interface 8
Enum 6

Languages

Rust100%

Modules by API surface

bevy_wasm_sys/src/time.rs36 symbols
bevy_wasm_sys/src/ecs/extern_res.rs20 symbols
bevy_wasm_sys/src/ffi_plugin.rs10 symbols
bevy_wasm/src/plugin.rs7 symbols
bevy_wasm/src/runtime/web/mod.rs6 symbols
bevy_wasm/src/runtime/native/mod.rs6 symbols
examples/cubes/mod_with_bevy/src/lib.rs5 symbols
bevy_wasm_shared/src/version.rs5 symbols
examples/simple/simple/src/main.rs4 symbols
examples/cubes/mod_without_bevy/src/lib.rs4 symbols
examples/cubes/cubes/src/main.rs4 symbols
bevy_wasm/src/wasm_asset.rs4 symbols

For agents

$ claude mcp add bevy_wasm \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page