In this guide
Validate, cook, and package Linux bundles and Android APK/AAB releases.
Shipping & builds
Validate the exact target, cook deterministic content, and package a transactional artifact. Release signing values come only from environment or CI secret references.
Release metadata
Set build in demi.project.json:
"build": {
"application_id": "com.example.mygame",
"display_name": "My Game",
"executable_name": "my-game",
"version_name": "0.1.0",
"version_code": 1,
"icon": "asset://branding/icon",
"splash": "asset://branding/splash",
"window": { "width": 1280, "height": 720, "mode": "borderless" },
"android": {
"orientation": "landscape",
"permissions": ["android.permission.INTERNET"]
}
}
executable_namemust match^[a-z0-9][a-z0-9_-]*$— lowercase letters, digits, hyphens, or underscores, starting with a letter or digit.- Icons and splash screens: PNG, JPEG, WebP, or SVG (SVG rasterized host-side via
rsvg-convert). - Discovery skips dot-directories,
build,generated,node_modules, and__pycache__. - When you author
build.android.permissionsand the project uses networking, includeandroid.permission.INTERNET. Projects without an authoredbuildblock retain the Gradle default permission set, which includes it.
Validate the shipping target
demi validate games/my_game --platform linux
demi validate games/my_game --platform android
Platform capability errors have stable codes:
| Code | Cause |
|---|---|
PROJECT_BUILD_FEATURE_MEDIA_UNSUPPORTED | FFmpeg missing |
PROJECT_BUILD_FEATURE_NETWORK_UNSUPPORTED | ENet missing |
PROJECT_BUILD_FEATURE_SVG_UNSUPPORTED | Runtime SVG unavailable |
PROJECT_BUILD_PERMISSION_NETWORK_MISSING | An authored Android permission list omits INTERNET while reachable content uses networking |
BUILD_PACKAGE_CONTENT_UNEXPECTED | Package contains non-audited paths |
demi doctor adds DOCTOR_OPTIONAL_FEATURE_MISSING warnings. Do not silence platform capability diagnostics — Android lacks some optional desktop capabilities.
Cook
demi cook --platform linux
Output: generated/cooked/<platform> + cook.manifest.json with every included path and hash. Cooking is deterministic across machines with the same sources and toolchain inputs.
Linux bundle
demi build linux
Produces an executable + launcher, cooked content, freedesktop entry, icon, attributions, and build-report.json.
Runtime writable locations:
- Saves:
$XDG_DATA_HOME/<game>/(fallback$HOME/.local/share/<game>) - Caches:
$XDG_CACHE_HOME/<game>/(fallback$HOME/.cache/<game>)
Android APK / AAB
demi build apk
demi build apk --configuration release
demi build aab
Artifacts land in <project>/build/android/ with *.build-report.json.
Release signing is environment-only:
export DEMI_ANDROID_KEYSTORE=/secure/path/release.keystore
export DEMI_ANDROID_KEYSTORE_PASSWORD=...
export DEMI_ANDROID_KEY_ALIAS=...
export DEMI_ANDROID_KEY_PASSWORD=...
Signing values must never enter source, command output, reports, or packaged content. Use CI secret references in pipelines.
Run on a device without a full rebuild when nothing changed:
demi run android --serial <device>
Package content audit
Release packages may contain only audited cooked roots: assets/, certs/, packages/, scenes/, scripts/, plus demi.project.json, demi.packages.lock.json, and cook.manifest.json. Unexpected content fails with BUILD_PACKAGE_CONTENT_UNEXPECTED. Do not bypass the audit or copy arbitrary project directories into a release.
Transactional packaging
A failed or cancelled build leaves the previous artifact intact and never publishes a partial staging directory. Verify with build-report.json after every release build.
Saves and rollback
Save documents retain format_version. Register a Save.register_migration handler for each older released version of a slot that the current game must read. Incompatible data must report an error instead of being silently discarded. Save slots live in platform user-data outside the artifact, so replacing or rolling back a build does not replace the slots.
Keep the previous artifact for rollback. Transactional packaging leaves it intact when a build fails; reinstalling it restores the earlier executable and cooked content. If a newer game has already written an incompatible save format, the older game must reject that format explicitly or include a deliberate reverse migration. Signing keys and certificates never belong in cooked content.
Capability gates
demi capabilities export --output capabilities.json
demi capabilities check --baseline capabilities.json --format json
demi capabilities verify-gates
Use these to detect accidental capability regressions in CI. See Capabilities for the support matrix.