DEMIENGINEDOCUMENTATION Everything is free
Project & file formats · Start here

application_id, window, Android permissions, branding.

Build & platform settings

Build metadata is the block of the project file that describes the game as a product: what it is called on a desktop, which identity it installs under on a phone, how big its window opens, and which device features it may use. This page explains each setting, why it exists, and what a finished package contains.

What build metadata is for

Gameplay files describe a world. Build metadata describes the application around it. Two jobs depend on it:

  • Packaging — producing an installable desktop build or an Android APK needs a stable application identity, display strings, icons, and version numbers. Without them there is nothing to install under.
  • Presentation and policy — window size and mode control how the desktop game appears; Android orientation and permissions declare what the app may do on a device.

Everything lives under build in demi.project.json. See demi.project.json for the rest of the project file.

A complete build block

"build": {
  "application_id": "com.example.skyforge",
  "display_name": "Skyforge",
  "executable_name": "skyforge",
  "version_name": "0.1.0",
  "version_code": 1,
  "icon": "asset://branding/icon",
  "splash": "asset://branding/splash",
  "window": {
    "width": 1280,
    "height": 720,
    "mode": "windowed"
  },
  "android": {
    "orientation": "landscape",
    "permissions": ["android.permission.INTERNET"]
  }
}

Field by field:

FieldMeaning
application_idThe product's permanent identity in reverse-DNS form. Required before packaging.
display_nameName people see: window title, desktop entry, installed app label.
executable_nameFile name of the launched program (for example skyforge).
version_nameHuman-readable version, typically semantic (0.1.0).
version_codeInteger version that increases with every release. Stores use it to order updates.
iconApp icon source, as an asset:// URI.
splashStartup image, as an asset:// URI.
windowDesktop window size and mode (below).
androidAndroid orientation and permissions (below).

application_id rules

The application ID is the one field that must never change after you ship: it is how operating systems recognize "this is the same app" across updates and how stores track installs and purchases.

  • Reverse-DNS form. At least two dot-separated segments, owned-looking and stable: com.example.skyforge, io.studio.mygame. Segments are lowercase letters, digits, and underscores; each segment starts with a letter.
  • Required for packaging. A missing or malformed application_id fails the packaging step.
  • Unique. Two different products must not share an ID — the device treats them as one app and will overwrite each other.
  • Not the display name. display_name is cosmetic and can change any time; application_id is identity and cannot.

Example for the Skyforge sample in games/my_game: application_id is com.example.skyforge, while display_name is simply Skyforge.

Names and versions

"display_name": "Skyforge",
"executable_name": "skyforge",
"version_name": "0.1.0",
"version_code": 1
  • display_name — what users read. May contain spaces and capitalization.
  • executable_name — what the shell runs. Lowercase letters, digits, underscores, and dashes only, starting with a letter or digit: ^[a-z0-9][a-z0-9_-]*$. This is the name of the binary in a desktop package.
  • version_name — the version you talk about in release notes.
  • version_code — the version machines compare. Bump it by at least one for every published build, even for a hotfix; a store will refuse an update whose code is not higher than the installed one.

Icon and splash

"icon": "asset://branding/icon",
"splash": "asset://branding/splash"
  • Both values are asset:// URIs pointing at manifests of type Icon2D or an image type. See Asset manifests.
  • Source images may be PNG, JPEG, WebP, or SVG. SVG is a good icon source because it scales to every required size cleanly.
  • icon is shown as the desktop shortcut / installed app icon. Provide a square image; the platform crops and pads it into its own icon shapes.
  • splash is shown while the game starts, especially on Android. Use a simple image that tolerates wide and tall crops.

Window modes

"window": {
  "width": 1280,
  "height": 720,
  "mode": "windowed"
}
FieldMeaning
width / heightInitial window size in screen pixels for desktop platforms.
modeOne of windowed (a normal titled window), borderless (fills the screen without a title bar, easy to alt-tab), fullscreen (exclusive full screen).

Choose windowed while developing — it is the easiest to debug. borderless is the usual shipping default on desktop because it behaves well with multi-monitor setups. fullscreen can give the display more control but is less forgiving when players alt-tab.

Android orientation and permissions

"android": {
  "orientation": "landscape",
  "permissions": ["android.permission.INTERNET"]
}
  • orientation — one of unspecified, portrait, landscape, portrait_sensor, or landscape_sensor. A fixed value locks the activity to that rotation so the HUD and camera never have to cope with an unexpected aspect; the *_sensor values allow both directions of that axis. Pick the orientation your game is designed for.
  • permissions — the Android permission strings this build declares, each written in the platform's dotted form, for example android.permission.INTERNET.

Why android.permission.INTERNET is explicit. On Android, network access is not granted by default. A game that never lists this permission cannot open sockets at all — no multiplayer, no asset fetch, no package store. Declaring it is a deliberate promise to the player: "this app uses the network." Declare only what you use; every extra permission is a question a careful player will ask.

Multiplayer titles need this permission. Single-player Skyforge can ship with an empty list. Capability notes per platform: Platform capabilities.

What lands in a package

When you package a build, the produced artifact is a self-contained game. It contains:

  • The executable named by executable_name.
  • The cooked game data: cooked scenes, prefabs, HUD documents, scripts, and imported assets from the audited content roots.
  • Branding: the icon and splash derived from the declared assets.
  • Platform metadata: application ID, display name, versions, orientation, and the exact permission list.

What does not land in a package:

  • Authoring-only files and editor state.
  • Anything outside the audited content roots — packaging is a root audit, not reachability pruning. Content outside those roots fails with BUILD_PACKAGE_CONTENT_UNEXPECTED, while unreferenced files inside an audited root still ship.
  • Player saves. Saves are written at run time to the platform's user-data directory as *.save.json, never into the game install or the project tree. See Game data & saves.

Packaging is transactional: if a build fails or you cancel it, the previous artifact stays intact and no partial output is published.

Validating before you package

Always validate the exact target first. Android accepts less than desktop, and the validator will say so instead of failing at install time:

demi validate games/my_game
demi validate games/my_game --platform android

The first command checks the project and all reachable sources for desktop; the second checks a shipping Android target and surfaces platform capability gaps. Fix every reported error, then package. Shipping workflow details: Shipping.