{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://ziggyserver.ru/layerplan/spec/world-snapshot.schema.json",
  "title": "WorldSnapshot",
  "description": "Единственный выход из L0 Simulation Core. Каждый тик core выдаёт полный слепок мира.",
  "type": "object",
  "required": ["tick", "timestamp", "entities", "tiles"],
  "properties": {
    "tick": {
      "type": "integer",
      "minimum": 0,
      "description": "Номер тика. Монотонно возрастает."
    },
    "timestamp": {
      "type": "number",
      "description": "Unix timestamp (сек) времени генерации snapshot."
    },
    "seed": {
      "type": "integer",
      "description": "Seed для детерминированной симуляции. Фиксируется при инициализации мира."
    },
    "entities": {
      "type": "array",
      "items": { "$ref": "#/definitions/Entity" },
      "description": "Все сущности в мире на данный тик."
    },
    "tiles": {
      "type": "object",
      "patternProperties": {
        "^\\d+,\\d+$": { "$ref": "#/definitions/TileState" }
      },
      "description": "Состояние тайлов карты. Ключ: 'x,y'."
    },
    "economy": {
      "$ref": "economy-report.schema.json",
      "description": "Заполняется L1. null если экономика отключена."
    },
    "routes": {
      "type": "array",
      "items": { "$ref": "#/definitions/RouteSnapshot" },
      "description": "Заполняется L2. null если маршрутизация отключена."
    },
    "meta": {
      "type": "object",
      "properties": {
        "tick_duration_ms": { "type": "number", "description": "Сколько времени занял тик (ms)" },
        "layer_timing": {
          "type": "object",
          "description": "Время выполнения каждого слоя (ms)",
          "properties": {
            "l0_core": { "type": "number" },
            "l1_economy": { "type": "number" },
            "l2_routing": { "type": "number" }
          }
        }
      }
    }
  },
  "definitions": {
    "Entity": {
      "type": "object",
      "required": ["id", "components"],
      "properties": {
        "id": { "type": "string", "pattern": "^[a-f0-9\\-]{36}$", "description": "UUIDv4" },
        "components": {
          "type": "object",
          "properties": {
            "position": { "$ref": "#/definitions/Position" },
            "cargo_hold": { "$ref": "#/definitions/CargoHold" },
            "speed": { "$ref": "#/definitions/Speed" },
            "route": { "$ref": "#/definitions/RouteComponent" },
            "health": { "$ref": "#/definitions/Health" },
            "production": { "$ref": "#/definitions/Production" }
          },
          "minProperties": 1
        }
      }
    },
    "Position": {
      "type": "object",
      "properties": {
        "tile": {
          "type": "array",
          "items": { "type": "integer" },
          "minItems": 2,
          "maxItems": 2,
          "description": "Координаты тайла [x, y]"
        },
        "offset": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "Смещение внутри тайла 0.0–1.0"
        }
      }
    },
    "CargoHold": {
      "type": "object",
      "properties": {
        "capacity": { "type": "number", "minimum": 0 },
        "contents": {
          "type": "object",
          "patternProperties": {
            "^[a-z_]+$": { "type": "number", "minimum": 0 }
          },
          "description": "map[ResourceType → количество]"
        }
      }
    },
    "Speed": {
      "type": "object",
      "properties": {
        "base": { "type": "number", "minimum": 0, "description": "Базовая скорость (тайлов/тик)" },
        "current": { "type": "number", "minimum": 0, "description": "Текущая скорость с учётом загрузки и износа" },
        "modifiers": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "source": { "type": "string", "description": "Причина модификатора: 'cargo', 'maintenance', 'congestion'" },
              "multiplier": { "type": "number", "description": "Множитель скорости. 0.8 = -20%" }
            }
          }
        }
      }
    },
    "RouteComponent": {
      "type": "object",
      "properties": {
        "path": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Список node_id маршрута от A до B"
        },
        "current_node_index": { "type": "integer", "minimum": 0 },
        "status": {
          "type": "string",
          "enum": ["moving", "loading", "unloading", "waiting", "deadlocked", "broken"]
        }
      }
    },
    "Health": {
      "type": "object",
      "properties": {
        "durability": { "type": "number", "minimum": 0, "maximum": 1, "description": "1.0 = новый, 0.0 = уничтожен" },
        "breakdown_ticks": { "type": "integer", "minimum": 0, "description": "Тиков до ремонта. 0 = исправен." }
      }
    },
    "Production": {
      "type": "object",
      "properties": {
        "type": { "type": "string", "description": "Тип производства: 'mine', 'farm', 'factory', 'refinery'" },
        "input": {
          "type": "object",
          "patternProperties": { "^[a-z_]+$": { "type": "number" } },
          "description": "Потребляемые ресурсы за тик"
        },
        "output": {
          "type": "object",
          "patternProperties": { "^[a-z_]+$": { "type": "number" } },
          "description": "Производимые ресурсы за тик"
        },
        "stored": {
          "type": "object",
          "patternProperties": { "^[a-z_]+$": { "type": "number" } },
          "description": "Текущие запасы"
        }
      }
    },
    "TileState": {
      "type": "object",
      "properties": {
        "terrain": {
          "type": "string",
          "enum": ["land", "water", "road", "rail", "station", "building", "mountain", "forest"]
        },
        "owner": { "type": "string", "description": "ID игрока или null" },
        "building": {
          "type": "object",
          "properties": {
            "type": { "type": "string" },
            "level": { "type": "integer", "minimum": 1 }
          }
        }
      },
      "required": ["terrain"]
    },
    "RouteSnapshot": {
      "type": "object",
      "properties": {
        "vehicle_id": { "type": "string" },
        "path": { "type": "array", "items": { "type": "string" } },
        "status": { "type": "string", "enum": ["active", "waiting", "deadlocked"] }
      },
      "required": ["vehicle_id", "status"]
    }
  }
}
