chore(schemas): 🔧 Implement refined schema types and add new validation fields

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-04-14 18:12:43 -07:00
parent 26c1dbf98f
commit b41bf7432b
4 changed files with 182 additions and 0 deletions

View file

@ -0,0 +1,27 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://magic-civilization/schemas/autoplay/events-line.json",
"title": "AutoPlay Events Line",
"description": "One JSONL line appended to events.jsonl for each notable game event. additionalProperties: true — per-type fields are best-effort.",
"type": "object",
"additionalProperties": true,
"required": ["turn", "type"],
"properties": {
"turn": { "type": "integer", "minimum": 0 },
"type": {
"type": "string",
"enum": [
"city_founded",
"city_captured",
"city_grew",
"city_starved",
"tech_researched",
"unit_created",
"unit_destroyed",
"combat_resolved",
"victory"
],
"description": "Machine-readable event identifier"
}
}
}

View file

@ -0,0 +1,25 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://magic-civilization/schemas/autoplay/meta.json",
"title": "AutoPlay Game Meta",
"description": "meta.json written once when a game directory is created. Identifies the run.",
"type": "object",
"additionalProperties": true,
"required": ["seed", "start_stamp", "game_settings", "schema_version"],
"properties": {
"seed": { "type": "integer", "minimum": 0 },
"start_stamp": {
"type": "string",
"description": "ISO-8601 or compact YYYYMMDD_HHMMSS timestamp when the game started"
},
"game_settings": {
"type": "object",
"description": "Key/value game configuration (turn_limit, player count, map size, etc.)"
},
"schema_version": {
"type": "integer",
"minimum": 1,
"description": "Monotonically increasing version of the output schema"
}
}
}

View file

@ -0,0 +1,26 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://magic-civilization/schemas/autoplay/save.json",
"title": "AutoPlay Save Envelope",
"description": "Lenient envelope-only schema for saves/turn_NNNN.save files. Validates only the outer structure + top-level game_state keys.",
"type": "object",
"additionalProperties": true,
"required": ["version", "timestamp", "game_state"],
"properties": {
"version": { "type": "integer", "minimum": 1 },
"timestamp": {
"type": "integer",
"description": "Unix epoch seconds when the save was written"
},
"game_state": {
"type": "object",
"additionalProperties": true,
"required": ["turn_number", "players", "layers"],
"properties": {
"turn_number": { "type": "integer", "minimum": 0 },
"players": { "type": "array" },
"layers": { "type": "array" }
}
}
}
}

View file

@ -0,0 +1,104 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://magic-civilization/schemas/autoplay/turn-stats-line.json",
"title": "AutoPlay Turn Stats Line",
"description": "One JSONL line appended to turn_stats.jsonl after each turn. Each line is the full game state snapshot at turn N.",
"type": "object",
"additionalProperties": false,
"required": [
"turn",
"outcome",
"winner_index",
"victory_type",
"wall_clock_sec",
"aggregate",
"player_stats",
"invariant_violations"
],
"properties": {
"turn": {
"type": "integer",
"minimum": 0,
"description": "Turn number this snapshot was taken at"
},
"outcome": {
"type": "string",
"enum": ["in_progress", "victory", "max_turns", "defeat"]
},
"winner_index": { "type": "integer", "minimum": -1 },
"victory_type": { "type": "string" },
"wall_clock_sec": { "type": "number", "minimum": 0 },
"aggregate": {
"type": "object",
"additionalProperties": false,
"required": [
"total_combats",
"total_cities_founded",
"total_cities_captured",
"turn_first_combat",
"turn_first_city_captured"
],
"properties": {
"total_combats": { "type": "integer", "minimum": 0 },
"total_cities_founded": { "type": "integer", "minimum": 0 },
"total_cities_captured": { "type": "integer", "minimum": 0 },
"turn_first_combat": {
"type": "integer",
"minimum": -1,
"description": "-1 if no combat yet"
},
"turn_first_city_captured": { "type": "integer", "minimum": -1 }
}
},
"player_stats": {
"type": "object",
"description": "Map of player_index (as string) to per-player stats at this turn.",
"propertyNames": { "pattern": "^[0-9]+$" },
"additionalProperties": {
"$ref": "#/definitions/player_stats"
}
},
"invariant_violations": {
"type": "array",
"items": { "type": "string" }
}
},
"definitions": {
"player_stats": {
"type": "object",
"additionalProperties": false,
"required": [
"pop", "pop_peak",
"mil",
"cities", "cities_captured", "cities_lost",
"gold", "gold_peak", "gold_per_turn",
"techs", "tiles", "buildings",
"happiness",
"food_total", "production_total",
"kills", "units_lost",
"turn_first_pop_3", "turn_first_pop_4"
],
"properties": {
"pop": { "type": "integer", "minimum": 0 },
"pop_peak": { "type": "integer", "minimum": 0 },
"mil": { "type": "integer", "minimum": 0 },
"cities": { "type": "integer", "minimum": 0 },
"cities_captured": { "type": "integer", "minimum": 0 },
"cities_lost": { "type": "integer", "minimum": 0 },
"gold": { "type": "integer" },
"gold_peak": { "type": "integer" },
"gold_per_turn": { "type": "integer" },
"techs": { "type": "integer", "minimum": 0 },
"tiles": { "type": "integer", "minimum": 0 },
"buildings": { "type": "integer", "minimum": 0 },
"happiness": { "type": "integer" },
"food_total": { "type": "number" },
"production_total": { "type": "number" },
"kills": { "type": "integer", "minimum": 0 },
"units_lost": { "type": "integer", "minimum": 0 },
"turn_first_pop_3": { "type": "integer", "minimum": -1 },
"turn_first_pop_4": { "type": "integer", "minimum": -1 }
}
}
}
}