{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "base", "title": "Base Resource", "description": "Root schema for all game resources. Every resource inherits from this.", "type": "object", "required": ["id", "name"], "properties": { "id": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$", "description": "Unique snake_case identifier. Must be globally unique within its category." }, "name": { "type": "string", "description": "Display name shown in UI and guide." }, "description": { "type": "string", "description": "Flavor text or functional description." }, "tags": { "type": "array", "items": { "type": "string" }, "default": [], "description": "Freeform classification tags for filtering and querying." }, "influences": { "type": "object", "description": "Design lineage. Notes equivalent or inspiring concepts from reference games and systems. Used for attribution and future design alignment, not read by the engine.", "properties": { "mtg": { "type": "string", "description": "Magic: The Gathering equivalent — creature type, specific cards, or mechanic." }, "dnd": { "type": "string", "description": "Dungeons & Dragons equivalent — Monster Manual entry, stat block, or sourcebook reference." }, "mom": { "type": "string", "description": "Master of Magic equivalent — unit, spell, or world feature." }, "civ": { "type": "string", "description": "Civilization series equivalent — unit, improvement, terrain, or wonder." }, "freeciv": { "type": "string", "description": "Freeciv / Fantastic Worlds equivalent." }, "notes": { "type": "string", "description": "General design notes about what was adapted, inverted, or combined from these sources." } }, "additionalProperties": false } }, "$defs": { "school": { "type": "string", "enum": ["life", "death", "nature", "aether", "chaos", "generic", "all", "none"] }, "ley_school": { "type": "string", "enum": ["life", "death", "nature", "aether", "chaos"] }, "mana_source": { "type": "object", "required": ["school", "amount"], "properties": { "school": { "$ref": "#/$defs/school" }, "amount": { "type": "number", "minimum": 0 } } }, "color_rgb": { "type": "array", "items": { "type": "integer", "minimum": 0, "maximum": 255 }, "minItems": 3, "maxItems": 3 }, "lifecycle": { "$id": "lifecycle", "type": "object", "description": "Full lifecycle metadata. Describes how this resource forms, evolves, and dies. The engine processes transforms; the guide renders the full chain.", "required": ["system", "stage"], "properties": { "system": { "type": "string", "description": "Groups resources into lifecycle families for guide display and engine processing.", "enum": [ "volcanic", "river", "glacier", "reef", "forest", "cave", "wetland", "desert", "mountain", "coast", "permafrost", "lake", "ocean", "spring", "erosion" ] }, "stage": { "type": "string", "description": "Position within the lifecycle.", "enum": ["birth", "young", "active", "mature", "dormant", "dying", "dead", "remnant", "terminal"] }, "formed_by": { "type": "array", "description": "What creates this resource. Engine ignores this; guide uses it to trace lineage backwards.", "items": { "type": "object", "required": ["source", "mechanism"], "properties": { "source": { "type": "string", "description": "ID of the source resource (terrain, event, etc.)." }, "mechanism": { "type": "string", "enum": ["time", "event", "climate", "accumulation", "map_gen"], "description": "How the formation happens." }, "event_category": { "type": "string", "description": "If mechanism=event, which event category triggers formation." }, "min_tier": { "type": "integer", "description": "If mechanism=event, minimum event tier required." }, "condition": { "type": "string", "description": "Readable condition for when this formation path applies." } } } }, "transforms": { "type": "array", "description": "Ordered list of possible transformations. First matching condition wins per turn.", "items": { "type": "object", "required": ["to", "condition"], "properties": { "to": { "type": "string", "description": "Target resource ID after transformation." }, "condition": { "type": "string", "enum": ["default", "event", "climate", "accumulation", "depletion"], "description": "What triggers this transform. 'default' = time-based countdown (engine processes). Others = external trigger (event system, climate thresholds, resource accumulation/depletion)." }, "turns": { "type": "integer", "minimum": 1, "description": "Duration in turns for condition=default. Scaled by world transform_rate_multiplier." }, "event_category": { "type": "string", "description": "For condition=event: which event category triggers this." }, "min_tier": { "type": "integer", "description": "For condition=event: minimum event tier." }, "climate_field": { "type": "string", "description": "For condition=climate: which TileState field to check (temperature, moisture, surface_water, etc.)." }, "climate_op": { "type": "string", "enum": ["<", "<=", ">", ">="], "description": "For condition=climate: comparison operator." }, "climate_value": { "type": "number", "description": "For condition=climate: threshold value." }, "climate_sustained_turns": { "type": "integer", "description": "For condition=climate: how many consecutive turns the condition must hold." }, "chance": { "type": "number", "minimum": 0, "maximum": 1, "description": "Probability [0,1] that this transform fires when condition is met. 1.0 = always." }, "description": { "type": "string", "description": "Readable explanation for the guide." } } } } } } } }