27 lines
1.9 KiB
Markdown
27 lines
1.9 KiB
Markdown
# 0005. Namespaced content IDs
|
|
|
|
- **Status:** Accepted
|
|
- **Date:** 2026-06-27
|
|
|
|
## Context
|
|
|
|
All registered content — blocks, items, recipes, biomes, entities, and so on — needs a stable identifier that is unambiguous across the engine, data packs, Lua mods, recipe references, and save files. First-party and third-party content must coexist without collision, and identifiers must survive being written to disk and read back.
|
|
|
|
## Decision
|
|
|
|
Content is identified by a **namespaced string** of the form `"namespace:id"`.
|
|
|
|
- The namespace `core:` is reserved for first-party content (`"core:stone"`, `"core:iron_sword"`). Mods choose their own short namespace (`"mymod:weird_dirt"`).
|
|
- The strict form is mandatory. A bare id with no `:` is an **error at registration / parse time**, never silently coerced to `core:`. The rule is identical everywhere: engine scripts, data packs, Lua mods, recipe references, save files.
|
|
- Charset: namespace and id are each `[a-z0-9_-]+` with exactly one `:` between them. Lowercase ASCII only — no uppercase, Unicode, spaces, dots, or slashes.
|
|
- At registration time each id string is interned into a small integer handle (e.g. `BlockId(u32)`). Hot paths compare handles; the original string is kept for display, save/load, and the Lua API.
|
|
|
|
The reserved namespace is deliberately `core:` rather than the project name, so it remains stable independent of branding.
|
|
|
|
## Consequences
|
|
|
|
- Identifiers are greppable, filesystem-safe, and unambiguous in logs and save files.
|
|
- First-party and mod content cannot collide, and the absence of a silent default means mistakes surface immediately rather than corrupting data.
|
|
- A small runtime cost is paid at registration to intern strings, in exchange for handle comparison on hot paths.
|
|
- The strict form is a permanent contract: relaxing it later (e.g. defaulting bare ids) would change the meaning of existing save files and is therefore effectively irreversible.
|