DEMIENGINEDOCUMENTATION Everything is free
CLI reference · Start here

validate, cook, build, test, capabilities, lua-stubs.

Build, cook & test

Creating a game is step one. Step two is proving it is correct and getting it onto a player's machine. This page covers validation (checking documents before you trust them), cooking (turning source into platform-ready content), testing (running real gameplay checks), and building (producing a shippable artifact). Examples use "Skyforge" at games/my_game and the CLI at demi.

Why validate before you run

A validation pass reads the project and everything it can reach — scenes, HUDs, prefabs, assets, saves, scripts — and reports problems with stable diagnostic codes. The point is to catch broken references and malformed documents before a player does, and to make "it works" a machine-checkable claim rather than a feeling. The editor shows the same codes as this command.

demi validate games/my_game
  • validate [path] — validates a project, a single document, or a directory of source. Defaults to the current directory's project.
  • Returns 0 when everything reachable is valid, 1 when any validation error was reported.

Validate for a shipping target, because platforms differ in what they can support:

demi validate games/my_game --platform android
  • --platform android — adds platform capability checks, for example missing permissions or unsupported features.

Stable capability codes include PROJECT_BUILD_FEATURE_MEDIA_UNSUPPORTED, PROJECT_BUILD_FEATURE_NETWORK_UNSUPPORTED, PROJECT_BUILD_FEATURE_SVG_UNSUPPORTED, PROJECT_BUILD_PERMISSION_NETWORK_MISSING, and BUILD_PACKAGE_CONTENT_UNEXPECTED. Details per platform: Linux bundles and Android builds.

Inspect scenes, HUDs, prefabs, and saves

Inspect commands summarize one document after validating it. They answer "what is actually in this file?" without opening a text editor.

demi scene list games/my_game
demi scene inspect games/my_game/scenes/main.scene.json
demi scene expand games/my_game/scenes/main.scene.json
  • scene list — lists every scene reference the project registers. Returns one scene ID per line.
  • scene inspect — validates and summarizes a scene: entities, components, and references.
  • scene expand — prints the scene with every prefab instance expanded into concrete entities, exactly what the runtime will create.
demi scene diff old/main.scene.json games/my_game/scenes/main.scene.json
  • scene diff <old> <new> — a deterministic structural diff of two expanded scenes. Useful for review: "what did this edit actually change?"
demi hud inspect games/my_game/hud/hud.json \
  --safe-area 24,24,24,24 --reveal-hidden --format text
  • hud inspect — validates and summarizes a HUD document.
  • --safe-area l,t,r,b — evaluate layout against the given safe-area insets.
  • --reveal-hidden — include nodes that are hidden in the summary.
  • --format — output format (text or json).
demi prefab inspect games/my_game/prefabs/enemy.prefab.json
demi save inspect saves/slot1.json
  • prefab inspect — validates and summarizes a prefab document.
  • save inspect — validates and summarizes a save file. Returns 1 if the save is corrupt.

Check Lua and generate editor stubs

Scripts are validated like any other source:

demi script check games/my_game/scripts/player.lua
  • script check — parses the Lua file with the engine's Lua 5.4 compiler and reports diagnostics with line numbers. Returns 1 on syntax errors.

For editor completion and type hints of the public Lua API:

demi lua-stubs generate games/my_game
  • lua-stubs generate [dir] — writes LuaLS stub files for the engine and installed package APIs.
  • [dir] — optional output directory. Defaults to .demi/lua, which LuaLS reads as workspace.library.

Exits 0 and prints the output directory.

Run tests

Testing means executing real gameplay through the real runtime and checking the results with assertions, not inspecting files. Project tests live in scripts/tests/e2e.lua and are written with the Test API — see E2E tests for authoring them.

demi test
  • demi test — runs built-in scaffold checks: the quick self-tests of the toolchain itself.
  • Returns 0 on success, 1 on failure.
demi test linux
  • test linux — desktop end-to-end tests through the real runtime window or headless path.
demi test android --serial <device>
  • test android --serial d — device end-to-end tests via adb on a connected physical device.
  • --serial <device> — which device to target.
DEMI_HEADLESS=1 demi test
  • DEMI_HEADLESS=1 — runs without a visible window. Returns 0 only when every test passed.

Each run always prints a final pass/fail summary, so a truncated log still tells you the outcome.

Run with tests, replay, and profiling

demi run accepts the same evidence-gathering flags, which is how you reproduce a bug report on your machine:

demi run --e2e-tests
  • --e2e-tests — runs the project E2E scripts during launch and reports pass/fail.
demi run \
  --input-replay fixtures/bug123.replay.json
  • --input-replay file — replays a recorded input stream instead of live input. The project's fixed timestep must match the fixture.
demi run linux --profiler \
  --profile-report report.csv --profile-frames frames.csv
  • run linux — desktop launch with the Linux runtime.
  • --profiler — prints slow-frame details while the game runs.
  • --profile-report r.csv — writes an aggregate scope report (totals per named scope).
  • --profile-frames f.csv — writes per-frame scope totals.
demi run \
  --debug-overlays colliders,contacts --window-size 1280x720
  • --debug-overlays names — comma-separated overlay names (colliders, contacts, grid, entity_ids, draw_order, ui_bounds, profiler) overriding the project settings for this run.
  • --window-size WxH — initial desktop window size in pixels.

Replay and profiling workflows are explained in Replay & profiler.

Cook platform content

Cooking converts authored source (JSON, scripts, imported assets) into the platform-ready form the runtime actually loads: compiled scripts, optimized textures, and a content manifest with hashes. Cooking exists so runtime startup is fast and so shipping content is a known, hashed set of files rather than loose source.

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

Writes cooked output under generated/cooked/<platform> plus cook.manifest.json listing every cooked path and its hash. Exits 0 when the cook is complete and consistent.

Build shippable artifacts

Building wraps cooked content and a runtime into an artifact a player can install. Packaging is transactional: a failed or cancelled build leaves the previous artifact intact and never publishes a partial staging directory.

demi build linux
  • build linux — cooks and packages a Linux runtime bundle: executable, launcher, cooked content, freedesktop entry, icon, attributions, and build-report.json.
demi build apk --configuration release
  • build apk — packages an Android APK. Add --configuration release for a release build and --gradle to invoke Gradle with a specific wrapper.
demi build aab
  • build aab — packages an Android App Bundle for store distribution.

Full artifact layouts: Linux bundles and Android builds.

Export capabilities

Capabilities describe what the engine supports (components, features, platforms) as machine-readable metadata. Exporting them lets tooling and continuous integration detect accidental capability regressions.

demi capabilities export
demi capabilities check --baseline capabilities-baseline.json --format json
demi capabilities verify-gates
  • capabilities export — writes the current component and capability metadata. The export is atomic.
  • capabilities check [--baseline path] — reports deltas against a baseline document. --format text|json chooses the output shape.
  • capabilities verify-gates — validates the reference capability manifest. Returns 1 if a gate is violated.

Exit codes again

CodeMeaning
0Success
1Validation or test failure
2Usage error
3Internal error

Next: author with the editor workspace, write checks with E2E tests, or measure with Replay & profiler.