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
| Code | Meaning |
|---|---|
0 | Valid (or packed) |
1 | Invalid command or arguments |
2 | Content errors; diagnostics name file and JSON pointer |
3 | Tool 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- EditSave any package file.
- SettleThe watcher waits until the files stop changing.
- BuildA complete new generation loads in the background with the same strict loader.
- 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.