From 4b5fa4345e24880ceb6d99fdfba99f642e6e5b4d Mon Sep 17 00:00:00 2001 From: Serkyo Date: Sun, 28 Jun 2026 00:50:10 +0200 Subject: [PATCH] docs(workspace): move data/resource pack design to docs/packs.md --- AGENTS.md | 36 ++----------- docs/README.md | 7 ++- ...007-declarative-content-via-modding-api.md | 25 +++++++++ docs/packs.md | 53 +++++++++++++++++++ 4 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 docs/adr/0007-declarative-content-via-modding-api.md create mode 100644 docs/packs.md diff --git a/AGENTS.md b/AGENTS.md index caa6369..a9a028f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,41 +61,11 @@ Three distinct locations, do not mix them: ## Data packs & resource packs -Two distinct, orthogonal systems — keep them separate, do not collapse them into one "pack" concept. +Two distinct, orthogonal systems — keep them separate, do not collapse them into one "pack" concept. **Resource packs** are client-side asset overlays (textures, sounds, models, fonts, language files; no logic). **Data packs** are declarative content definitions (JSON/TOML/RON): blocks, items, recipes, loot tables, biomes, tags. -**Resource packs** — client-side asset overlays. Textures, sounds, models, fonts, language files. No logic. A pack is a directory tree mirroring `/assets/` that overrides files by path. The renderer/asset loader resolves logical asset IDs against a stack of pack roots (base game → installed packs by priority) and the topmost hit wins. Server has no involvement. Owned by the asset pipeline (in `client`, or a sibling `assets` crate if it grows). Pack authors never touch Lua. +The load-bearing rule: **do not build a parallel registration system.** The data-pack loader reads the declarative files and calls the same Lua API the engine and Lua mods use — one source of truth (`data/blocks/stone.json` → loader → `blocks.register{ … }`). Each schema is a stable contract; version it deliberately. The decision is recorded in [ADR-0007](docs/adr/0007-declarative-content-via-modding-api.md). -**Data packs** — declarative content definitions in JSON (or TOML/RON, TBD): blocks, items, recipes, loot tables, biomes, tags. **Do not build a parallel registration system** — the loader reads the JSON and calls the same Lua API the engine and Lua mods use. One source of truth: `data/blocks/stone.json` → loader → `blocks.register{ id = "stone", … }`. Loader belongs in `scripting` (or a sibling crate if it grows). Engine first-party content may use either JSON or Lua, whichever fits. - -**Canonical load order** (later layers override earlier ones): - -``` -base game (assets/scripts + assets/data) - → data packs (declarative content add/override) - → Lua mods (full API access) - → resource packs (client-only, asset overlay — always last so visuals win) -``` - -**Repo layout:** - -``` -/assets/ - data/ # base-game declarative content - blocks/ items/ recipes/ … - scripts/ # base-game Lua (behavior) - textures/ models/ sounds/ icons/ shaders/ # base-game assets -``` - -**User-data layout** (runtime, resolved via `directories`/`dirs`): - -``` -/ - mods/ # Lua mods - datapacks/ # JSON content packs - resourcepacks/ # asset overlays (client only) -``` - -Every data-pack schema you accept is a stable contract, same as the Lua API. Version it deliberately. +Full subsystem detail — load order, repo and user-data layout, resolution semantics — lives in [`docs/packs.md`](docs/packs.md). ## Contributing workflow diff --git a/docs/README.md b/docs/README.md index 363cd20..660925e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -36,6 +36,11 @@ Each subsystem note should name the design topic it implements (by title, e.g. " - [`adr/0004-server-authoritative-simulation.md`](adr/0004-server-authoritative-simulation.md) — server-authoritative simulation. - [`adr/0005-namespaced-content-ids.md`](adr/0005-namespaced-content-ids.md) — namespaced content IDs. - [`adr/0006-base-game-on-modding-api.md`](adr/0006-base-game-on-modding-api.md) — base game built on the modding API. + - [`adr/0007-declarative-content-via-modding-api.md`](adr/0007-declarative-content-via-modding-api.md) — declarative content loads through the modding API. - [`adr/template.md`](adr/template.md) — template for new decisions. -Subsystem notes are added here as systems are implemented and locked. +Subsystem notes: + +- [`packs.md`](packs.md) — data packs & resource packs (load order, layout, resolution). + +Further subsystem notes are added here as systems are implemented and locked. diff --git a/docs/adr/0007-declarative-content-via-modding-api.md b/docs/adr/0007-declarative-content-via-modding-api.md new file mode 100644 index 0000000..a13d398 --- /dev/null +++ b/docs/adr/0007-declarative-content-via-modding-api.md @@ -0,0 +1,25 @@ +# 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). diff --git a/docs/packs.md b/docs/packs.md new file mode 100644 index 0000000..4198635 --- /dev/null +++ b/docs/packs.md @@ -0,0 +1,53 @@ +# Data packs & resource packs + +Two distinct, orthogonal systems. They are kept separate and are not collapsed into one "pack" concept. The decision that data packs register through the modding API rather than a parallel path is recorded in [ADR-0007](adr/0007-declarative-content-via-modding-api.md). + +## Resource packs + +Client-side asset overlays: textures, sounds, models, fonts, language files. No logic. + +A pack is a directory tree mirroring `/assets/` that overrides files by path. The renderer/asset loader resolves logical asset IDs against a stack of pack roots (base game → installed packs by priority) and the topmost hit wins. The server has no involvement. Ownership sits with the asset pipeline (in `client`, or a sibling `assets` crate if it grows). Pack authors never touch Lua. + +## Data packs + +Declarative content definitions in JSON (or TOML/RON, TBD): blocks, items, recipes, loot tables, biomes, tags. + +No parallel registration system is built. The loader reads the declarative files and calls the same Lua API the engine and Lua mods use. One source of truth: + +``` +data/blocks/stone.json → loader → blocks.register{ id = "stone", … } +``` + +The loader belongs in `scripting` (or a sibling crate if it grows). Engine first-party content may use either JSON or Lua, whichever fits. Every data-pack schema is a stable contract, the same as the Lua API — version it deliberately. + +## Canonical load order + +Later layers override earlier ones: + +``` +base game (assets/scripts + assets/data) + → data packs (declarative content add/override) + → Lua mods (full API access) + → resource packs (client-only, asset overlay — always last so visuals win) +``` + +## Repo layout + +``` +/assets/ + data/ # base-game declarative content + blocks/ items/ recipes/ … + scripts/ # base-game Lua (behavior) + textures/ models/ sounds/ icons/ shaders/ # base-game assets +``` + +## User-data layout + +Runtime, resolved via the `directories` / `dirs` crate: + +``` +/ + mods/ # Lua mods + datapacks/ # JSON content packs + resourcepacks/ # asset overlays (client only) +```