{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"$schema":{"type":"string","format":"uri"},"schema_version":{"default":1,"type":"number","const":1},"mode":{"description":"browser: plays in Patch's game window. installed: into a game on the player's PC. standalone: a program of its own. workshop: a Steam Workshop item. manual: players install it by hand. Left out: browser, or installed when there's a host game.","type":"string","enum":["browser","installed","standalone","workshop","manual"]},"games":{"default":[],"type":"array","items":{"type":"object","properties":{"game":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,63}$","description":"The host game's slug on Patch, e.g. hollow-knight."},"role":{"default":"host","description":"host: the game it plays in. companion: another game it needs on the player's PC, for its files or to run beside it. related: a game it's only related to.","type":"string","enum":["host","companion","related"]},"version":{"description":"The game versions it works with, in words or as a range, e.g. \">=1.6\".","type":"string","maxLength":80},"stores":{"minItems":1,"type":"array","items":{"type":"string","enum":["steam","epic","gog","xbox","ea","ubisoft","battlenet","microsoft"]}},"builds":{"description":"Exact builds per store; leave out to accept any build.","type":"object","propertyNames":{"type":"string","enum":["steam","epic","gog","xbox","ea","ubisoft","battlenet","microsoft"]},"additionalProperties":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}}}},"required":["game"]}},"components":{"description":"Left out: one main component, \"main\", holding every file.","minItems":1,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9][a-z0-9._-]{0,63}$"},"file":{"type":"string","description":"One uploaded file, a folder of them ending in \"/\", or \"\" for every file."},"label":{"description":"What it is, e.g. \"Main files\".","type":"string","maxLength":80},"kind":{"default":"main","description":"main: what players need. optional: players can turn it on. extra: not installed.","type":"string","enum":["main","optional","extra"]},"required":{"type":"boolean"},"extract":{"description":"The file is a zip to unpack when it's installed.","type":"boolean"}},"required":["id","file"]}},"mappings":{"default":[],"description":"Where each component's files go.","type":"array","items":{"type":"object","properties":{"component":{"type":"string"},"from":{"default":"","description":"\"\" for all of the component, \"folder/\" for a folder of it, or one file.","type":"string"},"to":{"type":"string"}},"required":["component","to"]}},"requirements":{"default":[],"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"project"},"project":{"type":"string","description":"Another project on Patch, e.g. a mod loader."},"version":{"default":"*","type":"string","description":"A semver range, e.g. ^1.2 or *."},"optional":{"description":"Used if the player has it, not needed.","type":"boolean"}},"required":["kind","project"]},{"type":"object","properties":{"kind":{"type":"string","const":"loader"},"loader":{"type":"string","enum":["bepinex-5","cet","ultimate-asi-loader","metamod-source","sourcemod","fabric","quilt","neoforge","forge"],"description":"A mod loader Patch sets up with the release and removes with it, e.g. bepinex-5, cet, sourcemod or fabric."},"version":{"description":"Minecraft loaders (fabric, quilt, neoforge, forge): the loader version; left out, Prism Launcher's recommended one for the game's version. Other loaders use the version Patch pins.","type":"string","maxLength":40}},"required":["kind","loader"]},{"type":"object","properties":{"kind":{"type":"string","const":"external"},"label":{"type":"string","minLength":1,"maxLength":80,"description":"What players get themselves."},"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"check":{"description":"Files that show it's installed.","type":"object","properties":{"files":{"minItems":1,"maxItems":8,"type":"array","items":{"type":"string"}}},"required":["files"]}},"required":["kind","label"]}]}},"launch":{"description":"Left out: index.html for a browser game, the game itself otherwise.","oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"browser"},"component":{"default":"main","type":"string"},"entry":{"default":"index.html","description":"The page Patch opens, inside the component.","type":"string"},"aspect_ratio":{"type":"string","pattern":"^\\d+:\\d+$"}},"required":["kind"]},{"type":"object","properties":{"kind":{"type":"string","const":"game"},"args":{"maxItems":32,"type":"array","items":{"type":"string","maxLength":400}}},"required":["kind"]},{"type":"object","properties":{"kind":{"type":"string","const":"exe"},"path":{"type":"string"},"cwd":{"type":"string"},"args":{"maxItems":32,"type":"array","items":{"type":"string","maxLength":400}},"env":{"type":"object","propertyNames":{"type":"string","pattern":"^[A-Za-z_][A-Za-z0-9_]{0,63}$"},"additionalProperties":{"type":"string","maxLength":400}}},"required":["kind","path"]},{"type":"object","properties":{"kind":{"type":"string","const":"uri"},"uri":{"type":"string","pattern":"^(steam|com\\.epicgames\\.launcher|https):\\/\\/"}},"required":["kind","uri"]},{"type":"object","properties":{"kind":{"type":"string","const":"none"}},"required":["kind"]}]},"settings":{"default":[],"description":"Config files and the values to set in them.","maxItems":4,"type":"array","items":{"type":"object","properties":{"file":{"type":"string"},"format":{"type":"string","enum":["ini","json","xml","cfg"]},"set":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["string","number","boolean"]}}},"required":["file","format","set"]}},"test":{"type":"object","properties":{"args":{"maxItems":16,"type":"array","items":{"type":"string","maxLength":400}},"checks":{"description":"Checks the release reports itself while it's tested: a browser game opened with ?patch-test=1 logs \"pass <name>\" or \"fail <name>: why\".","maxItems":12,"type":"array","items":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,39}$"}},"minutes":{"type":"integer","minimum":1,"maximum":15}}},"notes":{"description":"Short notes players see.","type":"object","properties":{"before_install":{"type":"string","maxLength":500},"first_launch":{"type":"string","maxLength":500}}},"runtime_data":{"default":[],"description":"Folders of the release's own data on the player's PC, never the game's.","maxItems":8,"type":"array","items":{"type":"string"}},"players":{"type":"object","properties":{"min":{"type":"integer","minimum":1,"maximum":9007199254740991},"max":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["min","max"]},"workshop":{"type":"object","properties":{"steam_app_id":{"type":"string","pattern":"^\\d+$"},"file_id":{"type":"string","pattern":"^\\d+$"}},"required":["steam_app_id","file_id"]},"credits":{"default":[],"type":"array","items":{"type":"object","properties":{"files":{"type":"string","minLength":1},"license":{"type":"string","minLength":1,"description":"SPDX id, e.g. CC0-1.0 or MIT."},"source":{"type":"string","format":"uri"},"author":{"type":"string"}},"required":["files","license"]}}},"additionalProperties":false,"$id":"https://patch.gg/schemas/recipe/v1.json","title":"Patch release recipe","description":"What a release is and how players get it. Sent with the release; a browser game whose entry is index.html needs none."}