0

I am trying to run a game I built with Bevy and Rust in the browser. Bevy started supporting WebGL2 from version 0.11.0, and I am using this version. I have compiled my Rust code to WebAssembly using wasm-pack build --target web.

However, when I try to initialize the WebAssembly module in my HTML file, I get the following error:

WebAssembly.instantiate(): Import #0 module="__wbindgen_placeholder__" error: module is not an object or function

Here is the JavaScript code I am using to initialize the WebAssembly module:

    import init, { run } from './game.js';

async function main() {
    await init('./game.wasm');
    run();
}

main();

In main.rs I have my run function with the export defined like:

#[wasm_bindgen]
pub fn run() {
    App::new()
        .add_plugins(DefaultPlugins)
    //initialize more systems and resources 
}

I have verified my paths are correct, and I am serving the files using the Live Server extension in VSCode. I am using the latest version of chrome and rust on popOS.

I have also checked the Bevy documentation and examples, but I couldn't find any specific guidance on this issue.

Does anyone know what could be causing this error and how to fix it?

jjreedv
  • 71
  • 2
  • 7

1 Answers1

1

If you want to compile a bevy application to wasm using wasm-pack you need to do it a bit different than usual.

First of all there is no need to add the #[wasm_bindgen] attribute anywhere in your rust code (e.g. no need to explicetly depend on wasm-bindgen).

To build your project for the wasm32-unknown-unknown target, run:

cargo build --release --target wasm32-unknown-unknown

and after that create the JavaScript bindings using wasm-pack and the binary built in the previous step:

wasm-bindgen --out-dir out --target web target/wasm32-unknown-unknown/release/game.wasm

Lastly serve such an index.html with a http-server of your choice:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Bevy Game</title>
    <meta charset="UTF-8" />
    <style>
        body {
            background: linear-gradient(135deg,
                    white 0%,
                    white 49%,
                    black 49%,
                    black 51%,
                    white 51%,
                    white 100%);
            background-repeat: repeat;
            background-size: 20px 20px;
        }

        canvas {
            background-color: white;
        }
    </style>
</head>
<script type="module">
    import init from './out/game.wasm'
    init()
</script>

</html>

with the relevant part of course being:

<script type="module">
    import init from './out/game.wasm'
    init()
</script>

I have a full repository where this workflow is set up over here.

frankenapps
  • 5,800
  • 6
  • 28
  • 69