Bevy 0.15 and Android
- This post is a followup to the guide for Bevy 0.13, where a lot has changed.
- These steps were done on an Apple M1 (2021) running Sequoia 15.3, and I deployed to a Pixel 9 phone.
Quickstart
Grab the following script and run it to create the necessary directory structure.
# Save the script above as setup.sh and then run it:
chmod +x setup.sh
./setup.sh
# Then load your project in android studio, and click: Run 'app'
When you run with Android Studio, you’ll be able to interact with your device in the app (under Running Devices), or on your phone directly.
If you choose not to use the script, the manual steps are under Android Structure.
Tools
- cargo-ndk (build)
- Android Studio (deploy)
- Android phone connected via USB (pixel 9)
Starting Project Structure
We’ll start with a generic bevy app.
cargo new bevy_breakout_15
cd bevy_breakout_15
cargo add bevy@0.15.2
mkdir assets
touch src/lib.rs
# For later:
brew install gradle
cargo install --locked cargo-ndk
Your project structure should look like this:
bevy_breakout_15
assets/
src/
lib.rs
main.rs
Cargo.toml
Cargo.toml
name = "bevy_breakout_15"
version = "0.1.0"
edition = "2021"
[dependencies]
bevy = "0.15.2"
main.rs
fn main() {
bevy_breakout_15::run_game();
}
lib.rs
Find the full lib.rs that I used for the Breakout game here.
use bevy::prelude::*;
// your dependencies
// ...
#[bevy_main]
fn main() {
run_game();
}
pub fn run_game() {
App::new()
.add_plugins(DefaultPlugins)
// your code
// ...
.run();
}
Android Structure
If you chose not to use the script, here are the manual steps.
Here, we’ll copy the necessary files from the bevy project, then modify them to suit our project (bevy_breakout_15).
Consider android_example your project root. So the files in here should be at the same level as your Cargo.toml and src/.
For every file inside: we want to copy them to our own project and modify the contents so example or android_example is replaced by our project name. My project is called bevy_breakout_15 so I’m going to replace all instances with that.
Copy exactly
- gradle.properties
- build.gradle: At the root of android_example
- gradle/libs.versions.toml
- app/CMakeLists.txt
- app/src/main/cpp/dummy.cpp
Copy and modify
- settings.gradle: change root.Project.name to bevy_breakout_15
- app/build.gradle: change the two instances of
org.bevyengine.example
fororg.bevyengine.bevy_breakout_15
, then change the paths onassets.srcDirs
andres.srcDirs
to just point one directory up (../assets) - app/src/main/java/org/bevyengine/example/MainActivity.java: change the page to org/bevyengine/bevy_breakout_15, and edit MainActivity.java changing
package org.bevyengine.example;
andSystem.loadLibrary("bevy_mobile_example");
topackage org.bevyengine.bevy_breakout_15;
andSystem.loadLibrary("bevy_breakout_15");
- app/src/main/AndroidManifest.xml: change
Bevy Example
tobevy_breakout_15
, andbevy_mobile_example
tobevy_breakout_15
Build for Android
- Make sure gradle is installed:
brew install gradle
- Generate gradle/wrapper, gradlew, and gradle.bat with:
gradle wrapper
cargo ndk -t arm64-v8a -o app/src/main/jniLibs build --package bevy_breakout_15
Final Project structure
bevy_breakout_15
app/
src/
main/
cpp/
java/
org/
bevyengine/
bevy_breakout_15/
MainActivity.java
jniLibs/
arm64-v8a/
libbevy_breakout_15.so
AndroidManifest.xml
build.gradle
CMakeLists.txt
assets/
android-res/
mipmap-mdpi/
ic_launcher.png
sounds/
breakout_collision.ogg
src/
lib.rs
main.rs
Cargo.toml
Cargo.toml
[package]
name = "bevy_breakout_15"
version = "0.1.0"
edition = "2021"
[dependencies]
bevy = "0.15.2"
[lib]
name = "bevy_breakout_15"
path = "src/lib.rs"
crate-type = [
"staticlib",
"cdylib", # needed for Android
"rlib", # rlib needed for running locally
]
[[bin]]
name = "bevy_breakout_15"
path = "src/main.rs"
Rebuild
Anytime you want to re-build for android, make sure to run: cargo ndk -t arm64-v8a -o app/src/main/jniLibs build --package bevy_breakout_15
, then click Run in Android Studio.
Resources
These resources made this post possible.