- QuestShockActivity now actually blocks the native engine from starting
when game data is missing, closing three gaps found via on-device
testing: super.onCreate() must run unconditionally first (Android
throws SuperNotCalledException otherwise); SDLActivity.mBrokenLibraries
is now set provisionally before the storage-permission check, since
onWindowFocusChanged() closing the permission dialog could otherwise
start the engine before the async onRequestPermissionsResult() callback
ran; and a new GameSurface (SDLSurface subclass) closes the actual gap
that let the init_popups NULL-deref crash through even with
mBrokenLibraries set - SDLSurface.surfaceChanged() starts the native
thread directly without ever checking that flag.
- Force Android to use SDL2's openslES audio backend instead of AAudio
(android/engine-patches/05-android-audio-driver.patch): AAudio only
allows one open playback device at a time, but the engine opens two
(cutscene audio via SDL_OpenAudioDevice, SFX/MIDI via Mix_OpenAudio),
hitting an assertion failure on real hardware.
- Add 16 KB ELF page-size alignment (-Wl,-z,max-page-size=16384) to every
Android shared library - the four prebuilts (SDL2, SDL2_mixer,
fluidsynth-lite, gl4es, in build-image/Dockerfile) and the engine's own
libmain.so (build.gradle) - matching Google's Play Store requirement
for Android 15+ and clearing Android Studio's compatibility warning.
- Add a stageEngine Gradle task that automatically re-stages the patched
engine/ copy and prebuilt libraries before any Android Studio build
(hooked into preBuild, with proper up-to-date checking), so source/
patch changes can't silently go stale in the build/android-engine
scratch copy - previously a manual, easy-to-forget step. Skips
automatically inside the build-image container so make apk/CI are
unaffected.