Running a Bevy game in SvelteKit
Recently, I started working on a new project using Bevy, a game engine written in Rust. I've been really enjoying it so far, and I'm excited to see where it goes.
I'd like to document the process of developing games, but I also wanted people to be able to play wasm builds of the games I make. I recently converted my entire website to SvelteKit, and I wanted to be able to import my games into it. I couldn't find any examples of using Bevy with SvelteKit specifically, so I thought I'd write one.
For this tutorial we will create a basic SvelteKit project, create a Rust workspace with a Bevy game, and configure SvelteKit to run the game.
Creating a basic SvelteKit project
We'll start with creating a basic SvelteKit project. If you already have a project you'd like to use, you can skip this
|
Next, we'll need to update the Vite configuration to be able to import wasm later. We're going to utilize the vite-plugin-wasm and vite-plugin-top-level-await plugins to do this.
|
Next, open vite.config.js
and update the plugins
section to look like this:
|
|
|
|
|
|
|
|
Before we can import wasm, we need...the wasm. So next, we'll initialize our Bevy game.
Adding a Bevy game
We'll start by creating a new Rust workspace. If you already have a workspace you'd like to use, you can skip this step.
Add a new file called Cargo.toml
to the root of your project with the following contents:
|
|
Next, we'll initialize our bevy game in the game
directory.
|
You'll need to also make sure you have the wasm target installed. You can do this by running:
|
Next, add bevy as a dependency in our game/Cargo.toml
file.
|
|
For this next part, any game that can compile to wasm should be fine.
One important change you'll want to make though is to update the WindowPlugin canvas property to use a custom id. This is how we're going to control the canvas element from SvelteKit.
Here's an example of customizing the WindowPlugin:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If you'd like a basic game to test with, you can use the following example from bevy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Next, we just need to build our game for the wasm target.
|
Now we should have a wasm file at target/wasm32-unknown-unknown/release/game.wasm
.
We're almost done! Next we're going to utilize wasm-bindgen to package our wasm file into a js/ts file that we can import into our SvelteKit project.
Generating lib files with wasm-bindgen
We're going to run wasm-bindgen and have it output our files to an assets
directory for Svelte to be able to import.
|
This will generate a game.js
and game_bg.wasm
file in the src/assets/game
directory.
Configuring SvelteKit to run the game
Now that we have importable js files, we can create our Svelte component to run the game. We'll create a component that renders a canvas element with a matching id to the one we specified in our game. And then we can customize this canvas component
Create a new file src/lib/components/Game.svelte
with the following contents:
|
|
|
|
|
|
|
|
|
|
Now we can import this component into our src/routes/index.svelte
file and render it.
|
|
|
|
|
Now we should be able to run our SvelteKit project and see our game running!
|