{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://marcallabs.co.uk/adventure-schema.json",
  "title": "Castle Quest Mini Adventure",
  "description": "One Mini Adventure for Marcal Labs: a story tying 2 to 5 puzzles together. Upload as adv/<id>.json with the puzzle checker. Rules this schema cannot express: (1) the characters < and > may not appear anywhere in the file; (2) every puzzle named must already be on the website (puz/<id>.json) and each may appear only once; (3) a 'place' must be one of the places that puzzle allows; (4) only one puzzle may be in the 'cellar' (fixed with place, or because the puzzle allows only the cellar); (5) the file must be no bigger than 64 KB. Check files at https://marcallabs.co.uk/puzzle-checker.html.",
  "type": "object",
  "required": ["id", "title", "story", "puzzles"],
  "additionalProperties": false,
  "properties": {
    "id": { "type": "string", "pattern": "^[a-z0-9-]{1,40}$", "description": "Unique short name: small letters, numbers and dashes. Also the file name: <id>.json." },
    "title": { "type": "string", "minLength": 1, "maxLength": 60, "description": "Shown on the list of Mini Adventures and the village notice board." },
    "story": { "type": "string", "minLength": 1, "maxLength": 800, "description": "What is going on. Shown on the list and the notice board. Do not name the village: it is made fresh each time." },
    "minLevel": { "type": "integer", "minimum": 1, "maximum": 20, "description": "The level the adventure is meant for. Players below it are warned but can still play. Default 1." },
    "puzzles": {
      "type": "array", "minItems": 2, "maxItems": 5,
      "description": "The tasks on the notice board, in this order (players may do them in any order).",
      "items": {
        "oneOf": [
          { "type": "string", "pattern": "^[a-z0-9-]{1,40}$", "description": "A puzzle's id. The game picks one of the puzzle's places." },
          { "type": "object", "required": ["puzzle"], "additionalProperties": false,
            "properties": {
              "puzzle": { "type": "string", "pattern": "^[a-z0-9-]{1,40}$", "description": "A puzzle's id." },
              "place": { "enum": ["dungeon", "mine", "cave", "keep", "cellar"], "description": "Where this puzzle happens: 'cellar' is the inn cellar in the village; the others are a few squares out in the wilds." }
            } }
        ]
      }
    },
    "reward": {
      "type": "object", "additionalProperties": false, "description": "For finishing every task (each puzzle also gives its own reward).",
      "properties": {
        "gold": { "type": "integer", "minimum": 0, "maximum": 1000 },
        "xp": { "type": "integer", "minimum": 0, "maximum": 600 },
        "magic": { "type": "boolean", "description": "true: a magic prize." },
        "text": { "type": "string", "minLength": 1, "maxLength": 400 }
      }
    }
  }
}
