{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://minecraftmetascript.github.io/mms/mms.schema.json",
  "title": "MMS project (mms.json)",
  "type": "object",
  "properties": {
    "$schema": {
      "description": "The JSON Schema for this file.",
      "type": "string",
      "default": "https://minecraftmetascript.github.io/mms/mms.schema.json"
    },
    "description": {
      "description": "The data pack's description, shown in the game's pack list (`pack.mcmeta`).",
      "markdownDescription": "The data pack's description, shown in the game's pack list (`pack.mcmeta`).",
      "type": "string",
      "default": "Built with MMS"
    },
    "icon": {
      "description": "A PNG in the project that becomes `pack.png` in both the data pack and the resource pack.",
      "markdownDescription": "A PNG in the project that becomes `pack.png` in both the data pack and the resource pack.",
      "type": "string",
      "pattern": "\\.[pP][nN][gG]$",
      "patternErrorMessage": "The icon must be a .png file.",
      "examples": [
        "icon.png"
      ]
    },
    "lint": {
      "description": "Lint rule severities by rule id. Each rule can be `error`, `warning`, `info`, `hint` or `off`.",
      "markdownDescription": "Lint rule severities by rule id. Each rule can be `error`, `warning`, `info`, `hint` or `off`.",
      "type": "object",
      "properties": {
        "accidental-markup": {
          "description": "A style mark in text that is never closed, such as the `*` of \"5 * 3\", so it is written as the character itself. The fix puts a backslash before it, which says so.\n\nDefault: `hint`.",
          "markdownDescription": "A style mark in text that is never closed, such as the `*` of \"5 * 3\", so it is written as the character itself. The fix puts a backslash before it, which says so.\n\nDefault: `hint`.",
          "$ref": "#/definitions/severity"
        },
        "book-page-overflow": {
          "description": "A Book page with more text than the book screen shows: 14 lines of about 19 characters. The game cuts the rest off. Widths are measured with the vanilla font, so text outside ASCII is a close guess.\n\nDefault: `warning`.",
          "markdownDescription": "A Book page with more text than the book screen shows: 14 lines of about 19 characters. The game cuts the rest off. Widths are measured with the vanilla font, so text outside ASCII is a close guess.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "constant-expression": {
          "description": "An arithmetic expression of number literals can be written as its value.\n\nDefault: `hint`.",
          "markdownDescription": "An arithmetic expression of number literals can be written as its value.\n\nDefault: `hint`.",
          "$ref": "#/definitions/severity"
        },
        "custom-item-as-base": {
          "description": "A Book used where the game takes a plain item id, such as a recipe ingredient or an item tag. It stands for written_book there, so any written book matches.\n\nDefault: `hint`.",
          "markdownDescription": "A Book used where the game takes a plain item id, such as a recipe ingredient or an item tag. It stands for written_book there, so any written book matches.\n\nDefault: `hint`.",
          "$ref": "#/definitions/severity"
        },
        "deprecated": {
          "description": "A use of a declaration whose doc comment has a `@deprecated` tag.\n\nDefault: `warning`.",
          "markdownDescription": "A use of a declaration whose doc comment has a `@deprecated` tag.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "external-asset": {
          "description": "An id of a texture, sound or structure in the project's namespace that no Texture, Sound or StructureFile call in the project provides. The pack still loads, but the file must come from another pack.\n\nDefault: `warning`.",
          "markdownDescription": "An id of a texture, sound or structure in the project's namespace that no Texture, Sound or StructureFile call in the project provides. The pack still loads, but the file must come from another pack.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "jigsaw-facing": {
          "description": "A jigsaw block that can never join its target: every jigsaw block with its target name in its pool faces a way it cannot meet. The game turns pieces only about the y axis, so a block facing up joins only one facing down, and a sideways block only a sideways one.\n\nDefault: `warning`.",
          "markdownDescription": "A jigsaw block that can never join its target: every jigsaw block with its target name in its pool faces a way it cannot meet. The game turns pieces only about the y axis, so a block facing up joins only one facing down, and a sideways block only a sideways one.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "jigsaw-fit": {
          "description": "An internal jigsaw block (the block in front of it is inside its own piece, such as an arch mount on a road, or a jigsaw inset by a block by mistake) whose pool has pieces that stick out of the piece however they are turned. The game only places a piece joined at an internal jigsaw wholly inside its parent, so those pieces are never placed there. Height is not checked for terrain_matching pieces.\n\nDefault: `warning`.",
          "markdownDescription": "An internal jigsaw block (the block in front of it is inside its own piece, such as an arch mount on a road, or a jigsaw inset by a block by mistake) whose pool has pieces that stick out of the piece however they are turned. The game only places a piece joined at an internal jigsaw wholly inside its parent, so those pieces are never placed there. Height is not checked for terrain_matching pieces.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "jigsaw-overlap": {
          "description": "A jigsaw block that can never grow when its piece joins a given parent: every piece its pool and the pool's fallback could place there overlaps the parent or the piece itself, however it is turned, and the game never places overlapping pieces. A junction narrower than the roads around it is the usual cause. Only certain cases are reported: every piece involved is a rigid project structure file with a known size and facing, and no pool involved has an empty or feature element.\n\nDefault: `info`.",
          "markdownDescription": "A jigsaw block that can never grow when its piece joins a given parent: every piece its pool and the pool's fallback could place there overlaps the parent or the piece itself, however it is turned, and the game never places overlapping pieces. A junction narrower than the roads around it is the usual cause. Only certain cases are reported: every piece involved is a rigid project structure file with a known size and facing, and no pool involved has an empty or feature element.\n\nDefault: `info`.",
          "$ref": "#/definitions/severity"
        },
        "jigsaw-unknown-name": {
          "description": "A jigsaw block in a structure file that StructureFile(\"...\") includes whose name or target is in a namespace with JigsawHole declarations, but is not one of them: most likely a typo made in the game's jigsaw screen. The quick fix declares it. Projects that declare no JigsawHole in a namespace are not checked there.\n\nDefault: `warning`.",
          "markdownDescription": "A jigsaw block in a structure file that StructureFile(\"...\") includes whose name or target is in a namespace with JigsawHole declarations, but is not one of them: most likely a typo made in the game's jigsaw screen. The quick fix declares it. Projects that declare no JigsawHole in a namespace are not checked there.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "jigsaw-unknown-pool": {
          "description": "A jigsaw block in a structure file that StructureFile(\"...\") includes draws from a pool in the project's namespace that no TemplatePool declares. The game skips the jigsaw, so the structure stops growing there. The quick fix declares the pool.\n\nDefault: `warning`.",
          "markdownDescription": "A jigsaw block in a structure file that StructureFile(\"...\") includes draws from a pool in the project's namespace that no TemplatePool declares. The game skips the jigsaw, so the structure stops growing there. The quick fix declares the pool.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "jigsaw-unreachable-target": {
          "description": "A jigsaw block whose target no piece of its pool can join: none of the pool's structure files has a jigsaw block with that name, or the pool has no pieces. Only pools whose pieces are all the project's own structure files are checked.\n\nDefault: `warning`.",
          "markdownDescription": "A jigsaw block whose target no piece of its pool can join: none of the pool's structure files has a jigsaw block with that name, or the pool has no pieces. Only pools whose pieces are all the project's own structure files are checked.\n\nDefault: `warning`.",
          "$ref": "#/definitions/severity"
        },
        "overrides-vanilla": {
          "description": "A declaration in the minecraft namespace replaces the vanilla resource with the same id.\n\nDefault: `info`.",
          "markdownDescription": "A declaration in the minecraft namespace replaces the vanilla resource with the same id.\n\nDefault: `info`.",
          "$ref": "#/definitions/severity"
        },
        "quoted-name": {
          "description": "An id or enum name in quotes can be written bare: `minecraft:stone` or `stone` rather than \"minecraft:stone\".\n\nDefault: `hint`.",
          "markdownDescription": "An id or enum name in quotes can be written bare: `minecraft:stone` or `stone` rather than \"minecraft:stone\".\n\nDefault: `hint`.",
          "$ref": "#/definitions/severity"
        },
        "redundant-namespace": {
          "description": "A `minecraft:` prefix that can be dropped: `stone` means `minecraft:stone` unless the project declares its own `stone`.\n\nDefault: `hint`.",
          "markdownDescription": "A `minecraft:` prefix that can be dropped: `stone` means `minecraft:stone` unless the project declares its own `stone`.\n\nDefault: `hint`.",
          "$ref": "#/definitions/severity"
        },
        "unused": {
          "description": "A worldgen piece, predicate or item modifier that nothing in the project references, so the game never uses it, or a const, Template, Type or Blueprint that nothing names. A TemplatePool counts as used when a jigsaw block in one of the project's structure files draws from it.\n\nDefault: `hint`.",
          "markdownDescription": "A worldgen piece, predicate or item modifier that nothing in the project references, so the game never uses it, or a const, Template, Type or Blueprint that nothing names. A TemplatePool counts as used when a jigsaw block in one of the project's structure files draws from it.\n\nDefault: `hint`.",
          "$ref": "#/definitions/severity"
        },
        "unused-asset": {
          "description": "A .png, .ogg or .nbt file in the project that no Texture, Sound or StructureFile call and no `icon` uses, so the packs leave it out. It is reported on the file itself (in VS Code's Problems panel, by `mms check`, and in the web editor's asset list), and not while the project has errors.\n\nDefault: `info`.",
          "markdownDescription": "A .png, .ogg or .nbt file in the project that no Texture, Sound or StructureFile call and no `icon` uses, so the packs leave it out. It is reported on the file itself (in VS Code's Problems panel, by `mms check`, and in the web editor's asset list), and not while the project has errors.\n\nDefault: `info`.",
          "$ref": "#/definitions/severity"
        },
        "use-shorthand": {
          "description": "An object literal that has a shorter MMS form: an item entry as its id, `1..3` for a uniform provider or bounds, `diamond * 4` for a stack, a trigger call for a criterion, and `\u0026\u0026`, `||` and `!` for conditions.\n\nDefault: `hint`.",
          "markdownDescription": "An object literal that has a shorter MMS form: an item entry as its id, `1..3` for a uniform provider or bounds, `diamond * 4` for a stack, a trigger call for a criterion, and `\u0026\u0026`, `||` and `!` for conditions.\n\nDefault: `hint`.",
          "$ref": "#/definitions/severity"
        }
      },
      "additionalProperties": false
    },
    "namespace": {
      "description": "The default namespace for files without a `Namespace` declaration.",
      "markdownDescription": "The default namespace for files without a `Namespace` declaration.",
      "type": "string",
      "pattern": "^[a-z0-9_.\\-]+$",
      "patternErrorMessage": "A namespace is lowercase letters, digits, '_', '-' or '.'.",
      "default": "mms"
    },
    "output": {
      "description": "The folder `mms build` writes the data pack to, relative to the project.",
      "markdownDescription": "The folder `mms build` writes the data pack to, relative to the project.",
      "type": "string",
      "default": "build"
    },
    "resourcePack": {
      "description": "Settings for the resource pack `mms build` writes when the project uses `Texture`, `Sound` or other resource pack declarations.",
      "markdownDescription": "Settings for the resource pack `mms build` writes when the project uses `Texture`, `Sound` or other resource pack declarations.",
      "type": "object",
      "properties": {
        "description": {
          "description": "The resource pack's description. The default is the data pack's `description`.",
          "markdownDescription": "The resource pack's description. The default is the data pack's `description`.",
          "type": "string"
        },
        "output": {
          "description": "The folder `mms build` writes the resource pack to, relative to the project. The default is the data pack's `output` with `-resources` appended.",
          "markdownDescription": "The folder `mms build` writes the resource pack to, relative to the project. The default is the data pack's `output` with `-resources` appended.",
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "sources": {
      "description": "Glob patterns for the project's .mms files, relative to the project; `**` matches any number of folders. The default is every .mms file (`**/*.mms`), skipping the output folders, hidden folders and `node_modules`.",
      "markdownDescription": "Glob patterns for the project's .mms files, relative to the project; `**` matches any number of folders. The default is every .mms file (`**/*.mms`), skipping the output folders, hidden folders and `node_modules`.",
      "type": "array",
      "examples": [
        [
          "src/**/*.mms"
        ]
      ],
      "items": {
        "description": "A glob relative to the project: `*` matches within a folder, `**` any number of folders and `?` one character.",
        "markdownDescription": "A glob relative to the project: `*` matches within a folder, `**` any number of folders and `?` one character.",
        "type": "string",
        "examples": [
          "src/**/*.mms"
        ]
      }
    }
  },
  "additionalProperties": false,
  "definitions": {
    "severity": {
      "description": "A lint severity.",
      "type": "string",
      "enum": [
        "error",
        "warning",
        "info",
        "hint",
        "off",
        "warn"
      ],
      "enumDescriptions": [
        "Report as an error; `mms build` fails.",
        "Report as a warning.",
        "Report as information.",
        "Report as a hint (shown faintly in editors).",
        "Turn the rule off.",
        "Same as `warning`."
      ]
    }
  }
}
