# Writing and symbol data Milestone 4 stores what a player wrote without deciding what that writing does to an Age. Milestone 5 owns grammar validation, symbol interaction, instability, and translation into biome, noise, dimension-type, and other world-generation configuration. ## Symbol catalog The authoritative server catalog loads JSON resources from `data//rivencraft/symbols/.json`. The resource ID is the symbol ID. For example, `data/rivencraft/rivencraft/symbols/terrain/standard.json` defines `rivencraft:terrain/standard`. Schema version 1 contains display metadata only: ```json { "schema_version": 1, "name": "symbol.rivencraft.terrain.standard", "description": "symbol.rivencraft.terrain.standard.description", "category": "rivencraft:terrain" } ``` `name` and `description` are translation keys, not arbitrary formatted text or executable behavior. `category` is a namespaced organizational identifier. Invalid definitions are logged and excluded by the server. Menus and future page synchronization must obtain resolved display metadata from the server; clients never make a symbol valid by naming it. Rivencraft ships a small catalog covering terrain, biomes, lighting, weather, celestial behavior, and features. It exists to exercise the complete writing workflow before Milestone 5 implements the full legacy grammar. ## Persistent writing `SymbolReference` stores only a namespaced symbol ID. `WritingEntry` is either a symbol reference or a baseline link-panel marker. `OrderedWriting` retains up to 256 entries in exact player-authored order. All three contracts have both persistent codecs and bounded network codecs. Removing a data pack never removes its IDs from saved writing. A missing ID is resolved as client-safe **Unresolved Symbol** display metadata while retaining the original namespaced ID for diagnostics and later restoration. This is deliberately different from treating an unknown symbol as valid grammar. ## Pages The single stackable `rivencraft:page` item has a bounded, persistent `rivencraft:page_content` component. Its explicit states are blank, symbol, unresolved symbol, and baseline link panel. Symbol and unresolved-symbol pages retain their namespaced symbol reference; unresolved pages can be inspected and removed but are rejected as usable writing until their data pack returns. Only server-side writing operations may turn a blank page into a known symbol page or link panel. The shared `PageItem` creation and validation gates reject new pages for identifiers absent from the server catalog. Later Writing Desk and Book Binder packets must call these gates rather than accepting page contents supplied by a client. The item model uses server-assigned custom-model data derived from the symbol identifier. Built-in pages reproduce Mystcraft Legacy's four-word poem composition from its page background and symbol-component sheet. Data-pack symbols without a bundled resource-pack model use the legacy question-mark fallback while keeping their real identifier and display metadata.