EverambleGAME API / 1

CONTENT CONTRACT · VERSION 1

Authoring tools.

Validate, test, pack and live-reload content packages with one command-line tool and the game itself.

Commands

hearthwild-content validate PACKAGE|ARCHIVE [--dependencies DIR] [--target desktop|macos|ios] [--format json]
Strict load of the package and its local dependencies, then every declared fixture in the game interpreter. No network; dependencies must be local.
hearthwild-content pack PACKAGE --out FILE.hwpkg
Validates, then writes the exact validated bytes with the canonical package.lock.json. Deterministic: with the same tool build, the same package always packs to the same archive, which is loaded back before it is kept.
hearthwild-content watch PACKAGE|PACKAGES_DIR [--format json] [--limit N]
Validates again whenever the files settle after a change and prints one report per generation.
hearthwild-content schema | types | generate --api 1 --out DIR
Regenerates the JSON schemas, Luau declarations and contract index from the Rust contract.
hearthwild-content docs --api 1 --out DIR --commit COMMIT
Builds this reference; it only builds from a package whose fixtures pass.

Exit codes

CodeMeaning
0Valid (or packed)
1Invalid command or arguments
2Content errors; diagnostics name file and JSON pointer
3Tool or I/O failure

Diagnostics

With --format json every diagnostic is a record with code, file, JSON pointer and message, sorted deterministically. A failing fixture reports fixture_failed with the expected and the actual answer:

{
  "diagnostics": [
    {
      "code": "fixture_failed",
      "file": "tests/healing_potion_60.json",
      "message": "healing_potion_60: result differs",
      "pointer": ""
    }
  ],
  "valid": false
}

Live reload while playing

Start the game with HW_CONTENT_WATCH=1 to reload the content packages of a local world whenever their files change:

HW_CONTENT_WATCH=1 cargo run -p hw-bench --bin everamble --features dev -- --continue
  1. EditSave any package file.
  2. SettleThe watcher waits until the files stop changing.
  3. BuildA complete new generation loads in the background with the same strict loader.
  4. SwitchBetween two ticks: save backup, migration, all handlers at once.

An invalid generation shows its first diagnostic as a notice and the running generation stays active; the full list goes to the log. A reload without content changes swaps nothing. Saved quest stages and variable values the new generation can no longer interpret return to their initial values; state of IDs it does not declare is kept. The first reload of a session keeps an extra save backup. Network players join again after a reload. Only local worlds reload: servers keep their packages until restart.