{
  "manifest": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://www.gamearter.com/api/publishing/schema#manifest",
    "title": "GameArter manifest.json v0.2",
    "type": "object",
    "required": [
      "standard",
      "slug",
      "name",
      "version",
      "languages",
      "genres",
      "min_age",
      "platforms",
      "game",
      "media",
      "gameplay",
      "content_descriptors",
      "declarations"
    ],
    "properties": {
      "standard": {
        "const": "0.2"
      },
      "slug": {
        "type": "string",
        "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
        "minLength": 2,
        "maxLength": 60
      },
      "name": {
        "type": "string",
        "minLength": 1,
        "maxLength": 40
      },
      "languages": {
        "type": "array",
        "items": {
          "type": "string",
          "pattern": "^[a-z]{2}(-[A-Z]{2})?$"
        },
        "uniqueItems": true,
        "contains": {
          "const": "en"
        }
      },
      "genres": {
        "type": "array",
        "description": "Genres, main genre first.",
        "items": {
          "enum": [
            "action",
            "adventure",
            "arcade",
            "board",
            "card",
            "casino",
            "casual",
            "educational",
            "music",
            "puzzle",
            "racing",
            "role-playing",
            "simulation",
            "sports",
            "strategy",
            "trivia",
            "word"
          ]
        },
        "minItems": 1,
        "maxItems": 3,
        "uniqueItems": true
      },
      "tags": {
        "type": "array",
        "description": "Optional tags, most relevant first.",
        "items": {
          "enum": [
            "shooter",
            "fps",
            "sniper",
            "fighting",
            "platformer",
            "runner",
            "parkour",
            "battle-royale",
            "io",
            "clicker",
            "idle",
            "merge",
            "match-3",
            "hidden-object",
            "physics",
            "tower-defense",
            "survival",
            "sandbox",
            "building",
            "crafting",
            "management",
            "tycoon",
            "escape-room",
            "stealth",
            "roguelike",
            "bullet-hell",
            "drawing",
            "coloring",
            "dress-up",
            "makeover",
            "cooking",
            "parking",
            "drifting",
            "stunts",
            "jigsaw",
            "mahjong",
            "solitaire",
            "chess",
            "snake",
            "upgrades",
            "animals",
            "horses",
            "dinosaurs",
            "cars",
            "trucks",
            "motorbikes",
            "bicycles",
            "flight",
            "trains",
            "naval",
            "tanks",
            "military",
            "police",
            "zombies",
            "monsters",
            "robots",
            "space",
            "sci-fi",
            "fantasy",
            "medieval",
            "pirates",
            "ninja",
            "stickman",
            "superhero",
            "horror",
            "christmas",
            "halloween",
            "food",
            "fashion",
            "farming",
            "city",
            "doctor",
            "soccer",
            "basketball",
            "american-football",
            "tennis",
            "golf",
            "hockey",
            "baseball",
            "boxing",
            "skiing",
            "fishing",
            "hunting",
            "billiards",
            "bowling",
            "3d",
            "2d",
            "pixel-graphics",
            "low-poly",
            "cartoon",
            "cute",
            "funny",
            "relaxing",
            "difficult",
            "math",
            "language",
            "geography",
            "science",
            "typing"
          ]
        },
        "maxItems": 8,
        "uniqueItems": true
      },
      "min_age": {
        "enum": [
          3,
          7,
          12,
          16,
          18
        ],
        "description": "Recommended minimum age of players."
      },
      "pegi": {
        "enum": [
          3,
          7,
          12,
          16,
          18
        ],
        "deprecated": true,
        "description": "Old name of min_age, still accepted."
      },
      "platforms": {
        "type": "object",
        "required": [
          "desktop",
          "mobile"
        ],
        "properties": {
          "desktop": {
            "type": "boolean"
          },
          "mobile": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "orientation": {
        "enum": [
          "landscape",
          "portrait",
          "any"
        ]
      },
      "game": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "enum": [
              "hosted",
              "external"
            ]
          },
          "engine": {
            "enum": [
              "html5",
              "unity"
            ]
          },
          "build_folder": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._-]+$"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://"
          }
        },
        "oneOf": [
          {
            "properties": {
              "type": {
                "const": "hosted"
              }
            },
            "required": [
              "engine"
            ]
          },
          {
            "properties": {
              "type": {
                "const": "external"
              }
            },
            "required": [
              "url"
            ]
          }
        ]
      },
      "media": {
        "type": "object",
        "required": [
          "cover_4x3",
          "wide_16x9"
        ],
        "properties": {
          "cover_4x3": {
            "type": "string",
            "pattern": "^media/cover-4x3\\.(png|jpe?g|webp)$",
            "description": "4:3 – Main game tile in the catalog (resized to 350×263 and 230×172) and the Gameplayer cover (460×344)."
          },
          "wide_16x9": {
            "type": "string",
            "pattern": "^media/wide-16x9\\.(png|jpe?g|webp)$",
            "description": "16:9 – Social share image (cropped to 1200×630), banners and featured slots."
          },
          "square_1x1": {
            "type": "string",
            "pattern": "^media/square-1x1\\.(png|jpe?g|webp)$",
            "description": "1:1 – Icon-style listings and mobile shelves."
          },
          "portrait_2x3": {
            "type": "string",
            "pattern": "^media/portrait-2x3\\.(png|jpe?g|webp)$",
            "description": "2:3 – Vertical cards on mobile."
          },
          "screenshots": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^media/screenshot-[1-5]\\.(png|jpe?g|webp)$"
            },
            "minItems": 3,
            "maxItems": 5,
            "description": "Unity WebGL only. 16:9 – Shown on the loading screen of Unity WebGL games."
          },
          "preview_video": {
            "const": "media/preview.mp4"
          },
          "youtube": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://(www\\.)?(youtube\\.com|youtu\\.be)/"
          }
        }
      },
      "theme": {
        "type": "object",
        "properties": {
          "primary": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          },
          "background": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          }
        },
        "additionalProperties": false
      },
      "version": {
        "type": "string",
        "pattern": "^\\d+\\.\\d+(\\.\\d+)?$"
      },
      "changelog": {
        "type": "string",
        "maxLength": 1000
      },
      "gameplay": {
        "type": "object",
        "required": [
          "player_modes",
          "session_length",
          "audience",
          "saves"
        ],
        "properties": {
          "player_modes": {
            "type": "array",
            "items": {
              "enum": [
                "single",
                "local_multiplayer",
                "online_multiplayer"
              ]
            },
            "minItems": 1,
            "uniqueItems": true
          },
          "max_players": {
            "type": "integer",
            "minimum": 1
          },
          "session_length": {
            "enum": [
              "short",
              "medium",
              "long"
            ]
          },
          "audience": {
            "enum": [
              "kids",
              "teens",
              "everyone",
              "adults"
            ]
          },
          "saves": {
            "enum": [
              "none",
              "browser"
            ]
          }
        },
        "additionalProperties": false
      },
      "content_descriptors": {
        "type": "array",
        "items": {
          "enum": [
            "violence",
            "bad_language",
            "fear",
            "gambling",
            "sex",
            "drugs",
            "discrimination",
            "in_game_purchases"
          ]
        },
        "uniqueItems": true
      },
      "declarations": {
        "type": "object",
        "required": [
          "owns_rights",
          "no_personal_data",
          "no_third_party_tracking"
        ],
        "properties": {
          "owns_rights": {
            "const": true,
            "description": "You own or have a license for everything in the game: code, graphics, music, sounds and fonts. No third-party IP (characters, brands, names) without permission."
          },
          "no_personal_data": {
            "const": true,
            "description": "The game itself does not collect personal data (names, e-mails, location, device identifiers)."
          },
          "no_third_party_tracking": {
            "const": true,
            "description": "The game contains no own tracking, analytics or advertising code of third parties."
          }
        }
      },
      "credits": {
        "type": "array",
        "items": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "maxItems": 30
      }
    }
  },
  "texts": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://www.gamearter.com/api/publishing/schema#texts",
    "title": "GameArter texts.json v0.2 (English)",
    "type": "object",
    "required": [
      "title",
      "meta_desc",
      "controls",
      "description"
    ],
    "properties": {
      "title": {
        "type": "string",
        "minLength": 1,
        "description": "plain: SEO title tag. Starts with the game name, then a short natural description of the game type (e.g. \"Turbo Drift - Neon Street Racing Game\"). No keyword stuffing.",
        "maxLength": 60
      },
      "meta_desc": {
        "type": "string",
        "minLength": 1,
        "description": "plain: Meta description. One or two natural sentences saying what the player does and why it is fun. Mentions the game name.",
        "maxLength": 160
      },
      "controls": {
        "type": "string",
        "minLength": 1,
        "description": "controls: Complete control mapping, one control per line in the format `*key* = action`, including touch controls for mobile games (see Controls format)."
      },
      "description": {
        "type": "string",
        "minLength": 1,
        "description": "html: Detailed description of the game – the source for every other text about the game (see What the description must cover). Paragraphs (<p>) with <h2> subheadings, lists allowed."
      }
    }
  }
}