DEMIENGINEDOCUMENTATION Everything is free
CLI reference · Start here

asset and package command groups in detail.

Assets & packages

Games are mostly content: images, models, sounds, data files. In DemiEngine that content is managed as assets (files the game loads by stable ID) and packages (reusable bundles of scripts and assets other projects can depend on). This page covers the demi asset and demi package command groups, using the sample game "Skyforge" at games/my_game.

What an asset is

An asset is one piece of game content plus a small JSON manifest that names it. The manifest lives at assets/<name>.asset.json and gives the asset a stable ID like asset://textures/brick. Scenes and scripts reference that ID, never a file path, so the file behind it can be reimported or re-exported without rewriting the game.

Why manifests instead of raw paths? Because IDs survive reimports, cooking, and packaging. A scene that says asset://ui/theme keeps working when the theme source file is replaced by a newer export from your art tool.

Inspect an asset

Before debugging a missing texture, ask the engine what it knows about the asset:

demi asset inspect assets/textures/brick.asset.json
  • asset inspect — takes the manifest path, validates it, and prints a summary: ID, type, importer, source path, and source hash.

Exits 0 when the manifest is valid, 1 when validation reports errors.

demi asset deps assets/textures/brick.asset.json
  • asset deps — takes the manifest path and lists what this asset depends on: first the IDs of asset dependencies, then the source-file paths. One per line, so it is easy to use in a build script to decide whether a reimport is needed.

Import and reimport

Import takes a source file from anywhere on disk (an art export, a WAV, a glTF model), copies it into the project's asset area, and writes the manifest that registers it.

demi asset import ~/art/brick.png \
  --id asset://textures/brick
  • asset import <source> — the file to bring in.
  • --id asset://textures/brick — the stable ID the new manifest will declare.
  • --importer <id> — optional; names the importer when the file type alone is ambiguous (for example a model that could be static or skinned).

Returns 0 and prints the manifest path on success. When the source file changes later, refresh the registered output:

demi asset reimport assets/textures/brick.asset.json
  • asset reimport — takes the manifest path, regenerates the asset output, updates the source hash and metadata, and leaves the asset ID unchanged.

Content produced by another tool already inside the project can be registered without a copy:

demi asset register-generated assets/textures/brick_atlas.png \
  --id asset://textures/brick_atlas
  • asset register-generated <source> — registers a tool-generated source under assets/ so it becomes a first-class asset.

Colliders, packs, and budgets

Three specialized asset commands cover physics shapes, portable packs, and performance checks:

demi asset collider assets/models/crate.asset.json \
  --id asset://colliders/crate
  • asset collider — generates a collider asset from a model asset, so physics uses the authored shape instead of a rough box.
demi asset export \
  --output skyforge_props.demipack \
  --asset asset://textures/brick
  • asset export --output file.demipack --asset asset://id — writes a portable asset pack: a single file other projects can import. At least one --asset asset://id is required; repeat the flag to export several assets. Without it the command exits with a usage error.
demi asset import-package skyforge_props.demipack
 
  • asset import-package file.demipack — verifies the pack and imports its assets into the project. Returns 1 if verification fails.
demi asset budget games/my_game/demi.project.json --platform android
  • asset budget — takes the project file (demi.project.json, not a directory) and reports 3D budget usage against the platform's profile.
  • --platform android|linux — which platform's budget profile to measure against.

Budgets are declared in the project file and are covered in demi.project.json.

What a package is

A package is a versioned, reusable unit of game code and content: Lua modules, scenes, prefabs, and assets that several games can share. Packages exist so "health bars", "third-person movement", or "prototype textures" are written once and depended on, instead of copied between projects. Installing packages is covered on Installing packages; publishing your own is on Publishing packages.

Add and remove dependencies

Dependencies are declared in the project file and managed with the package commands:

demi package add demi.gameplay.health@^1.0.0
 
  • package add name@constraint — resolves the name against the registry and records the constraint as a direct dependency.
  • name@constraint — for example demi.gameplay.health@^1.0.0, meaning "any 1.x release at 1.0.0 or newer".

Resolves and records the dependency, updates demi.packages.lock.json with the pinned version, and exits 0.

demi package remove demi.gameplay.health
 
  • package remove name — removes the named direct dependency and re-resolves the lock file.

Install, update, and inspect

demi package install
  • package install — installs every resolved package into .demi/packages, a derived folder that is safe to delete and regenerate.
  • --locked — installs exactly the versions in demi.packages.lock.json and fails instead of re-resolving. Use this in continuous integration.
  • --offline — installs from the local cache only; no network access. Returns 1 if a needed version is not cached.
  • --dry-run — prints the install plan and exits without writing anything.
demi package update demi.gameplay.health
 
  • package update [name] — re-resolves within the declared constraints. With a name, updates that package only; without one, updates every package.
demi package list
demi package outdated --format json
  • package list — prints the resolved versions currently installed.
  • package outdated — prints resolved versions that have a newer release satisfying the constraint.
  • --format json — same information as a JSON document for scripts and editors.

Both return the listing on standard output and exit 0 when the project's dependency state is consistent.

Test a package

Packages can ship their own tests so consumers can trust an upgrade:

demi package test packages/skyforge-kit
  • package test [dir] — runs the declared Lua package tests in the given package directory (default: the current directory).
  • Returns 0 when all tests pass, 1 when any test fails.

Publish a package

demi package publish packages/skyforge-kit \
  --registry https://demiengine.de
  • package publish [dir] — packages the directory and uploads a release to the registry.
  • --registry <url-or-path> — where to publish. https://demiengine.de is the public store.

Releases are immutable once published: a version number is a promise that its content will not change. The full workflow, including the audited package content roots, is documented on Publishing packages.

Command map

GoalCommand
Summarize an assetdemi asset inspect <manifest>
List asset sourcesdemi asset deps <manifest>
Bring a file indemi asset import <source> --id asset://…
Refresh after art changesdemi asset reimport <manifest>
Register tool outputdemi asset register-generated <source> --id asset://…
Make a physics shapedemi asset collider <model.asset.json> --id asset://…
Share assets as a packdemi asset export --output file.demipack --asset asset://…
Consume an asset packdemi asset import-package file.demipack
Check budget usagedemi asset budget demi.project.json --platform android|linux
Add a dependencydemi package add name@constraint
Install resolved packagesdemi package install [--locked] [--offline] [--dry-run]
Upgrade within constraintsdemi package update [name]
See resolved and outdated versionsdemi package list|outdated [--format json]
Run package testsdemi package test [dir]
Ship a releasedemi package publish [dir] --registry <url>

See also Installing packages, Publishing packages, and the CLI reference.