Android as a target platform #21

Closed
opened 2026-09-13 17:04:24 +00:00 by icub3d · 0 comments
Owner

Make Android a first-class target: the game must run on a tablet, not merely compile
for one.

A spike proved this is viable before any art exists to waste. The crate cross-compiles
to aarch64-linux-android in under two minutes, first try, with no dependency patched
and no feature disabled. On a Pixel Tablet (Android 17, Mali-G710, 2560x1600) the
mission view renders over Vulkan in 546 ms, RON definitions load from the APK, and
tapping a menu button transitions state.

Scope

  • src/lib.rs holds the app assembly behind #[bevy_main]; src/main.rs becomes a
    one-line caller. Android dlopens a shared object and calls android_main — it never
    runs a main — and #[bevy_main] can only generate that entry point where the crate
    builds as a cdylib.
  • Cargo.toml gains crate-type = ["lib", "cdylib"], the android-native-activity
    feature under cfg(target_os = "android"), and strip = "symbols" on release (worth
    60 MB of the shared object).
  • android/AndroidManifest.xml and android/build.sh — cross-compile with cargo-ndk,
    aapt2 link, add the library, align, sign. No Gradle: NativeActivity needs no Java.
  • ADRs 0002 (target Android),
    0003 (touch-first input), and
    0004 (render budget,
    Proposed).
  • docs/ROADMAP.md and CLAUDE.md updated to record the platform and how to build for
    it.

Not in scope

The spike surfaced problems that are their own issues rather than this one: the blank
screen on resume, system insets, forced portrait, the missing font glyphs, touch camera
gestures, the movement-preview rework, and the render-resolution measurement that ADR
0004 is waiting on.

Moving from NativeActivity to GameActivity is also deferred — it needs the
androidx.games AAR and with it Gradle and the Android Gradle Plugin's dependency tree,
which is a build-system decision to make deliberately.

Done when

android/build.sh --install produces a signed APK, installs it, and the mission view
runs on the tablet; desktop build, test, clippy, and fmt are unaffected.

Make Android a first-class target: the game must *run* on a tablet, not merely compile for one. A spike proved this is viable before any art exists to waste. The crate cross-compiles to `aarch64-linux-android` in under two minutes, first try, with no dependency patched and no feature disabled. On a Pixel Tablet (Android 17, Mali-G710, 2560x1600) the mission view renders over Vulkan in 546 ms, RON definitions load from the APK, and tapping a menu button transitions state. ## Scope - `src/lib.rs` holds the app assembly behind `#[bevy_main]`; `src/main.rs` becomes a one-line caller. Android dlopens a shared object and calls `android_main` — it never runs a `main` — and `#[bevy_main]` can only generate that entry point where the crate builds as a `cdylib`. - `Cargo.toml` gains `crate-type = ["lib", "cdylib"]`, the `android-native-activity` feature under `cfg(target_os = "android")`, and `strip = "symbols"` on release (worth 60 MB of the shared object). - `android/AndroidManifest.xml` and `android/build.sh` — cross-compile with `cargo-ndk`, `aapt2 link`, add the library, align, sign. No Gradle: `NativeActivity` needs no Java. - ADRs [0002](../src/branch/main/docs/adr/0002-target-android.md) (target Android), [0003](../src/branch/main/docs/adr/0003-touch-first-input.md) (touch-first input), and [0004](../src/branch/main/docs/adr/0004-mobile-render-budget.md) (render budget, Proposed). - `docs/ROADMAP.md` and `CLAUDE.md` updated to record the platform and how to build for it. ## Not in scope The spike surfaced problems that are their own issues rather than this one: the blank screen on resume, system insets, forced portrait, the missing font glyphs, touch camera gestures, the movement-preview rework, and the render-resolution measurement that ADR 0004 is waiting on. Moving from `NativeActivity` to GameActivity is also deferred — it needs the `androidx.games` AAR and with it Gradle and the Android Gradle Plugin's dependency tree, which is a build-system decision to make deliberately. ## Done when `android/build.sh --install` produces a signed APK, installs it, and the mission view runs on the tablet; desktop `build`, `test`, `clippy`, and `fmt` are unaffected.
icub3d referenced this issue from a commit 2026-09-13 17:05:38 +00:00
Sign in to join this conversation.
No description provided.