Synvael/docs/adr/0007-declarative-content-via-modding-api.md

26 lines
1.9 KiB
Markdown

# 0007. Declarative content loads through the modding API
- **Status:** Accepted
- **Date:** 2026-06-27
## Context
Content can be defined declaratively in data files (JSON, or another format) rather than in Lua: blocks, items, recipes, loot tables, biomes, tags. A naive implementation gives data packs their own registration code path straight into the engine's registries. That produces two parallel ways to register the same content, which drift apart and double the surface that must be kept correct.
This decision concerns **data packs** (declarative content). It is distinct from **resource packs**, which are client-side asset overlays carrying no logic; the two systems are orthogonal and must not be merged into one "pack" concept.
## Decision
The data-pack loader reads the declarative files and **calls the same Lua API** the engine and Lua mods use. There is one registration path: `data/blocks/stone.json` → loader → `blocks.register{ id = "stone", … }`. No parallel registration system is built. The loader belongs in `scripting` (or a sibling crate if it grows). First-party content may use either JSON or Lua, whichever fits.
Each data-pack schema is treated as a stable contract, versioned as deliberately as the Lua API.
The canonical load order, later layers overriding earlier ones, is: base game → data packs → Lua mods → resource packs (resource packs last so client visuals win).
## Consequences
- One source of truth for registration; declarative content and scripted content cannot diverge in behaviour because they end at the same API.
- Accepting a schema is a long-lived commitment, since data packs in the wild depend on it.
- Resource packs remain entirely client-side with no server involvement, and are kept conceptually separate from data packs.
- Full subsystem detail (load order, repo and user-data layout, resolution semantics) lives in [`docs/packs.md`](../packs.md).