{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "TacticMesh pack v1",
  "description": "Structure only. The shared semantic validator additionally checks IDs, XI/GK membership, roles, local asset paths and compatibility.",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "format": {
      "const": "tacticmesh-pack"
    },
    "formatVersion": {
      "const": "1.0.0"
    },
    "packId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$"
    },
    "packRevision": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 160
    },
    "author": {
      "type": "string",
      "maxLength": 160
    },
    "createdAt": {
      "type": "string",
      "maxLength": 40
    },
    "engineCompatibility": {
      "const": "tf-v1"
    },
    "attributeModelVersion": {
      "const": "tm-attributes-1"
    },
    "defaultsProfileVersion": {
      "const": "tm-role-1"
    },
    "provenance": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "category": {
          "enum": [
            "fictional",
            "estimated",
            "mixed",
            "sourced"
          ]
        },
        "sourceDate": {
          "type": "string",
          "maxLength": 40
        },
        "references": {
          "type": "array",
          "maxItems": 32,
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048
          }
        },
        "notes": {
          "type": "string",
          "maxLength": 2000
        }
      },
      "required": [
        "category"
      ]
    },
    "dataLicense": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "assetLicenses": {
      "type": "array",
      "maxItems": 1024,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "path": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^assets/(crests|faces)/[a-zA-Z0-9_. -]+\\.([pP][nN][gG]|[jJ][pP][eE]?[gG]|[wW][eE][bB][pP])$"
          },
          "license": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "attribution": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "path",
          "license"
        ]
      }
    },
    "teams": {
      "type": "array",
      "minItems": 1,
      "maxItems": 16,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "abbreviation": {
            "type": "string",
            "maxLength": 12
          },
          "season": {
            "type": "string",
            "maxLength": 80
          },
          "crest": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^assets/(crests|faces)/[a-zA-Z0-9_. -]+\\.([pP][nN][gG]|[jJ][pP][eE]?[gG]|[wW][eE][bB][pP])$"
          },
          "kits": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "home": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "primary": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  },
                  "secondary": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  }
                },
                "required": [
                  "primary",
                  "secondary"
                ]
              },
              "away": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "primary": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  },
                  "secondary": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  }
                },
                "required": [
                  "primary",
                  "secondary"
                ]
              }
            },
            "required": []
          },
          "players": {
            "type": "array",
            "minItems": 11,
            "maxItems": 30,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "id": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$"
                },
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 160
                },
                "number": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 99
                },
                "positionFamily": {
                  "enum": [
                    "GK",
                    "DEF",
                    "MID",
                    "FWD"
                  ]
                },
                "roles": {
                  "type": "array",
                  "minItems": 1,
                  "maxItems": 25,
                  "items": {
                    "enum": [
                      "GK",
                      "RB",
                      "LB",
                      "RCB",
                      "LCB",
                      "CB",
                      "DM",
                      "RDM",
                      "LDM",
                      "RCM",
                      "LCM",
                      "CM",
                      "AM",
                      "RAM",
                      "LAM",
                      "RM",
                      "LM",
                      "RWB",
                      "LWB",
                      "RW",
                      "LW",
                      "ST",
                      "DEF",
                      "MID",
                      "FWD"
                    ]
                  }
                },
                "preferredRole": {
                  "enum": [
                    "GK",
                    "RB",
                    "LB",
                    "RCB",
                    "LCB",
                    "CB",
                    "DM",
                    "RDM",
                    "LDM",
                    "RCM",
                    "LCM",
                    "CM",
                    "AM",
                    "RAM",
                    "LAM",
                    "RM",
                    "LM",
                    "RWB",
                    "LWB",
                    "RW",
                    "LW",
                    "ST",
                    "DEF",
                    "MID",
                    "FWD"
                  ]
                },
                "preferredFoot": {
                  "enum": [
                    "left",
                    "right"
                  ]
                },
                "height": {
                  "type": "number",
                  "minimum": 1.4,
                  "maximum": 2.2
                },
                "weight": {
                  "type": "number",
                  "minimum": 40,
                  "maximum": 130
                },
                "attributes": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "acceleration": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "sprintSpeed": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "agility": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "turning": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "balance": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "strength": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "stamina": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "jumping": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "reach": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "recoverySpeed": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "firstTouch": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "shortPassing": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "longPassing": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "throughBalls": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "crossing": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "shooting": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "finishing": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "heading": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "dribbling": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "ballCarrying": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "tackling": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "interception": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "weakFoot": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "awareness": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "vision": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "anticipation": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "decisionMaking": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "composure": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "positioning": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "teamwork": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "creativity": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "concentration": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "discipline": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "aggression": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "workRate": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "offBallIntelligence": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "handling": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "reflexes": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "catching": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "parrying": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "diving": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "oneOnOne": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "aerialCommand": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "sweeping": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "throwing": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    },
                    "kicking": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    }
                  },
                  "required": []
                },
                "traits": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "riskAppetite": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "directness": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "patience": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "selfishness": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "roaming": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "pressingEnthusiasm": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "receiveToFeet": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "attackSpace": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "earlyCrossing": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "dribbleTendency": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "longShotTendency": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "conservativePassing": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "switchPlay": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "weakFootUse": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    }
                  },
                  "required": []
                },
                "portrait": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "pattern": "^assets/(crests|faces)/[a-zA-Z0-9_. -]+\\.([pP][nN][gG]|[jJ][pP][eE]?[gG]|[wW][eE][bB][pP])$"
                },
                "appearance": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "skinColor": {
                      "type": "string",
                      "pattern": "^#[0-9a-fA-F]{6}$"
                    },
                    "hairColor": {
                      "type": "string",
                      "pattern": "^#[0-9a-fA-F]{6}$"
                    },
                    "hairStyle": {
                      "enum": [
                        "short",
                        "bald",
                        "crop"
                      ]
                    }
                  },
                  "required": []
                }
              },
              "required": [
                "id",
                "name",
                "number",
                "positionFamily"
              ]
            }
          },
          "formation": {
            "enum": [
              "4-3-3",
              "4-2-3-1",
              "4-4-2",
              "3-4-2-1",
              "3-5-2"
            ]
          },
          "lineup": {
            "type": "array",
            "minItems": 11,
            "maxItems": 11,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$"
            }
          },
          "tacticalPreset": {
            "enum": [
              "balanced",
              "patient",
              "direct"
            ]
          },
          "tacticalOverrides": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "width": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "attackingWidth": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "defensiveWidth": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "defensiveLine": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "pressingIntensity": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "engagementLine": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "compactness": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "tempo": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "buildupRisk": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "passingDirectness": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "counterattack": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "counterpress": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "crossingFrequency": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "overlapPreference": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "centralOverload": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "goalkeeperDistribution": {
                "enum": [
                  "short",
                  "mixed",
                  "long"
                ]
              },
              "markingBias": {
                "enum": [
                  "zonal",
                  "man",
                  "mixed"
                ]
              },
              "timeManagement": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            },
            "required": []
          }
        },
        "required": [
          "id",
          "name",
          "players",
          "formation"
        ]
      }
    }
  },
  "required": [
    "format",
    "formatVersion",
    "packId",
    "packRevision",
    "title",
    "engineCompatibility",
    "attributeModelVersion",
    "defaultsProfileVersion",
    "provenance",
    "dataLicense",
    "teams"
  ]
}
