{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/ThePandemoniumInstitute/botc-release/main/script-schema.json", "type": "array", "default": [], "title": "Blood on the Clocktower Custom Script", "minItems": 5, "maxItems": 201, "items": { "oneOf": [ { "type": "object", "title": "Script Character", "required": ["id", "name", "team", "ability"], "additionalProperties": false, "properties": { "id": { "type": "string", "title": "Character ID, alphanumeric lowercase", "maxLength": 50, "examples": ["washerwoman", "lilmonsta", "fanggu"] }, "name": { "type": "string", "title": "Character name", "maxLength": 30, "examples": ["Washer Woman", "Lil' Monsta", "Fang-Gu"] }, "image": { "oneOf": [ { "type": "string", "format": "uri", "title": "Character icon", "examples": ["https://i.imgur.com/character-icon.png"] }, { "type": "array", "title": "Set of character icon URLs", "description": "For non-traveller characters, the icons should be regular alignment and flipped alignment, for travellers they should be unaligned, good alignment and evil alignment", "minItems": 1, "maxItems": 3, "items": { "type": "string", "format": "uri" }, "examples": [ [ "https://imgur.com/townsfolk.png", "https://imgur.com/townsfolk_evil.png" ], [ "https://imgur.com/minion.png", "https://imgur.com/minion_good.png" ], [ "https://imgur.com/traveller.png", "https://imgur.com/traveller_good.png", "https://imgur.com/traveller_evil.png" ] ] } ] }, "team": { "type": "string", "title": "Character team", "enum": [ "townsfolk", "outsider", "minion", "demon", "traveller", "fabled", "loric" ] }, "edition": { "type": "string", "title": "The edition ID", "maxLength": 50, "examples": ["tb", "bmr", "snv", "fallofrome"] }, "ability": { "type": "string", "title": "Character ability", "maxLength": 250, "examples": [ "You start knowing that 1 of 2 players is a particular Townsfolk.", "Each night, Minions choose who babysits Lil' Monsta's token \u0026 \"is the Demon\". A player dies each night*. [+1 Minion]", "Each night*, choose a player: they die. The 1st Outsider this kills becomes an evil Fang Gu \u0026 you die instead. [+1 Outsider]" ] }, "flavor": { "type": "string", "title": "Character flavor text", "maxLength": 500, "examples": [ "Bloodstains on a dinner jacket? No, this is cooking sherry. How careless.", "Certainly madam, under normal circumstances, you may borrow the Codex Malificarium from the library vaults. However, you do not seem to be a member.", "It is a fine night for a stroll, wouldn't you say, Mister Morozov? Or should I say... BARON Morozov?" ] }, "firstNight": { "type": "number", "title": "First night wake-up priority. 0 means this character doesn't wake during the first night.", "examples": [37, 0, 15] }, "firstNightReminder": { "type": "string", "title": "First night Storyteller reminder", "maxLength": 500, "examples": [ "Show the Townsfolk character token. Point to both the *TOWNSFOLK* and *WRONG* players.", "Wake all Minions, allow them to choose a babysitter :reminder:", "" ] }, "otherNight": { "type": "number", "title": "Other nights wake-up priority. 0 means this character doesn't wake during other nights.", "examples": [0, 10, 15] }, "otherNightReminder": { "type": "string", "title": "Other nights Storyteller reminder", "maxLength": 500, "examples": [ "", "Wake all Minions, allow them to choose a babysitter :reminder: A player might die :reminder:", "The Fang Gu chooses a player. :reminder: If they chose an Outsider (once only): Replace the Outsider token with the spare Fang Gu token. Put the Fang Gu to sleep. Wake the target. Show the *YOU ARE* and Fang Gu tokens \u0026 give a thumbs-down. :reminder:" ] }, "reminders": { "type": "array", "maxItems": 20, "default": [], "title": "Character reminder tokens", "items": { "type": "string", "maxLength": 30, "examples": ["Townsfolk", "Wrong", "Dead", "Is The Demon"] } }, "remindersGlobal": { "type": "array", "maxItems": 20, "default": [], "title": "Global character reminder tokens, which will be selectable even when the character is not in play.", "items": { "type": "string", "maxLength": 25, "examples": ["Drunk", "Is The Philosopher"] } }, "setup": { "type": "boolean", "title": "Whether this character has a ability that is relevant for the game setup.", "default": false }, "jinxes": { "type": "array", "title": "Jinxes with other characters on this script", "items": { "type": "object", "title": "An individual Jinx pair", "required": ["id", "reason"], "properties": { "id": { "type": "string", "title": "The ID of the other character this one is jinxed with.", "maxLength": 50, "examples": ["spy", "fanggu", "lilmonsta"] }, "reason": { "type": "string", "title": "The Jinx explanation", "maxLength": 500, "examples": [ "If the Cannibal gains the Butler ability, the Cannibal learns this.", "The Mathematician learns if the Lunatic attacks a different player(s) than the real Demon attacked." ] } } } }, "special": { "type": "array", "title": "Special app integration features for this character", "items": { "type": "object", "title": "A special app integration feature", "required": ["name", "type"], "properties": { "type": { "type": "string", "title": "The integration type, where the feature will be used.", "description": "Currently supported values are:\n selection - during character selection,\n signal - during night signaling,\n ability - when clicking on the character token,\n vote - during a vote,\n reveal - at the end of the game, before characters are revealed,\n player - an ability that can be initiated by the player", "enum": [ "selection", "ability", "signal", "vote", "reveal", "player" ] }, "name": { "type": "string", "title": "The feature name reference", "description": "This is a list of the currently implemented special features and will be growing over time.", "enum": [ "grimoire", "pointing", "ghost-votes", "distribute-roles", "bag-disabled", "bag-duplicate", "multiplier", "hidden", "replace-character", "player", "card", "open-eyes" ] }, "value": { "oneOf": [ { "type": "string", "title": "Special ability text value", "maxLength": 50, "description": "The text value that will be used by the special ability." }, { "type": "number", "title": "Special ability number value", "description": "The numeric value that will be used by the special ability." } ] }, "time": { "type": "string", "title": "At which point during the game can the ability be used", "enum": [ "pregame", "day", "night", "firstNight", "firstDay", "otherNight", "otherDay" ] }, "global": { "type": "string", "title": "Global ability scope", "description": "If it's a global ability that can be used without the character being in play, this property defines on which characters it can be used. This does not work on non-player characters, because they are not considered to be on the Script.", "enum": [ "townsfolk", "outsider", "minion", "demon", "traveller", "dead" ] } }, "examples": [ { "type": "player", "name": "open-eyes", "time": "night" }, { "type": "signal", "name": "card", "value": "This is a Custom ST Card" }, { "type": "ability", "name": "pointing", "time": "night", "global": "minion" }, { "type": "vote", "name": "multiplier", "value": "3" } ] } } }, "examples": [ { "id": "washerwoman", "name": "Washerwoman", "edition": "tb", "team": "townsfolk", "firstNightReminder": "Show the Townsfolk character token. Point to both the *TOWNSFOLK* and *WRONG* players.", "otherNightReminder": "", "reminders": ["Townsfolk", "Wrong"], "setup": false, "ability": "You start knowing that 1 of 2 players is a particular Townsfolk.", "flavor": "Bloodstains on a dinner jacket? No, this is cooking sherry. How careless.", "firstNight": 37, "otherNight": 0 } ] }, { "type": "string", "title": "Official character ID", "maxLength": 20, "description": "If you want to include official characters in the script, it is sufficient to provide their ID as a string", "examples": ["soldier", "imp", "washerwoman"] }, { "type": "object", "title": "Script Metadata", "required": ["id", "name"], "properties": { "id": { "type": "string", "title": "The ID property must be called '_meta' for the Script metadata object.", "enum": ["_meta"] }, "name": { "type": "string", "title": "The script name", "maxLength": 50, "examples": ["Fall of Rome", "My Custom Homebrew"] }, "author": { "type": "string", "title": "The script author", "maxLength": 50, "examples": ["The Pandemonium Institute", "Your Name"] }, "logo": { "type": "string", "format": "uri", "maxLength": 250, "title": "The script logo image", "examples": ["https://imgur.com/logo.png"] }, "hideTitle": { "type": "boolean", "title": "Whether the script title / author should be hidden on the app" }, "background": { "type": "string", "format": "uri", "maxLength": 250, "title": "The script background image", "examples": ["https://imgur.com/background.jpg"] }, "almanac": { "type": "string", "format": "uri", "maxLength": 250, "title": "A link to the script's almanac page", "examples": [ "https://beardytas.com/garden-of-djinn/the-ballad-of-seat-7/" ] }, "bootlegger": { "type": "array", "title": "A list of homebrew rules that are to be used for this script", "description": "Any (optional) homebrew rules that should be shown on the character sheet can be listed here, up to a limit of 10.", "maxItems": 10, "items": { "type": "string", "title": "A homebrew rule", "examples": [ "If the Snake Charmer swaps with the Demon on the first night, they learn their Minions and Bluffs instead of the original Demon." ] } }, "firstNight": { "type": "array", "title": "The relative First Night order of characters on this script.", "description": "A custom first night order for this script can be provided in the form of an array here, with optional special entries for 'dusk', 'minioninfo', 'demoninfo' and 'dawn'.", "maxItems": 30, "items": { "type": "string", "title": "Character ID of an on-script character in the first night order" }, "examples": [ [ "dusk", "minioninfo", "demoninfo", "poisoner", "spy", "washerwoman", "librarian", "investigator", "chef", "empath", "fortuneteller", "butler", "dawn" ] ] }, "otherNight": { "type": "array", "title": "The relative Other Nights order of characters on this script.", "description": "A custom other night order for this script can be provided in the form of an array here, with optional special entries for 'dusk' and 'dawn'.", "maxItems": 30, "items": { "type": "string", "title": "Character ID of an on-script character in the other night order" }, "examples": [ [ "dusk", "poisoner", "monk", "spy", "scarletwoman", "imp", "ravenkeeper", "undertaker", "empath", "fortuneteller", "butler", "dawn" ] ] } }, "examples": [ { "id": "_meta", "name": "Deadly Penance Day", "author": "TPI", "logo": "https://url.to/your/logo.png" } ] }, { "type": "object", "title": "Official Character (deprecated)", "deprecated": true, "required": ["id"], "additionalProperties": false, "properties": { "id": { "type": "string", "maxLength": 20, "title": "Official character ID", "examples": ["soldier", "imp", "washerwoman"] } } } ] } }