DEMIENGINEDOCUMENTATION Everything is free

build linux output and runtime save locations.

Linux bundles

A Linux bundle is a shippable desktop package: a game executable players can double-click, with cooked content, a desktop menu entry, an icon, and a report of exactly what was built. Bundling exists so "works in the editor" becomes "runs on a player's machine" as one audited, reproducible artifact. This page covers validation and capability codes for Linux, cooking, building, and where the running game writes data. Examples use "Skyforge" at games/my_game.

Validate the Linux target first

Validation checks the project and everything it reaches against one platform's rules. Ask for Linux explicitly when you are about to ship a desktop build:

demi validate games/my_game --platform linux
  • validate [path] — validates the project and all reachable source.
  • --platform linux — applies Linux capability and content checks in addition to document shape checks.
  • Returns 0 when everything is valid, 1 when any validation error was reported.

Problems come back as stable capability error codes so build logs and continuous integration can classify them without parsing prose:

CodeMeaning
PROJECT_BUILD_FEATURE_MEDIA_UNSUPPORTEDThe project needs media support (FFmpeg) that this build of the engine was compiled without.
PROJECT_BUILD_FEATURE_NETWORK_UNSUPPORTEDThe project needs networking (ENet) that this build of the engine was compiled without.
PROJECT_BUILD_FEATURE_SVG_UNSUPPORTEDThe project needs SVG support that this build of the engine was compiled without.
PROJECT_BUILD_PERMISSION_NETWORK_MISSINGA platform permission required by the project is not declared (Android INTERNET is the common case).
BUILD_PACKAGE_CONTENT_UNEXPECTEDPackage content outside the audited roots was found and rejected.

Environment checks add one more code, DOCTOR_OPTIONAL_FEATURE_MISSING, for optional features that do not block a run:

demi doctor --format json
  • doctor — inspects the environment and the project and reports what is ready and what is missing.
  • --format json — emits the report as JSON for editors and pipelines.

Validate before packaging. A build never papers over a capability error; it fails with the code so you can fix the project or the toolchain deliberately.

Cook the content

Cooking turns authored source — JSON documents, Lua scripts, imported assets — into the platform-ready form the runtime loads. Cooking exists so startup is fast and shipping content is a hashed, known set of files.

demi cook --platform linux
  • cook — validates, then cooks every reachable source file.
  • --platform linux — which platform profile to cook for.

Output lands under generated/cooked/<platform> together with cook.manifest.json: every cooked path and its content hash. The manifest is what later audits and incremental builds compare against. Returns 0 when the cook completes and the manifest is consistent.

Cooked output is generated content: never hand-edit it and never commit it. Re-run the cook instead.

Build the bundle

Building wraps the cooked content and a Linux runtime into the artifact a player installs:

demi build linux
  • build linux — cooks if needed, then packages the Linux runtime bundle.
  • Returns 0 on success, 1 when validation, cooking, or packaging fails.

The bundle contains:

PieceWhat it is
Executable and launcherThe game binary players start.
Cooked contentThe platform content from cook.manifest.json, verified by hash.
Freedesktop entryThe .desktop menu entry for application launchers.
IconThe application icon taken from the project's build metadata.
AttributionsThird-party attribution files for the libraries the runtime links.
build-report.jsonA report of what was built: versions, content hashes, and configuration.

Packaging is transactional. A failed or cancelled build leaves the previous artifact intact and never publishes a partial staging directory — the thing on disk is always a complete build or the previous complete build.

Package content audit

When content is packed for release, an audit checks every shipped file against the allowed roots. The audit exists so a release cannot accidentally include build output, editor state, or stray folders. The allowed roots are:

  • assets/ — asset manifests and sources.
  • certs/ — declared certificate material.
  • packages/ — vendored package content.
  • scenes/ — scene documents.
  • scripts/ — Lua sources.
  • demi.project.json — the project root document.
  • demi.packages.lock.json — the pinned dependency lock.
  • cook.manifest.json — the cooked-content manifest with paths and hashes.

Anything else is rejected with BUILD_PACKAGE_CONTENT_UNEXPECTED. The same roots apply when publishing packages (see Publishing packages) and when building release artifacts.

Where the running game writes

A shipped bundle must not write next to its own executable — that folder may be read-only or shared. Instead, the runtime uses the platform's per-user directories, following the XDG base directory rules:

DataPrimary locationFallback
Game saves$XDG_DATA_HOME/<game>/$HOME/.local/share/<game>/
Caches$XDG_CACHE_HOME/<game>/$HOME/.cache/<game>/
  • <game> — the game's identity from the project build metadata.
  • $XDG_DATA_HOME / $XDG_CACHE_HOME — environment variables from the XDG base directory specification; when unset, the fallbacks are used.

Saves and caches are per-user state. They never enter the bundle, never enter packages, and never become authored source. The save API itself is described in Replay & profiler.

Build metadata used by the bundle

Identity and window settings come from the project file:

"build": {
  "application_id": "com.example.skyforge",
  "display_name": "Skyforge",
  "executable_name": "skyforge",
  "version_name": "0.1.0",
  "version_code": 1,
  "icon": "asset://branding/icon",
  "window": { "width": 1280, "height": 720, "mode": "windowed" }
}
  • application_id — reverse-DNS identity, required before packaging.
  • display_name — the name in the desktop entry and window title.
  • executable_name — the binary name inside the bundle; must match ^[a-z0-9][a-z0-9_-]*$.
  • version_name / version_code — human and machine version numbers written into build-report.json.
  • icon — the asset:// ID of the application icon.
  • window — initial desktop window size in pixels and mode: windowed, borderless, or fullscreen.

The full project field list is on demi.project.json.

Before you hand the bundle to a player

  1. demi doctor — the machine can produce a desktop build.
  2. demi validate games/my_game --platform linux — no capability or content errors.
  3. demi test linux — end-to-end tests pass (E2E tests).
  4. demi build linux — a fresh bundle and build-report.json.
  5. Launch the bundle from a clean user account and confirm saves land under $XDG_DATA_HOME.

Android packaging is covered in Android builds; all build commands are listed in Build, cook & test.