{
  "$id": "https://dnd-gm.local/schemas/adventure-contract.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "contractVersion",
    "adventureId",
    "title",
    "genre",
    "tone",
    "premise",
    "mapId",
    "startSceneId",
    "facts",
    "items",
    "npcs",
    "clocks",
    "scenes"
  ],
  "properties": {
    "contractVersion": {
      "const": "1.0.0"
    },
    "adventureId": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "genre": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "tone": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "premise": {
      "type": "string",
      "minLength": 12
    },
    "mapId": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "startSceneId": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "facts": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "statement",
          "visibility",
          "initiallyKnownBy"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "statement": {
            "type": "string",
            "minLength": 1
          },
          "visibility": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "public"
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "party"
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "branchId"
                ],
                "properties": {
                  "kind": {
                    "const": "branch"
                  },
                  "branchId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "playerIds"
                ],
                "properties": {
                  "kind": {
                    "const": "players"
                  },
                  "playerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "uniqueItems": true
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "gm"
                  }
                }
              }
            ]
          },
          "initiallyKnownBy": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          }
        }
      }
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "locationId",
          "grants",
          "consumable",
          "visibility"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "locationId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "grants": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "consumable": {
            "type": "boolean"
          },
          "visibility": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "public"
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "party"
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "branchId"
                ],
                "properties": {
                  "kind": {
                    "const": "branch"
                  },
                  "branchId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "playerIds"
                ],
                "properties": {
                  "kind": {
                    "const": "players"
                  },
                  "playerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "uniqueItems": true
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "gm"
                  }
                }
              }
            ]
          }
        }
      }
    },
    "npcs": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "locationId",
          "hitPoints",
          "visibility"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "locationId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "hitPoints": {
            "type": "integer",
            "minimum": 1
          },
          "visibility": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "public"
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "party"
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "branchId"
                ],
                "properties": {
                  "kind": {
                    "const": "branch"
                  },
                  "branchId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "playerIds"
                ],
                "properties": {
                  "kind": {
                    "const": "players"
                  },
                  "playerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "uniqueItems": true
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "const": "gm"
                  }
                }
              }
            ]
          }
        }
      }
    },
    "clocks": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "max",
          "initial"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "max": {
            "type": "integer",
            "minimum": 1
          },
          "initial": {
            "type": "integer",
            "minimum": 0
          }
        }
      }
    },
    "scenes": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "title",
          "locationIds",
          "entry",
          "objective",
          "conflict",
          "allowedImprovisation",
          "forbiddenCanonicalChanges",
          "ending"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "locationIds": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "uniqueItems": true
          },
          "entry": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind"
                  ],
                  "properties": {
                    "kind": {
                      "const": "always"
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "clockId",
                    "value"
                  ],
                  "properties": {
                    "kind": {
                      "const": "clock_at_least"
                    },
                    "clockId": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 128
                    },
                    "value": {
                      "type": "integer",
                      "minimum": 0
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "factId"
                  ],
                  "properties": {
                    "kind": {
                      "const": "fact_known"
                    },
                    "factId": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 128
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "locationId"
                  ],
                  "properties": {
                    "kind": {
                      "const": "actor_at"
                    },
                    "locationId": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 128
                    }
                  }
                }
              ]
            }
          },
          "objective": {
            "type": "string",
            "minLength": 1
          },
          "conflict": {
            "type": "string",
            "minLength": 1
          },
          "allowedImprovisation": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "forbiddenCanonicalChanges": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "successNextSceneId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "failForwardNextSceneId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "ending": {
            "type": "boolean"
          }
        }
      }
    }
  }
}
