5.0 KiB
Server-authoritative symbol semantics (schema v2)
Milestone 5 issue #29 adds typed meaning to the existing data-pack symbol catalog. Put definitions at data/<namespace>/rivencraft/symbols/<path>.json; the file ID becomes the stable symbol ID. For example, data/example/rivencraft/symbols/terrain/highlands.json defines example:terrain/highlands:
{
"schema_version": 2,
"name": "symbol.example.terrain.highlands",
"description": "symbol.example.terrain.highlands.description",
"category": "example:terrain",
"semantics": {
"role": "terrain",
"value": "example:highlands"
},
"poem": "Terrain Form Tradition Flow"
}
name and description are translation keys. category is for display and sorting; it does not determine grammar. semantics.role and its typed value are server-owned. The terrain value above names an Age runtime profile that a later compiler must resolve and validate. A syntactically valid resource ID alone does not guarantee the profile or feature exists.
poem is optional, client-safe artwork metadata: exactly four alphabetic words, ordered top, right, bottom, left. The client layers their glyphs from the shared Legacy component sheet at runtime. GUI thumbnails use the full transparent artwork over their page backgrounds; item icons use the same artwork reduced from 16 to 13 pixels across, over the page texture. Unregistered words use a stable generated component combination; when a symbol has no poem, the six original built-in IDs retain their Legacy poems and other IDs produce four stable fallback words. This affects appearance only, never Age generation. Generated images are cached up to 256 entries and discarded on resource reload.
The Writing Desk's 88 collection tabs use Legacy's number components, chiefly the bottom row of symbolcomponents.png, rather than word sigils. Legacy's ModWords.constructNumber combines four unit marks (1–4) with four five-step marks (5–20) to form 1–24 and uses a separate zero mark. Rivencraft extends these marks positionally in base 25 for tabs 25–88 (for example, 25 is 1 followed by 0). Hovering still reveals the decimal number for accessibility. The former arbitrary-word glyph generator remains useful for rendering text: on page-free Descriptive Books, the generated Age description now appears as a sequence of layered word glyphs instead of Minecraft's enchantment font. The Age name stays readable.
| Role | Value type and allowed values |
|---|---|
terrain |
Canonical namespaced Age profile ID. |
biome_controller |
native, single, tiled, grid, tiny, small, medium, large, or huge. |
biome |
Canonical namespaced biome ID. |
lighting |
normal, dark, or bright. |
weather |
normal, fast, slow, off, always, cloudy, rain, snow, or storm. |
celestial |
normal_time (the first representable single-cycle behavior). |
period_modifier |
JSON number in [0, 2]; zero is stopped time. |
angle_modifier |
JSON number in [0, 360) degrees. |
phase_modifier |
JSON number in [0, 360) degrees; the compiler will convert to turns. |
feature |
Canonical namespaced feature-effect ID; future generation mapping must recognize it. |
These are schema bounds, not claims that Legacy shipped numeric config ranges. See the Legacy grammar audit for the source values and biome-count rules. Roles outside this table—including multiple suns, gradients, special structures, and hazards—are intentionally unsupported by schema v2. Their meaning requires a later versioned extension, not an unvalidated free-form field.
The server rejects a v2 definition with an unknown top-level or semantics field, missing/incorrectly typed field, unknown role or choice, malformed/non-canonical resource ID, or out-of-range/non-finite number. An invalid definition is logged with its file ID and excluded from the active catalog. Saved pages and books still retain that ID, allowing the player to recover them if the data pack is corrected. A reload atomically replaces the catalog rather than mutating saved writing.
Schema v1 definitions remain readable as display-only symbols; existing packs need not be rewritten merely to show or copy pages. A v1 definition cannot add a semantics field. To make one eligible for Age grammar parsing, publish a v2 definition with the same file path and ID, adding a valid role and value. Do not rename the page ID or reorder a book's OrderedWriting. The client receives only SymbolDisplayMetadata (ID, translation keys, category, resolved flag); semantic definitions are not serialized to it. The ordered-writing parser validates new books, but does not yet apply written symbols to Age generation; issue #31 adds compilation.
The six built-in definitions demonstrate terrain, biome-controller, lighting, weather, celestial, and feature roles. A third-party pack may add its own definitions under its namespace. Use an explicit semantic role even when the display category has the same name; the two fields serve different purposes.