58 lines
3.5 KiB
Markdown
58 lines
3.5 KiB
Markdown
# 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. Ownership sits with the asset pipeline (in `client`, or a sibling `assets` crate if it grows). Pack authors never touch Lua.
|
|
|
|
A client's own resource packs are a purely local choice; the server has no say over them and they are never part of gameplay modlist matching. The **one** exception is a **server resource pack**: a server may push a single cosmetic overlay of its own (a themed / total-conversion server) to connecting clients. It is a one-way server → client push, applied on top of the client's local stack, and enforced per the server's choice — *optional* packs the client may decline and keep playing, a *required* pack the client declines or fails to fetch rejects the connection. It is still `assets/`-only (no `data/`, no `scripts/`), so it can never affect authoritative state.
|
|
|
|
## 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). Every data-pack schema is a stable contract, the same as the Lua API, version it deliberately.
|
|
|
|
**Declarative-first (ADR-0007):** JSON and Lua are not free alternatives. Anything expressible as data — the static fields of a block, item, recipe, loot table, biome, or tag — is authored as data in `data/`; Lua is reserved for behavior (logic that runs on an event or tick). A pure-data block therefore needs no Lua, and a data pack can register such a primitive on its own; only its behavior half (if any) comes from a Lua mod. Engine first-party content follows the same rule, keeping pure-data `core` content in `data/` and only behavioral systems in `scripts/`. To avoid hand-authoring large volumes of near-identical files, modders may use **datagen**: code that emits `data/` files at build time, before the pack ships — its output, not its code, is the shipped artifact, and it never runs at load time.
|
|
|
|
## 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)
|
|
```
|