4 Commits

Author SHA1 Message Date
ml 790b4ffd21 Add screenshots, a quick start and a trademark notice to the README
build / build (push) Successful in 3m8s
2026-09-25 20:25:17 +02:00
ml 135e474a14 Add v0.5.3 screenshots and a video; name captures by version.
build / build (push) Successful in 2m52s
2026-09-21 20:14:51 +02:00
ml 295f4869c1 Sign release APKs with a fixed key from CI secrets
build / build (push) Successful in 2m48s
2026-09-20 17:47:43 +02:00
ml f0a83df667 Replace the logo and icon with QuestShock artwork; add a GitHub release workflow
build / build (push) Successful in 2m14s
2026-09-20 17:23:55 +02:00
52 changed files with 328 additions and 16 deletions
+18
View File
@@ -69,7 +69,25 @@ jobs:
dist/shockolate-*-linux-*.tar.gz dist/shockolate-*-linux-*.tar.gz
dist/shockolate-*-windows-*.zip dist/shockolate-*-windows-*.zip
# The release key is stored base64-encoded in ANDROID_KEYSTORE_BASE64
# (see README section 4.3). Without it the APK is a debug build.
- name: Prepare release signing
env:
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
run: |
set -euo pipefail
if [ -z "$KEYSTORE_BASE64" ]; then
echo "No signing key: the APK will be a debug build"
exit 0
fi
echo "$KEYSTORE_BASE64" | base64 -d > "${RUNNER_TEMP:-/tmp}/questshock-release.jks"
echo "QUESTSHOCK_KEYSTORE=${RUNNER_TEMP:-/tmp}/questshock-release.jks" >> "$GITHUB_ENV"
- name: Build Quest APK - name: Build Quest APK
env:
QUESTSHOCK_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
QUESTSHOCK_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
QUESTSHOCK_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
# QUESTSHOCK_BUILD_IMAGE is already set (see Preflight above), so # QUESTSHOCK_BUILD_IMAGE is already set (see Preflight above), so
# this runs build-apk.sh directly instead of trying to docker-run # this runs build-apk.sh directly instead of trying to docker-run
# the image again - same reasoning as `make package` above. # the image again - same reasoning as `make package` above.
+145
View File
@@ -0,0 +1,145 @@
name: release
# GitHub's build. The Gitea build is .gitea/workflows/build.yml.
#
# Pushing a tag vX.Y.Z builds the Linux and Windows packages and the Quest APK
# inside the build-image and attaches them to a GitHub release. A manual run
# builds the same files and keeps them as a workflow artifact without
# releasing them.
#
# The build-image (build-image/Dockerfile) is published to GHCR, tagged with a
# hash of the files that define it, and only built when that tag does not
# exist yet.
on:
push:
tags:
- "v*"
workflow_dispatch:
permissions:
contents: read
jobs:
image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
name: ${{ steps.name.outputs.name }}
steps:
- uses: actions/checkout@v4
- name: Name the image after the files that define it
id: name
run: |
set -euo pipefail
hash="$(cat build-image/Dockerfile build-image/docker-entrypoint.sh build-image/build-engine.sh | sha256sum | cut -c1-16)"
echo "name=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/questshock-builder:${hash}" >> "$GITHUB_OUTPUT"
- name: Build and push the image if it does not exist yet
env:
IMAGE: ${{ steps.name.outputs.name }}
REGISTRY_USER: ${{ github.actor }}
REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
echo "$REGISTRY_PASSWORD" | docker login ghcr.io -u "$REGISTRY_USER" --password-stdin
if docker manifest inspect "$IMAGE" >/dev/null 2>&1; then
echo "$IMAGE already exists"
exit 0
fi
# The image is large and the runner's disk is small.
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
# The label links the package to this repository, so the build job
# can pull it with the workflow's token.
docker build -f build-image/Dockerfile \
--label "org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY}" \
-t "$IMAGE" .
docker push "$IMAGE"
build:
needs: image
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
defaults:
run:
shell: bash
# The job runs inside the build-image, so `make` compiles directly instead
# of starting the image itself (QUESTSHOCK_BUILD_IMAGE is set in it).
container:
image: ${{ needs.image.outputs.name }}
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
# The version comes from `git describe --tags`.
fetch-depth: 0
- name: Build the Linux and Windows packages
run: make package
# The release key is stored base64-encoded in ANDROID_KEYSTORE_BASE64; see
# README section 4.3. A tag build must be signed with it.
- name: Prepare release signing
env:
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
run: |
set -euo pipefail
if [ -z "$KEYSTORE_BASE64" ]; then
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
echo "::error::ANDROID_KEYSTORE_BASE64 is not set: a release APK must be signed"
exit 1
fi
echo "No signing key: the APK will be a debug build"
exit 0
fi
echo "$KEYSTORE_BASE64" | base64 -d > "${RUNNER_TEMP:-/tmp}/questshock-release.jks"
echo "QUESTSHOCK_KEYSTORE=${RUNNER_TEMP:-/tmp}/questshock-release.jks" >> "$GITHUB_ENV"
# Needs network access for Gradle's own dependency resolution.
- name: Build the Quest APK
env:
QUESTSHOCK_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
QUESTSHOCK_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
QUESTSHOCK_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
run: make apk
- uses: actions/upload-artifact@v4
with:
name: questshock
path: |
dist/shockolate-*-linux-*.tar.gz
dist/shockolate-*-windows-*.zip
dist/questshock-*-android-*.apk
release:
if: startsWith(github.ref, 'refs/tags/')
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
steps:
- uses: actions/download-artifact@v4
with:
name: questshock
path: dist
- name: Create the release, or update its files if it exists
run: |
set -euo pipefail
if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
gh release upload "$GITHUB_REF_NAME" dist/* --clobber
else
gh release create "$GITHUB_REF_NAME" dist/* \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--notes "Sideload the APK onto a Meta Quest (see README section 5.1). The game data is not included: you need your own copy of System Shock: Enhanced Edition."
fi
+4
View File
@@ -38,3 +38,7 @@
# Local registry credentials (see registry.env.example) # Local registry credentials (see registry.env.example)
/registry.env /registry.env
# Signing keys
*.jks
*.keystore
+19 -6
View File
@@ -34,7 +34,7 @@ These come from the maintainer. Follow them without being asked again.
`make apk` and `make android-studio` overwrite `android/engine.properties` `make apk` and `make android-studio` overwrite `android/engine.properties`
with container-only paths and break an open Android Studio project. What you with container-only paths and break an open Android Studio project. What you
can do is dry-run patches (section 6) and run static consistency checks can do is dry-run patches (section 6) and run static consistency checks
(section 12). Say plainly in your report that the change was not built or (section 13). Say plainly in your report that the change was not built or
tested. tested.
3. **`engine/` and `android/gl4es-src/` are never edited.** They are vendored 3. **`engine/` and `android/gl4es-src/` are never edited.** They are vendored
snapshots. Every change to them is a numbered patch under snapshots. Every change to them is a numbered patch under
@@ -74,7 +74,8 @@ These come from the maintainer. Follow them without being asked again.
| `android/app/build.gradle` | Gradle project; the `stageEngine` task stages the patched engine. | | `android/app/build.gradle` | Gradle project; the `stageEngine` task stages the patched engine. |
| `android/force-rebuild.sh` | Stops Gradle daemons and wipes staged/build output for a fully fresh native build. | | `android/force-rebuild.sh` | Stops Gradle daemons and wipes staged/build output for a fully fresh native build. |
| `build-image/` | Docker build environment (`Dockerfile`, `VERSION`, `prepare-android-project.sh`, `build-apk.sh`, engine build scripts). | | `build-image/` | Docker build environment (`Dockerfile`, `VERSION`, `prepare-android-project.sh`, `build-apk.sh`, engine build scripts). |
| `res/` | Bundled resources: `questshock.config.default.json`, `controller_profiles/` (JSON + PNG per controller), `assets/` (where the user's own game data goes, git-ignored), `run.sh`/`run.bat`. | | `res/` | Bundled resources: `questshock.config.default.json`, `controller_profiles/` (JSON + PNG per controller), `splash.png` (startup splash), `logo.png` (1024x1024 logo, master of the launcher icons in `android/app/src/main/res/mipmap-*/`), `logo_small.png` (the README header), `screenshots/` (headset captures and videos named `questshock_v<version>_<nnn>.<ext>`, numbered per version), `assets/` (where the user's own game data goes, git-ignored), `run.sh`/`run.bat`. |
| `.gitea/workflows/build.yml`, `.github/workflows/release.yml` | CI. Gitea is the primary repository and builds on every push; GitHub is a mirror whose workflow builds and publishes a release when a `vX.Y.Z` tag is pushed. Each platform has its own file. |
| `Makefile` | `engine`, `dist`, `package`, `apk`, `android-studio`, `clean`, ... (see README section 2). | | `Makefile` | `engine`, `dist`, `package`, `apk`, `android-studio`, `clean`, ... (see README section 2). |
| `README.md`, `CONFIG.md`, `NOTICE.txt` | User docs, config reference, license notice. | | `README.md`, `CONFIG.md`, `NOTICE.txt` | User docs, config reference, license notice. |
@@ -140,7 +141,7 @@ not print it or commit it.
`qs_config_frame_tick()`) is called from `xr_input.c`. `qs_config_frame_tick()`) is called from `xr_input.c`.
- JNI symbol names must match the Java `native` declarations exactly - JNI symbol names must match the Java `native` declarations exactly
(`Java_de_ladkau_questshock_<Class>_<method>`). A mismatch only fails at (`Java_de_ladkau_questshock_<Class>_<method>`). A mismatch only fails at
runtime, so check it (section 12). runtime, so check it (section 13).
### 4.5 Off-screen views (`OverlayPanel`, `MenuOverlay`, `KeyboardOverlay`) ### 4.5 Off-screen views (`OverlayPanel`, `MenuOverlay`, `KeyboardOverlay`)
@@ -336,7 +337,19 @@ or directory must also be declared as `inputs.file(...)`/`inputs.dir(...)` of
The proprietary game data (`res/data/`, `res/sound/`) is never bundled or The proprietary game data (`res/data/`, `res/sound/`) is never bundled or
committed. The app refuses to start the engine until it is present. committed. The app refuses to start the engine until it is present.
## 11. Code and documentation style ## 11. Signing
Distributed APKs are release builds signed with one fixed key, so users can
update in place. `build-image/build-apk.sh` reads the key from
`QUESTSHOCK_KEYSTORE`, `QUESTSHOCK_KEYSTORE_PASSWORD`, `QUESTSHOCK_KEY_ALIAS`
and `QUESTSHOCK_KEY_PASSWORD`; `android/app/build.gradle` applies it to the
`release` build type only when `QUESTSHOCK_KEYSTORE` is set. Both CI workflows
decode it from the `ANDROID_KEYSTORE_BASE64` secret. Without a key the build is
a debug APK (`...-debug.apk`), which is only for testing. Never commit a
keystore or a password, print them, or put them in a workflow file (README
section 4.3 lists the secrets).
## 12. Code and documentation style
- Match the surrounding code: naming, comment density, idiom. C is plain C with - Match the surrounding code: naming, comment density, idiom. C is plain C with
`static` helpers and `//` comments; Java targets Android API 34 and uses only the SDK plus `static` helpers and `//` comments; Java targets Android API 34 and uses only the SDK plus
@@ -352,7 +365,7 @@ committed. The app refuses to start the engine until it is present.
- English, French and German strings live in `Strings.java`; keep the three - English, French and German strings live in `Strings.java`; keep the three
entries of each key on the same `put(...)`. entries of each key on the same `put(...)`.
## 12. Verifying a change without building ## 13. Verifying a change without building
Because you may not build (rule 2), check statically and say so in the report: Because you may not build (rule 2), check statically and say so in the report:
@@ -374,7 +387,7 @@ Then report what was checked, what was not (build, on-device behaviour), and
any device check the maintainer should do (for example a new patch that may any device check the maintainer should do (for example a new patch that may
need `android/force-rebuild.sh`). need `android/force-rebuild.sh`).
## 13. Commit messages ## 14. Commit messages
Draft only (rule 1). Use a short imperative subject (about 70 characters), a Draft only (rule 1). Use a short imperative subject (about 70 characters), a
blank line, then a body that explains what the change does and why: the blank line, then a body that explains what the change does and why: the
+3
View File
@@ -8,6 +8,9 @@ and is not relicensed by this project's MIT license.
Game assets are not included - see res/GET_ASSETS.txt. Game assets are not included - see res/GET_ASSETS.txt.
System Shock is a trademark of its respective owners. This is an unofficial
fan project and is not affiliated with, endorsed by or supported by them.
The Android build additionally bundles: The Android build additionally bundles:
- GL4ES (https://github.com/ptitSeb/gl4es), vendored and patched (see - GL4ES (https://github.com/ptitSeb/gl4es), vendored and patched (see
+98 -5
View File
@@ -17,6 +17,45 @@ button, stick direction and game hotkey can be assigned to a game action.
Questshock runs entirely on the headset (tested on a Meta Quest 2) as a Questshock runs entirely on the headset (tested on a Meta Quest 2) as a
sideloaded Android app, and needs your own copy of the game data. sideloaded Android app, and needs your own copy of the game data.
> **Unofficial fan project.** Questshock is not affiliated with, endorsed by or
> supported by the rights holders of System Shock. It contains no game data: you
> need your own copy of System Shock: Enhanced Edition.
## Screenshots
<table>
<tr>
<td width="50%"><img src="res/screenshots/questshock_v0.5.3_001.jpg" alt="Exploring the station on the virtual screen"><br><sub>Exploring the station on the virtual screen</sub></td>
<td width="50%"><img src="res/screenshots/questshock_v0.5.3_003.jpg" alt="Reading an email - the laser pointer clicks like a mouse"><br><sub>Reading an email - the laser pointer clicks like a mouse</sub></td>
</tr>
<tr>
<td width="50%"><img src="res/screenshots/questshock_v0.5.3_005.jpg" alt="Cyberspace"><br><sub>Cyberspace</sub></td>
<td width="50%"><img src="res/screenshots/questshock_v0.5.3_006.jpg" alt="The game screen, the menu and the keyboard float independently"><br><sub>The game screen, the menu and the keyboard float independently</sub></td>
</tr>
<tr>
<td width="50%"><img src="res/screenshots/questshock_v0.5.3_007.jpg" alt="The VR menu"><br><sub>The VR menu</sub></td>
<td width="50%"><img src="res/screenshots/questshock_v0.5.3_008.jpg" alt="Assigning controller inputs to game actions"><br><sub>Assigning controller inputs to game actions</sub></td>
</tr>
</table>
[A short video](res/screenshots/questshock_v0.5.3_010.mp4) shows the game in use.
## Quick start
You need a Meta Quest (tested on a Quest 2) and your own copy of the game data.
1. Get **System Shock: Enhanced Edition** (for example from
[gog.com](https://www.gog.com/)); see "3. Game assets" below.
2. Download `questshock-<version>-android-arm64.apk` from the repository's
Releases page and sideload it onto the headset with
[SideQuest](https://sidequestvr.com/) or `adb install`.
3. Launch it once. It creates `/sdcard/QuestShock/`. Copy your game's `res/data/`
and `res/sound/` folders into `/sdcard/QuestShock/res/`.
4. Launch it again. The left controller's menu button opens the menu; the
default controls are in "5.1.1. Menu, controls and cheats" below.
Section "5.1. Installing and playing" has the details.
## 1. Design principles ## 1. Design principles
- **Standalone-headset-only.** The game must run entirely on the headset - **Standalone-headset-only.** The game must run entirely on the headset
@@ -46,7 +85,11 @@ sideloaded Android app, and needs your own copy of the game data.
(see [CONFIG.md](CONFIG.md)); `res/controller_profiles/` - the per-controller (see [CONFIG.md](CONFIG.md)); `res/controller_profiles/` - the per-controller
illustrations and labels shown in the Controller Options tab (see illustrations and labels shown in the Controller Options tab (see
[CONFIG.md](CONFIG.md)). Both are copied into the APK, as is [CONFIG.md](CONFIG.md)). Both are copied into the APK, as is
`res/splash.png`, the startup splash image. `res/splash.png`, the startup splash image. `res/logo.png` is the 1024x1024
logo, the master of the launcher icon
(`android/app/src/main/res/mipmap-*/ic_launcher.png` are scaled copies of it)
and the image to use for store listings; `res/logo_small.png` is the copy
shown at the top of this file.
- `Makefile` - targets: - `Makefile` - targets:
- `all` (default) - alias for `dist`. - `all` (default) - alias for `dist`.
- `build-image` - builds the Docker build-image (`./build-image.sh`). - `build-image` - builds the Docker build-image (`./build-image.sh`).
@@ -65,9 +108,11 @@ sideloaded Android app, and needs your own copy of the game data.
proprietary game assets (ships `res/GET_ASSETS.txt` in their place). proprietary game assets (ships `res/GET_ASSETS.txt` in their place).
See "4.1. Packaging a distributable build" below. See "4.1. Packaging a distributable build" below.
- `apk` - builds `dist/questshock-<version>-android-arm64.apk` for - `apk` - builds `dist/questshock-<version>-android-arm64.apk` for
Android-based OpenXR headsets. Unlike every other target, this needs Android-based OpenXR headsets (a debug build, `...-arm64-debug.apk`,
network access at build time (Gradle/AGP's own dependency when there is no signing key - see "4.3. Releases and signing" below).
resolution). See "5. Android / Quest build" below. Unlike every other target, this needs network access at build time
(Gradle/AGP's own dependency resolution). See "5. Android / Quest
build" below.
- `android-studio` - stages `engine/`/`android/gl4es-src/` (scratch, - `android-studio` - stages `engine/`/`android/gl4es-src/` (scratch,
patched copies) and the Android prebuilts with host-resolvable paths, patched copies) and the Android prebuilts with host-resolvable paths,
so Android Studio can compile and deploy `android/` natively instead so Android Studio can compile and deploy `android/` natively instead
@@ -211,6 +256,49 @@ package on every push, using the build-image as its container (so no
extra setup is needed in CI beyond the image itself), and publishes the extra setup is needed in CI beyond the image itself), and publishes the
resulting tarball to dl.ladkau.de. resulting tarball to dl.ladkau.de.
### 4.3. Releases and signing
The repository is developed on Gitea, and the GitHub repository is a mirror of
it. `.github/workflows/release.yml` is GitHub's own workflow (the Gitea build
is `.gitea/workflows/build.yml`):
- Pushing a tag `vX.Y.Z` builds the Linux and Windows packages and the Quest
APK inside the build-image and attaches them to a GitHub release with the
same name. A manual run ("Run workflow") builds the same files without
releasing them and keeps them as a downloadable workflow artifact.
- The build-image is pushed to GitHub's container registry (`ghcr.io`) when it
does not exist there yet. Its tag is a hash of `build-image/Dockerfile`,
`docker-entrypoint.sh` and `build-engine.sh`, so a change to any of them
builds a new image (`build-image/VERSION` is not used). The first run is slow
because it builds the image.
- The APK is signed with the release key described below.
**Signing.** Android only updates an installed app from an APK signed with the
same key, so every distributed APK is signed with one fixed key. `make apk`
(`build-image/build-apk.sh`) builds and signs the release APK when
`QUESTSHOCK_KEYSTORE` is set, together with `QUESTSHOCK_KEYSTORE_PASSWORD` and
optionally `QUESTSHOCK_KEY_ALIAS` (default `questshock`) and
`QUESTSHOCK_KEY_PASSWORD` (default: the keystore password). Without a keystore
it builds a debug APK, `questshock-<version>-android-arm64-debug.apk`, signed
with a per-machine debug key. That is what Android Studio's Run uses too; an
installed build has to be uninstalled before one signed with another key can be
installed.
Create the key once and keep the file and its password safe: without them,
users have to uninstall the app to get an update.
```sh
keytool -genkeypair -v -storetype PKCS12 -keystore questshock-release.jks \
-alias questshock -keyalg RSA -keysize 4096 -validity 10000
base64 -w0 questshock-release.jks # the value of ANDROID_KEYSTORE_BASE64
```
Both CI systems read the key from these secrets: `ANDROID_KEYSTORE_BASE64`,
`ANDROID_KEYSTORE_PASSWORD`, and optionally `ANDROID_KEY_ALIAS` and
`ANDROID_KEY_PASSWORD`. Without `ANDROID_KEYSTORE_BASE64`, the Gitea build
produces a debug APK and the GitHub build fails on a tag. `*.jks` and
`*.keystore` are git-ignored.
## 5. Android / Quest build ## 5. Android / Quest build
**Prerequisites:** **Prerequisites:**
@@ -225,7 +313,8 @@ resulting tarball to dl.ladkau.de.
apk` needs its own separate toolchain - see "5.2. Building natively in apk` needs its own separate toolchain - see "5.2. Building natively in
Android Studio" below. Android Studio" below.
`make apk` builds `dist/questshock-<version>-android-arm64.apk` - an `make apk` builds `dist/questshock-<version>-android-arm64.apk` (or
`...-arm64-debug.apk`, see "4.3. Releases and signing" above) - an
immersive OpenXR app (see `android/app/src/main/cpp/xr_session.c`) that immersive OpenXR app (see `android/app/src/main/cpp/xr_session.c`) that
can be sideloaded onto any Android-based VR headset with OpenXR support can be sideloaded onto any Android-based VR headset with OpenXR support
(Meta Quest, Pico, etc. - see "1. Design principles" above), not just one (Meta Quest, Pico, etc. - see "1. Design principles" above), not just one
@@ -965,6 +1054,10 @@ under the **GNU GPLv3** (see `engine/LICENSE`) - it is included unchanged
and is *not* relicensed by this project's MIT license. Any build or and is *not* relicensed by this project's MIT license. Any build or
distribution of the compiled engine must comply with the GPLv3. distribution of the compiled engine must comply with the GPLv3.
System Shock is a trademark of its respective owners. Questshock is an
unofficial fan project and is not affiliated with, endorsed by or supported by
them.
The game assets extracted into `res/assets/ss_ee/` are proprietary, The game assets extracted into `res/assets/ss_ee/` are proprietary,
copyrighted game data owned by their respective rightsholders - they are copyrighted game data owned by their respective rightsholders - they are
never committed to this repository (see `.gitignore`) and must be never committed to this repository (see `.gitignore`) and must be
+19
View File
@@ -212,9 +212,28 @@ android {
} }
} }
// The release key comes from the environment (build-image/build-apk.sh,
// CI secrets). Without it there is no release signing, and the release
// build type is left unsigned.
def releaseKeystore = System.getenv("QUESTSHOCK_KEYSTORE")
def releaseStorePassword = System.getenv("QUESTSHOCK_KEYSTORE_PASSWORD")
signingConfigs {
release {
if (releaseKeystore) {
storeFile file(releaseKeystore)
storePassword releaseStorePassword
keyAlias System.getenv("QUESTSHOCK_KEY_ALIAS") ?: "questshock"
keyPassword System.getenv("QUESTSHOCK_KEY_PASSWORD") ?: releaseStorePassword
}
}
}
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
if (releaseKeystore) {
signingConfig signingConfigs.release
}
} }
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 16 KiB

+22 -5
View File
@@ -24,16 +24,33 @@ VERSION="$("$REPO_ROOT/build-image/version.sh")"
VERSION_CODE="$(git -C "$REPO_ROOT" rev-list --count HEAD)" VERSION_CODE="$(git -C "$REPO_ROOT" rev-list --count HEAD)"
echo "Version: $VERSION (versionCode $VERSION_CODE)" echo "Version: $VERSION (versionCode $VERSION_CODE)"
echo "== Building the APK (gradlew assembleDebug) ==" # A release APK is built and signed when QUESTSHOCK_KEYSTORE is set (with
# QUESTSHOCK_KEYSTORE_PASSWORD, and optionally QUESTSHOCK_KEY_ALIAS,
# default "questshock", and QUESTSHOCK_KEY_PASSWORD, default the keystore
# password). Without it the APK is a debug build, signed with a per-machine
# debug key.
if [ -n "${QUESTSHOCK_KEYSTORE:-}" ]; then
[ -f "$QUESTSHOCK_KEYSTORE" ] || { echo "BUILD FAIL: QUESTSHOCK_KEYSTORE ($QUESTSHOCK_KEYSTORE) does not exist" >&2; exit 1; }
[ -n "${QUESTSHOCK_KEYSTORE_PASSWORD:-}" ] || { echo "BUILD FAIL: QUESTSHOCK_KEYSTORE_PASSWORD is not set" >&2; exit 1; }
GRADLE_TASK=assembleRelease
APK="$ANDROID_DIR/app/build/outputs/apk/release/app-release.apk"
PKG_SUFFIX=""
else
echo "== QUESTSHOCK_KEYSTORE is not set: building a debug APK, not for distribution =="
GRADLE_TASK=assembleDebug
APK="$ANDROID_DIR/app/build/outputs/apk/debug/app-debug.apk"
PKG_SUFFIX="-debug"
fi
echo "== Building the APK (gradlew $GRADLE_TASK) =="
cd "$ANDROID_DIR" cd "$ANDROID_DIR"
./gradlew --no-daemon assembleDebug \ ./gradlew --no-daemon "$GRADLE_TASK" \
"-PquestshockVersionName=$VERSION" "-PquestshockVersionCode=$VERSION_CODE" "-PquestshockVersionName=$VERSION" "-PquestshockVersionCode=$VERSION_CODE"
APK="$ANDROID_DIR/app/build/outputs/apk/debug/app-debug.apk" [ -f "$APK" ] || { echo "BUILD FAIL: $APK not found after $GRADLE_TASK" >&2; exit 1; }
[ -f "$APK" ] || { echo "BUILD FAIL: $APK not found after assembleDebug" >&2; exit 1; }
mkdir -p "$REPO_ROOT/dist" mkdir -p "$REPO_ROOT/dist"
PKG_NAME="questshock-$VERSION-android-arm64.apk" PKG_NAME="questshock-$VERSION-android-arm64$PKG_SUFFIX.apk"
cp "$APK" "$REPO_ROOT/dist/$PKG_NAME" cp "$APK" "$REPO_ROOT/dist/$PKG_NAME"
echo "== Done ==" echo "== Done =="
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 628 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Before

Width:  |  Height:  |  Size: 493 KiB

After

Width:  |  Height:  |  Size: 493 KiB

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 434 KiB

Before

Width:  |  Height:  |  Size: 343 KiB

After

Width:  |  Height:  |  Size: 343 KiB

Before

Width:  |  Height:  |  Size: 272 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Before

Width:  |  Height:  |  Size: 309 KiB

After

Width:  |  Height:  |  Size: 309 KiB

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 265 KiB

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 310 KiB

Before

Width:  |  Height:  |  Size: 297 KiB

After

Width:  |  Height:  |  Size: 297 KiB

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Before

Width:  |  Height:  |  Size: 402 KiB

After

Width:  |  Height:  |  Size: 402 KiB

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 157 KiB

Before

Width:  |  Height:  |  Size: 641 KiB

After

Width:  |  Height:  |  Size: 641 KiB

Before

Width:  |  Height:  |  Size: 575 KiB

After

Width:  |  Height:  |  Size: 575 KiB

Before

Width:  |  Height:  |  Size: 707 KiB

After

Width:  |  Height:  |  Size: 707 KiB

Before

Width:  |  Height:  |  Size: 382 KiB

After

Width:  |  Height:  |  Size: 382 KiB

Before

Width:  |  Height:  |  Size: 413 KiB

After

Width:  |  Height:  |  Size: 413 KiB

Before

Width:  |  Height:  |  Size: 368 KiB

After

Width:  |  Height:  |  Size: 368 KiB

Before

Width:  |  Height:  |  Size: 435 KiB

After

Width:  |  Height:  |  Size: 435 KiB

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 276 KiB

Before

Width:  |  Height:  |  Size: 209 KiB

After

Width:  |  Height:  |  Size: 209 KiB

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.