Skip to content

wasvy-org/wasvy

Repository files navigation

@wasvy logo

Wasvy - WASI Integration for Bevy (Just hatched! 🪺)

License Crates.io Downloads Docs Rust Version CI Discord

🪺 Just hatched: This project in in the process of stabilization. Some features are still missing and breaking API changes are likely to happen as we approach a 1.0 release. Use at your own risk!

🎯 Community Feedback: Your ideas, suggestions, and contributions are highly valued! Come and talk with us in the Bevy Discord. Report bugs and discuss new features on Github. Together, we can shape this into something great!

💡 TIP: Check out the justfile for useful commands and as a reference for common operations in the project.

Overview

Wasvy is an experimental Bevy modding engine, enabling the execution of WebAssembly (WASM) binaries within Bevy applications. It's powered by WebAssembly System Interface (WASI), enabling full access to the Bevy ECS, network, filesystem, system clock and more!

Features

  • 🪶 Easy integration with your game (see the example below)
  • 🔥 Hot reloading
  • 🛠️ Devtools (soon) via wasvy-cli
  • 🧩 WASI support powered by wasmtime

Vision

The ultimate goal of Wasvy is to create a vibrant ecosystem where:

  • Game developers can easily make their games moddable with just a few lines of code
  • The developer experience is fantastic (Hot reloading, live debugging tools, etc)
  • Modders can write mods in their language of choice (Rust, Python, etc.)
  • Performance is close to native
  • Mods are sandboxed and safe to run
  • The ecosystem is vibrant with shared components and tools

Installation

Run the following command in your project directory:

cargo add wasvy

Quick Start

use bevy::prelude::*;
use bevy::{DefaultPlugins, app::App};

// Get started by importing the prelude
use wasvy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        // Adding the [`ModloaderPlugin`] is all you need 😉
        .add_plugins(ModloaderPlugin::default())
        .add_systems(Startup, startup)
        .run();
}

/// Access the modloader's api through the Mods interface 🪄
fn startup(mut mods: Mods) {
    // Load one (or several) mods at once from the asset directory!
    mods.load("mods/my-mod.wasm");
}

Creating Mods

Mods are WebAssembly binaries coded in any language of choice. We're working on a way to streamline mod creation with wasvy-cli, but until that hatches, you can reference the examples in the repo.

To create a WASM component that works with Wasvy, you'll need to use the WebAssembly Component Model and define your interfaces using WIT (WebAssembly Interface Types). Here's how to get started with a new mod written in rust:

Prerequisites

  1. Add the wasm32-wasip2 target for rust
rustup target add wasm32-wasip2
  1. Install wkg (WebAssembly Kit Generator from wasm-pkg-tools):
cargo install wkg

And then configure wkg:

wkg config --default-registry wa.dev

This will make wkg use wa.dev as the default registry, which is where the latest version of wasvy:ecs is hosted.

Creating a New WASM Mod

  1. Create a new crate:
cargo new my-mod --lib
cd my-mod
  1. Update your cargo.toml:
[package]
name = "my-mod"
version = "0.1.0"
edition = "2024"

[dependencies]
# Hassle-less codegen for wit
wit-bindgen = "0.46"

# Wasvy uses json for serializing components. We use serde instead
# of bevy_reflect since at the moment bevy-reflect bloats the wasm binary considerably
serde = "1.0"
serde_json = "1.0"

# Import any bevy-sub crates for any components you will be using
# Note: enable the serialize feature to allow using serde
bevy_transform = { version = "0.17.2", features = ["serialize"], default-features = false }
bevy_math = { version = "0.17.2", features = ["serialize"], default-features = false }

[lib]
crate-type = ["cdylib"] # necessary for wasm
  1. Define your WIT interface in wit/world.wit. Here's a basic example:
package component:my-mod;

/// An example world for the component to target.
world example {
    /// This is the wit definition for wasvy's ecs access interface
    use wasvy:ecs/app.commands;

    /// An example system with a Commands system params
    export my-system: func(commands: commands);

    /// This is important.
    /// This makes it so the WASM module must implement the guest required functions by the Bevy host.
    include wasvy:ecs/guest;
}
  1. Fetch the Wasvy WIT files from the registry:
wkg wit fetch

This will automatically fetch the latest version of wasvy:ecs from wa.dev and add it to your wit folder. You can also copy them directly from the source.

  1. Modify my-mod/src/lib.rs as shown:
wit_bindgen::generate!({
    path: ["./wit"],
    world: "component:my-mod/example",
    with: {
       "wasvy:ecs/app": generate,
    }
});
use wasvy::ecs::app::{App, Commands, Schedule, System};

struct MyMod;

impl Guest for MyMod {
    fn setup() {
        // This must match the system we have defined in world.wit
        // If you want more systems, just define more in wit
        let system = System::new("my-system");
        system.add_commands();

        // Register the system, similarly as you would in a Bevy App
        let app = App::new();
        app.add_systems(&Schedule::ModStartup, vec![system]);
    }

    fn my_system(commands: Commands) {
        println!("Hello from my mod!");

        commands.spawn(&[
            ("example::Component".to_string(), "{}".to_string())
        ]);
    }
}

export!(MyMod);
  1. Build your mod:
cargo build --target wasm32-wasip2 --release

The resulting .wasm file will be in target/wasm32-wasip2/release/my-mod.wasm.

Hint: The binary must be in your game's assets library for it to be visible to Bevy. By default this is assets in the same directory as src. Then, make sure to load it via Mods::load as shown above (e.g. mods.load("mods/my-mod.wasm")).

Tips

  • You can enable hot reloading for assets (including wasm files) simply by enabling Bevy's file_watcher feature. Try running your game with the command cargo run --features bevy/file_watcher
  • The WIT registry at WebAssembly Components Registry contains many useful interfaces

Examples

Check out the examples directory for more detailed usage:

Contributing

Contributions come in many forms, and we welcome all kinds of help! Here's how you can contribute:

Code Contributions

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Non-Code Contributions

We're actively looking for:

  • Feature suggestions and ideas
  • Use case examples
  • Documentation improvements
  • Bug reports
  • Design discussions
  • Feedback on the API
  • Modding workflow suggestions

You don't need to write code to help out! If you have an idea or suggestion, please:

  1. Open an issue to discuss it
  2. Share your thoughts in the discussions
  3. Create a feature request

Please make sure to:

  • Follow Rust coding standards (for code contributions)
  • Add tests for new features (Not required for now, but will be appreciated)
  • Update documentation as needed
  • Keep the alpha status in mind when proposing changes

Roadmap

Phase 1: Core Integration (Current)

Phase 2: Enhanced Features

  • Hot reloading wasm files
  • Seamless dev experience building mods (See wasvy-cli)
  • Mod permissions
  • Improved rust modding experience (See wasvy-rust)
  • Improved python modding experience
  • Add more languages + examples
  • Test suite
  • Cross-component communication
  • Performance optimizations

Phase 3: Production Ready (1.0!)

  • Comprehensive documentation
  • Benchmarking suite
  • Stable API

Resources

License

This project is dual-licensed under either:

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.

Acknowledgments

About

Bevy modding engine powered by WASI

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Languages