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
0when everything reachable is valid,1when 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 (textorjson).
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. Returns1if 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. Returns1on 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 asworkspace.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
0on success,1on 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. Returns0only 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, andbuild-report.json.
demi build apk --configuration release
build apk— packages an Android APK. Add--configuration releasefor a release build and--gradleto 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|jsonchooses the output shape.capabilities verify-gates— validates the reference capability manifest. Returns1if a gate is violated.
Exit codes again
| Code | Meaning |
|---|---|
0 | Success |
1 | Validation or test failure |
2 | Usage error |
3 | Internal error |
Next: author with the editor workspace, write checks with E2E tests, or measure with Replay & profiler.