docs(workspace): move data/resource pack design to docs/packs.md
This commit is contained in:
parent
0416aa35ca
commit
4b5fa4345e
36
AGENTS.md
36
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`):
|
||||
|
||||
```
|
||||
<user-data>/
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
25
docs/adr/0007-declarative-content-via-modding-api.md
Normal file
25
docs/adr/0007-declarative-content-via-modding-api.md
Normal file
|
|
@ -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).
|
||||
53
docs/packs.md
Normal file
53
docs/packs.md
Normal file
|
|
@ -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:
|
||||
|
||||
```
|
||||
<user-data>/
|
||||
mods/ # Lua mods
|
||||
datapacks/ # JSON content packs
|
||||
resourcepacks/ # asset overlays (client only)
|
||||
```
|
||||
Loading…
Reference in a new issue