Files
gen1recomp/mobile/ANDROID.md
T
Marcus Pereira cd33858020 Respect the device rotation lock on Android
The manifest asks for android:screenOrientation="fullUser", but SDL
overrides it at window creation: SDLActivity.setOrientationBis, given a
resizable window and no SDL_HINT_ORIENTATIONS -- which is what conf.lua
produces on Android -- requests SCREEN_ORIENTATION_FULL_SENSOR. The
*_SENSOR constants follow the accelerometer even when the player has
turned auto-rotate off, so the game rotated anyway on a locked device.

Override setOrientationBis in GameActivity to remap SDL's request onto
the matching *_USER constant after super has run. The same orientations
stay allowed and SDL keeps deciding which ones those are; only the
tie-break changes, from the sensor to the system rotation setting.
2026-07-28 23:22:35 -03:00

3.6 KiB

Android (love-android 11.5a)

mobile/android/ is a vendored copy of love2d/love-android at tag 11.5a (matches conf.lua t.version = "11.5"), tracked directly in this repo, no git submodules involved. Nested love sources live at mobile/android/love/src/jni/love (also vendored). Build outputs (app/build/, love/build/, .gradle/, local.properties) stay gitignored.

Refreshing the vendored tree

To pick up a newer love-android release, replace the tree and re-vendor:

rm -rf mobile/android
git clone --depth 1 --branch <new-tag> --recurse-submodules --shallow-submodules \
  https://github.com/love2d/love-android.git mobile/android
rm -rf mobile/android/.git mobile/android/love/src/jni/love/.git \
       mobile/android/.gitmodules

scripts/build_android.sh re-applies project branding on every run (gradle.properties app id / name / portrait, plus permission trims), so a refresh is safe, just rebuild.

Build

# Build the APK
scripts/build_android.sh

# Build the APK, setting app.version_name/app.version_code to match a release
scripts/build_android.sh --version 0.2.5

# Zip game.love + branding only (no Android SDK required)
scripts/build_android.sh --package-only

Or via scripts/build.sh android [--version X.Y.Z].

The embedded game.love deliberately excludes data/generated/, assets/generated/, and any ROM. It contains the first-boot Lua importer and tools/rom_manifest.json.

ROM / mod / save import on Android uses love.system.pickFile([kind]) → GameActivity.showFilePicker (Storage Access Framework), which copies the chosen file under the app save directory as picked_rom.gb, picked_mod.zip, or picked_save.sav. RomImporter imports pending files from that folder on Choose / refocus; see docs/launcher.md. The APK payload itself remains data-free (no embedded ROM or generated cache).

SDK / NDK

love-android 11.5a expects:

  • JDK 17
  • Android SDK with API 34
  • NDK 25.2.9519653 (Apple Silicon host supported)

Set ANDROID_SDK_ROOT (or ANDROID_HOME), or let the script write local.properties when it finds ~/Library/Android/sdk.

Gradle flavor used: embedNoRecord (game fused into the APK, no microphone). Build task: assembleEmbedNoRecordDebug.

The APK lands under app/build/outputs/apk/embedNoRecord/debug/. scripts/build_android.sh also copies it to dist/android/debug/.

Payload path

app/src/embed/assets/game.love - zip of main.lua, conf.lua, src/, data/, assets/, and tools/rom_manifest.json. Generated game data, scripts, tests, and mobile build sources are excluded.

Branding (applied by the build script)

Setting Value
app.application_id com.theboisclub.pokemonred
app.name Pokemon Red
app.orientation fullUser. This is only the manifest default: SDL requests FULL_SENSOR at window creation (resizable window, no SDL_HINT_ORIENTATIONS), and GameActivity.setOrientationBis remaps that to FULL_USER so the device's rotation lock is honoured.
app.version_name / app.version_code set from --version X.Y.Z (code = major10000 + minor100 + patch); left as-is if --version is omitted
Permissions INTERNET / RECORD_AUDIO / WRITE_EXTERNAL_STORAGE stripped; VIBRATE + BLUETOOTH kept

Releases

.github/workflows/release.yml builds the APK with --version set to the release version and publishes it alongside the macOS/Windows/Linux builds as PokemonRed-<version>-android.apk.

Signing

Signed with the default Android keystore (no setup required).