# 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.