{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Map metadata",
  "type": "object",
  "properties": {
    "schemaVersion": {
      "type": "number",
      "const": 1,
      "description": "Version of this file's layout. It changes only when the layout does."
    },
    "id": {
      "type": "string",
      "pattern": "^[a-z-]+$",
      "description": "Short id of the world, also its folder name under `data/maps`."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "Map name shown in the game's server browser."
    },
    "world": {
      "type": "string",
      "minLength": 1,
      "description": "Name of the world (level) the map belongs to."
    },
    "gameBuild": {
      "type": "string",
      "description": "Steam build id the data was extracted from."
    },
    "units": {
      "type": "string",
      "const": "meters",
      "description": "Unit of every distance in the file."
    },
    "bounds": {
      "type": "object",
      "properties": {
        "min": {
          "type": "array",
          "prefixItems": [
            {
              "type": "number"
            },
            {
              "type": "number"
            }
          ],
          "items": false,
          "minItems": 2,
          "maxItems": 2,
          "description": "Minimum corner: [x, y] in meters."
        },
        "max": {
          "type": "array",
          "prefixItems": [
            {
              "type": "number"
            },
            {
              "type": "number"
            }
          ],
          "items": false,
          "minItems": 2,
          "maxItems": 2,
          "description": "Maximum corner: [x, y] in meters."
        }
      },
      "required": [
        "min",
        "max"
      ],
      "additionalProperties": false,
      "description": "Area the map covers, as world X and Y. Pixel (0, 0) of the image is the minimum corner."
    },
    "image": {
      "type": "object",
      "properties": {
        "width": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991,
          "description": "Image width in pixels."
        },
        "height": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991,
          "description": "Image height in pixels."
        },
        "metersPerPixel": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "World meters per image pixel. `pixel = (world - bounds.min) / metersPerPixel`; rows increase with world Y."
        },
        "padding": {
          "type": "object",
          "properties": {
            "right": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991,
              "description": "Padding columns on the right edge."
            },
            "bottom": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991,
              "description": "Padding rows on the bottom edge."
            }
          },
          "required": [
            "right",
            "bottom"
          ],
          "additionalProperties": false,
          "description": "Pixels past the bounds on the right and bottom edges. They hold padding, not map."
        }
      },
      "required": [
        "width",
        "height",
        "metersPerPixel",
        "padding"
      ],
      "additionalProperties": false,
      "description": "The single full-size map image the tiles were cut from."
    },
    "tiles": {
      "type": "object",
      "properties": {
        "size": {
          "type": "number",
          "const": 256,
          "description": "Tile size in pixels (tiles are square)."
        },
        "minZoom": {
          "type": "number",
          "const": 0,
          "description": "Lowest zoom level (one tile covers the whole map)."
        },
        "maxZoom": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991,
          "description": "At this zoom the tiles cover the full image at 1:1 (`image.width = 256 * 2^maxZoom`)."
        },
        "format": {
          "type": "string",
          "const": "webp",
          "description": "Tile image format."
        },
        "urlTemplate": {
          "type": "string",
          "description": "Path of a tile inside the release's map folder; replace `{z}`, `{x}` and `{y}`."
        }
      },
      "required": [
        "size",
        "minZoom",
        "maxZoom",
        "format",
        "urlTemplate"
      ],
      "additionalProperties": false,
      "description": "The tile pyramid published as a release asset."
    }
  },
  "required": [
    "schemaVersion",
    "id",
    "name",
    "world",
    "gameBuild",
    "units",
    "bounds",
    "image",
    "tiles"
  ],
  "additionalProperties": false,
  "description": "Metadata that places a world's map image and tiles in world coordinates. All distances are meters."
}
