Files
libretro/schemas/emulator.schema.json
T
Abdessamad Derraz 7ff8f17808 feat: profile RetroPie's AdvanceMAME tip build
RetroPie clones amadvance/advancemame at the branch tip with no
revision (scriptmodules/emulators/advmame.sh:16, 39-41 at 427e762), so
advmame is profiled at 96237a5 (v5.0-484), built_by retropie and held
by pin_follows. RetroPie's advmame now resolves to it, advancemame
keeping EmuELEC, AmberELEC and Recalbox.

The MAME workflow at 96237a5: 28 BIOS roots registered in
mame/mamedriv.c (macs2bios is not), the eight ZN roots under their MAME
names (coh1000c, coh3002c, coh1002m, coh1000t, coh1002e, coh1001l,
coh1000w, coh1000a), modern Neo Geo members, coh1000w's CAT702, and 15
device archives that BIOS_LOAD reads first (atarisy1, coh3002t, m1comm,
midssio, namcoc65/68/69/71/74, s_smp, saa5050, sente6vb, sns_dsp1bleg,
t5182, v4bios). bctvidbs declares no ROM of its own. Three laserdisc
player programs are opened by name outside any ROM list, with a fatal
length, CRC32 and SHA1 check: pr8210, 22vp931 and simutrek.

pin_build accepts pin_follows in the schema, and bump_commit advances a
built_by profile that follows the tip.

Manifests: RetroPie gains 24 archives at its BIOS root, the ZN ones
under their new names, and nss.zip moves to the copy holding
nss-c.dat and nss-ic14.02. The other platforms do not change.
verify --all keeps its counts. profile_sync: 0 to review.
2026-11-11 13:27:00 +01:00

1441 lines
49 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://abdess.github.io/retrobios/api/v1/schemas/emulator.schema.json",
"title": "Emulator BIOS Profile",
"description": "One YAML per emulator core or engine, documenting every external file the code loads. Field reference: https://abdess.github.io/retrobios/wiki/profiling/",
"type": "object",
"additionalProperties": false,
"required": [
"emulator",
"type"
],
"allOf": [
{
"comment": "A build reference documents why a pin is held or follows the branch tip, or the build config_reads are read at: it never stands without the pin_frozen, pin_follows or config_reads that say so.",
"if": {
"required": [
"pin_build"
]
},
"then": {
"anyOf": [
{"required": ["pin_frozen"]},
{"required": ["pin_follows"]},
{"required": ["config_reads"]}
]
}
},
{
"comment": "An alias profile points at another profile and carries no files of its own.",
"if": {
"properties": {
"type": {
"const": "alias"
}
},
"required": [
"type"
]
},
"then": {
"required": [
"alias_of"
]
},
"else": {
"required": [
"files"
]
}
},
{
"comment": "Per-file mode separates the two builds of a dual profile. A profile with only a standalone build has no libretro side to separate it from, and a file marked standalone there drops out of the gap analysis and of the packs of every platform that lists the emulator without standalone_cores.",
"if": {
"properties": {
"type": {
"const": "standalone"
}
},
"required": [
"type"
]
},
"then": {
"properties": {
"files": {
"items": {
"not": {
"properties": {
"mode": {
"const": "standalone"
}
},
"required": [
"mode"
]
}
}
}
}
}
},
{
"comment": "A profile whose code states no version says so with version_basis kind none and a null core_version, never a placeholder.",
"if": {
"properties": {
"version_basis": {
"properties": {
"kind": {
"const": "none"
}
},
"required": [
"kind"
]
}
},
"required": [
"version_basis"
]
},
"then": {
"properties": {
"core_version": {
"type": "null"
}
}
}
}
],
"properties": {
"emulator": {
"type": "string"
},
"display_name": {
"type": "string"
},
"type": {
"description": "Operational: resolve_platform_cores() filters on it. Not a classification.",
"type": "string",
"enum": [
"libretro",
"standalone",
"standalone + libretro",
"alias",
"launcher",
"game",
"utility"
]
},
"role": {
"description": "What a libretro core is for when it emulates no machine: a game of its own (2048), a utility (radio, video_processor), or a test core. Descriptive: the core stays type libretro, so every reader of all_libretro reaches it, and the site and coverage leave test cores out by this field.",
"type": "string",
"enum": [
"game",
"utility",
"test"
]
},
"core_classification": {
"description": "Descriptive only, no effect on tooling.",
"type": "string",
"enum": [
"pure_libretro",
"official_port",
"community_fork",
"frozen_snapshot",
"enhanced_fork",
"game_engine",
"embedded_hle",
"launcher",
"alias",
"other"
]
},
"built_by": {
"description": "The platforms that ship this build under its core name, compiled by them or installed from the project's own release (Recalbox's mame0278, the GSplus legacy build Recalbox, Batocera and RetroBat run). On those platforms the name resolves to this profile. It is never reached by all_libretro: the libretro buildbot does not publish it.",
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
},
"source": {
"type": [
"string",
"object"
]
},
"upstream": {
"type": [
"string",
"object",
"null"
]
},
"source_commit": {
"oneOf": [
{
"type": "string"
},
{
"type": "object"
}
],
"description": "Revision the profile was read at. An object keys it by build mode when the builds live in different repositories."
},
"upstream_commit": {
"oneOf": [
{
"type": "string"
},
{
"type": "object"
}
],
"description": "Revision the profile was read at. An object keys it by build mode when the builds live in different repositories."
},
"profiled_date": {
"description": "Quote it: an unquoted YAML date parses to a date object.",
"type": [
"string",
"object"
]
},
"core_version": {
"description": "The version of the code at the pin, read where version_basis says: the string the program states, git describe's form of the nearest tag, or the package read. Never a branch or VCS name (Git, SVN, master, latest, dev, unknown). null when version_basis is kind none. An object keys it by build mode, like source.",
"oneOf": [
{
"type": "string",
"pattern": "^(?!([Gg][Ii][Tt]|[Ss][Vv][Nn]|[Uu][Nn][Kk][Nn][Oo][Ww][Nn]|[Mm][Aa][Ss][Tt][Ee][Rr]|[Mm][Aa][Ii][Nn]|[Ll][Aa][Tt][Ee][Ss][Tt]|[Dd][Ee][Vv]|[Hh][Ee][Aa][Dd])([\\s(]|$)).*\\S"
},
{
"type": "null"
},
{
"type": "object",
"minProperties": 1,
"additionalProperties": {
"oneOf": [
{
"type": "string",
"pattern": "^(?!([Gg][Ii][Tt]|[Ss][Vv][Nn]|[Uu][Nn][Kk][Nn][Oo][Ww][Nn]|[Mm][Aa][Ss][Tt][Ee][Rr]|[Mm][Aa][Ii][Nn]|[Ll][Aa][Tt][Ee][Ss][Tt]|[Dd][Ee][Vv]|[Hh][Ee][Aa][Dd])([\\s(]|$)).*\\S"
},
{
"type": "null"
}
]
}
}
]
},
"version_basis": {
"description": "Where core_version is read, so a tool reads it again at any pin. An object keyed by build mode when core_version is.",
"oneOf": [
{
"$ref": "#/$defs/version_basis"
},
{
"type": "object",
"minProperties": 1,
"not": {
"required": [
"kind"
]
},
"additionalProperties": {
"$ref": "#/$defs/version_basis"
}
}
]
},
"alias_of": {
"type": "string"
},
"cores": {
"description": "Upstream names the core is known by. A dict maps each name to per-variant metadata. Names are strings: an unquoted 81 or 2048 parses as a number and stops matching the buildbot name.",
"oneOf": [
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
{
"type": "object",
"propertyNames": {
"minLength": 1
}
}
]
},
"systems": {
"type": "array",
"items": {
"type": "string"
}
},
"mode": {
"type": "string",
"enum": [
"standalone",
"libretro",
"both"
]
},
"verification": {
"type": "string",
"enum": [
"existence",
"md5",
"sha1",
"crc32"
]
},
"exclusion_note": {
"type": "string"
},
"analysis": {
"type": "object"
},
"analysis_commit": {
"type": "string"
},
"analysis_date": {
"type": "string"
},
"archive_prefix": {
"type": "string"
},
"author": {
"type": "string"
},
"based_on": {
"type": "string"
},
"bios_directory": {
"type": "string"
},
"bios_identical_to": {
"type": "string"
},
"found_by": {
"description": "How the code finds the file: by the name it opens, or by content in a folder it scans, the name then being a label. Keyed by build when the libretro and standalone builds differ.",
"oneOf": [
{"type": "string", "enum": ["name", "content"]},
{
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"libretro": {"type": "string", "enum": ["name", "content"]},
"standalone": {"type": "string", "enum": ["name", "content"]}
}
}
]
},
"bios_mode": {
"type": "string"
},
"bios_size": {
"type": "integer",
"minimum": 0
},
"builtin_boot_roms": {
"type": "object"
},
"core": {
"type": "string"
},
"core_name": {
"type": "string"
},
"data_directories": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"ref"
],
"properties": {
"ref": {
"type": "string"
},
"destination": {
"type": "string"
},
"required": {
"type": "boolean",
"description": "false when the core runs without the tree; --required-only leaves it out"
},
"mode": {
"type": "string",
"enum": [
"standalone",
"libretro",
"both"
]
},
"bundled": {
"type": "boolean",
"description": "Installed with the emulator for the build mode names, so packs leave the tree out."
},
"installed_on": {
"type": "array",
"items": {"type": "string"},
"description": "Platforms (registry keys) whose own package installs this beside the emulator, so their packs leave it out."
},
"not_bundled_on": {
"type": "array",
"items": {"type": "string"},
"description": "Platforms (registry keys) whose package leaves out a file the emulator's release bundles, so their packs bring it."
},
"unread_on": {
"type": "array",
"items": {"type": "string"},
"description": "Platforms (registry keys) whose launcher points the emulator at other files, so this entry is never opened there."
},
"systems": {
"type": "array",
"items": {"type": "string"},
"description": "The systems whose games the tree serves, when fewer than the profile's: an install for some systems keeps the tree only with one of them."
},
"load_from": {
"description": "Where the emulator reads the tree when not below the system directory, keyed by build when the builds differ (content_dir: beside the content). A platform pack carries only a tree read from the system directory.",
"oneOf": [
{"type": "string"},
{
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"libretro": {"type": "string"},
"standalone": {"type": "string"}
}
}
]
},
"source_ref": {
"type": "string"
}
}
}
},
"dev_flash": {
"type": "object"
},
"dev_flash2": {
"type": "object"
},
"dev_flash3": {
"type": "object"
},
"firmware_titles": {
"type": "array",
"items": {
"type": "object"
}
},
"game_count": {
"type": "integer",
"minimum": 0
},
"library_name": {
"description": "The library_name the libretro core reports in retro_get_system_info. A frontend sorting saves by core (RetroArch's sort_savefiles_enable) hands the core <save directory>/<library_name>, so a profile with a file the libretro build reads below the save directory (load_from: save_dir) declares it. Empty when the core reports an empty name, which RetroArch appends nothing for.",
"type": "string",
"pattern": "^[^/\\\\]*$"
},
"save_folder_once": {
"description": "true when the core adds its own folder to the save directory only where the directory it is handed is not already named so (Cemu's in_named_dir), so it reads the same place whether the frontend sorts saves by core or not. Every load_from: save_dir path then starts with that folder, the library_name.",
"const": true
},
"logo": {
"type": "string"
},
"machine_directories": {
"type": "object"
},
"machine_properties": {
"type": "object"
},
"mame_version": {
"type": "string"
},
"memory_layout": {
"type": "object"
},
"mlc_structure": {
"type": "array",
"items": {
"type": "string"
}
},
"model_kickstart_map": {
"type": "object"
},
"note": {
"type": "string"
},
"notes": {
"type": [
"string",
"array",
"object"
]
},
"pack_structure": {
"type": "object"
},
"platform_details": {
"type": "object"
},
"resources_directory": {
"type": "string"
},
"rom_path": {
"type": "string"
},
"source_ref": {
"type": "string"
},
"valid_bios_crc32": {
"type": "object"
},
"whdload_kickstarts": {
"type": "array",
"items": {
"type": "string"
}
},
"groups": {
"description": "The sets of entries the code takes one of, by name, with the requirement of each. A member names its sets with group and writes no required of its own: it is required when one of its sets is.",
"type": "object",
"minProperties": 1,
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"required": ["required"],
"properties": {
"required": {"type": "boolean"}
}
}
},
"files": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"required": {
"type": "boolean"
},
"system": {
"type": "string"
},
"systems": {
"type": "array",
"minItems": 2,
"uniqueItems": true,
"items": {
"type": "string"
},
"description": "The systems of the profile this entry serves, when it serves several and not all: a MAME device set the machines of two systems load. One system is written as system:."
},
"path": {
"type": [
"string",
"null"
]
},
"destination": {
"type": "string"
},
"aliases": {
"type": "array",
"items": {
"type": "string"
}
},
"archive": {
"description": "ROM set the file lives in, for arcade entries.",
"type": "string"
},
"category": {
"type": "string",
"enum": [
"bios",
"game_data",
"bios_zip"
]
},
"mode": {
"type": "string",
"enum": [
"standalone",
"libretro",
"both"
]
},
"storage": {
"type": "string",
"enum": [
"embedded",
"external",
"user_provided",
"large_file",
"release"
]
},
"hle_fallback": {
"type": "boolean"
},
"evidence": {
"description": "Real-condition runs that settled a field of this entry, by field: the ids of the core probe records in measurements/<emulator>.jsonl. Written by scripts/campaign.py when its rule table settles the field.",
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"required": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}-[0-9a-f]{12}$"}},
"hle_fallback": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}-[0-9a-f]{12}$"}},
"path": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}-[0-9a-f]{12}$"}},
"aliases": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}-[0-9a-f]{12}$"}},
"validation": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}-[0-9a-f]{12}$"}}
}
},
"adler32_byteswap": {
"type": "boolean"
},
"adler32_pairs_with": {
"description": "The file hashed together with this one. adler32_pairs lists the combinations the code accepts.",
"type": "string"
},
"adler32_pairs": {
"description": "Accepted Adler-32 combinations, this file's value first, in the code's table order.",
"type": "array",
"items": {
"type": "array",
"items": {"type": "string"},
"minItems": 2,
"maxItems": 2
},
"minItems": 1
},
"agnostic": {
"type": "boolean"
},
"bundled": {
"type": "boolean",
"description": "Installed with the emulator for the build mode names (all builds when mode is absent): already on the user's machine, so packs and install manifests leave it out."
},
"installed_on": {
"type": "array",
"items": {"type": "string"},
"description": "Platforms (registry keys) whose own package installs this beside the emulator, so their packs leave it out."
},
"not_bundled_on": {
"type": "array",
"items": {"type": "string"},
"description": "Platforms (registry keys) whose package leaves out a file the emulator's release bundles, so their packs bring it."
},
"unread_on": {
"type": "array",
"items": {"type": "string"},
"description": "Platforms (registry keys) whose launcher points the emulator at other files, so this entry is never opened there."
},
"config_key": {
"type": "string"
},
"embedded": {
"type": "boolean"
},
"fast_boot": {
"type": "string"
},
"has_builtin": {
"type": "boolean"
},
"found_by": {
"description": "How the code finds the file: by the name it opens, or by content in a folder it scans, the name then being a label. Keyed by build when the libretro and standalone builds differ.",
"oneOf": [
{"type": "string", "enum": ["name", "content"]},
{
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"libretro": {"type": "string", "enum": ["name", "content"]},
"standalone": {"type": "string", "enum": ["name", "content"]}
}
}
]
},
"load_from": {
"description": "Where the emulator reads the file when not from the system directory, keyed by build when the libretro and standalone builds read it from different places. save_dir: path is relative to the directory the frontend returns for RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, and packs and the installer place the libretro build's file there.",
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"libretro": {
"type": "string"
},
"standalone": {
"type": "string"
}
}
}
]
},
"priority": {
"description": "Preference order among the BIOS a system accepts, lowest first. DuckStation's FindBIOSImageInDirectory keeps the image whose priority is lower. A search list the code walks in order maps onto it as 1, 2, 3. The order only: which entries stand in for one another is group.",
"type": "integer",
"minimum": 0
},
"group": {
"description": "The sets of the profile's groups map this entry belongs to. A set is one need: the code loads one member (the first it finds, in priority order where the source states one) and holding any member fills it. A list puts a file in several sets, a fallback two machine models share, and a map from set to rank gives its place in each when the places differ (priority otherwise). The entry writes no required: it is derived from its sets.",
"oneOf": [
{"type": "string", "minLength": 1},
{"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
{"type": "object", "minProperties": 1, "additionalProperties": {"type": ["integer", "null"], "minimum": 0}}
]
},
"region_check": {
"type": "boolean"
},
"size_note": {
"type": "string"
},
"standalone_path": {
"type": "string"
},
"type": {
"description": "Set on an entry that names a directory the code reads whole. The entry then stands for every file under path.",
"type": "string",
"enum": [
"directory"
]
},
"selection_slot": {
"description": "Files one core chooses between by a rule other than first found: the disc's territory, a core option, a feature probe. They fill one slot of the core whatever system each is filed under, region filtering compares them together, and same-named entries in different slots stay apart. A member does not stand in for another: entries that do are a group.",
"type": "string",
"minLength": 1
},
"size": {
"type": [
"integer",
"array",
"null"
],
"minimum": 0,
"items": {
"type": "integer",
"minimum": 0
},
"minItems": 1
},
"min_size": {
"type": "integer"
},
"max_size": {
"type": "integer"
},
"size_multiple": {
"description": "Granule the file size must be a whole number of, the bounds still applying.",
"type": "integer",
"minimum": 1
},
"md5": {
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"pattern": "^[a-fA-F0-9]{32}$"
},
{
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-fA-F0-9]{32}$"
}
}
]
},
"sha1": {
"oneOf": [
{
"type": "string",
"pattern": "^[a-fA-F0-9]{40}$"
},
{
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-fA-F0-9]{40}$"
}
}
]
},
"sha256": {
"type": "string",
"pattern": "^[a-fA-F0-9]{64}(,[a-fA-F0-9]{64})*$"
},
"crc32": {
"description": "CRC32 the code accepts, as a list when several dumps pass.",
"oneOf": [
{
"type": "string",
"pattern": "^[a-fA-F0-9]{8}$"
},
{
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-fA-F0-9]{8}$"
},
"minItems": 1
}
]
},
"known_hash_adler32": {
"description": "Adler-32 values the code accepts, as a list when several revisions pass.",
"oneOf": [
{
"type": [
"string",
"integer"
]
},
{
"type": "array",
"items": {
"type": [
"string",
"integer"
]
},
"minItems": 1
}
]
},
"masked_sha1": {
"description": "SHA-1 the code takes over a file with a byte range cleared (validation: masked_sha1), for each file size it tries.",
"type": "object",
"additionalProperties": false,
"properties": {
"zeroed": {"description": "Start and end offsets of the bytes cleared before hashing.", "type": "array", "items": {"type": "integer", "minimum": 0}, "minItems": 2, "maxItems": 2},
"reads": {"type": "array", "minItems": 1, "items": {"type": "object", "additionalProperties": false, "properties": {"size": {"type": "integer"}, "lengths": {"type": "array", "items": {"type": "integer"}, "minItems": 1}}, "required": ["size", "lengths"]}},
"sha1": {"type": "string", "pattern": "^[0-9a-f]{40}$"}
},
"required": ["zeroed", "reads", "sha1"]
},
"romdir": {
"description": "How the code reads a PS2 ROM directory (validation: romdir): the RESET search, the walk to ROMVER, and the serial and zone tests after it.",
"type": "object",
"additionalProperties": false,
"properties": {
"reset_compare": {"description": "Bytes of the entry name strncmp compares with RESET: 5 takes any name starting RESET, 10 wants RESET and a NUL.", "enum": [5, 10]},
"missing_reset": {"description": "What 512 Ki entries without RESET do.", "enum": ["rejects", "ends_walk"]},
"terminated_names": {"description": "The walk stops at a name with no NUL in its 10 bytes.", "type": "boolean"},
"extinfo": {"description": "EXTINFO is read 0x10 past its offset, and an unreadable one ends the walk.", "type": "boolean"},
"unreadable_romver": {"description": "What ROMVER bytes past the end of the file do.", "enum": ["rejects", "ends_walk", "ignored"]},
"truncated_walk": {"description": "What a next entry past the end of the file does.", "enum": ["rejects", "ends_walk"]},
"offset_width": {"description": "Bit width of the file offset sum.", "enum": [32, 64]},
"refused_serials": {"description": "EXTINFO serials the code turns away.", "type": "array", "items": {"type": "string"}},
"zones": {"description": "ROMVER zone codes the scan keeps, ROMVER[4] then [5] where the code reads it.", "type": "array", "items": {"type": "string", "minLength": 1, "maxLength": 2}},
"refused_zones": {"description": "ROMVER zone codes the scan passes over.", "type": "array", "items": {"type": "string", "minLength": 1, "maxLength": 2}}
},
"required": ["reset_compare", "missing_reset", "terminated_names", "extinfo", "unreadable_romver", "truncated_walk"]
},
"validation": {
"description": "Checks the code performs. A dict splits core from upstream when they diverge.",
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "object"
}
]
},
"region": {
"description": "Region the emulator code selects this file for, never the region of the dump.",
"type": "array",
"items": {
"enum": [
"world",
"north-america",
"canada",
"latin-america",
"brazil",
"mexico",
"argentina",
"europe",
"uk",
"france",
"germany",
"italy",
"spain",
"netherlands",
"portugal",
"greece",
"poland",
"russia",
"sweden",
"norway",
"denmark",
"finland",
"asia",
"japan",
"south-korea",
"china",
"taiwan",
"hong-kong",
"singapore",
"india",
"asia-ntsc",
"asia-pal",
"oceania",
"australia",
"new-zealand"
]
}
},
"contents": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"size": {
"type": "integer",
"minimum": 0
},
"sha1": {
"type": "string",
"pattern": "^[a-fA-F0-9]{40}$"
},
"crc32": {
"type": "string",
"pattern": "^[a-fA-F0-9]{8}$"
},
"description": {
"type": "string"
},
"bad_dump": {
"type": "boolean"
}
}
}
},
"source_ref": {
"description": "A dict splits core from upstream when the two diverge.",
"type": [
"string",
"array",
"object"
]
},
"description": {
"type": "string"
},
"note": {
"type": "string"
},
"unsourceable": {
"type": "string"
},
"on_mismatch": {
"description": "What the code does when a declared check fails: reject the file (default) or warn and run with it, for every check or check by check.",
"oneOf": [
{
"enum": [
"reject",
"warn"
]
},
{
"type": "object",
"minProperties": 1,
"additionalProperties": false,
"patternProperties": {
"^(size|crc32|md5|sha1|sha256|adler32|signature|crypto)$": {
"enum": [
"reject",
"warn"
]
}
}
}
]
}
},
"allOf": [
{
"not": {
"required": [
"system",
"systems"
]
}
},
{
"not": {"required": ["group", "required"]}
},
{
"if": {
"properties": {
"name": {
"pattern": "/$"
}
}
},
"then": {
"required": [
"type"
]
}
},
{
"if": {
"anyOf": [
{
"required": [
"path"
],
"properties": {
"path": {
"type": "string",
"pattern": "/$"
}
}
},
{
"required": [
"standalone_path"
],
"properties": {
"standalone_path": {
"type": "string",
"pattern": "/$"
}
}
}
]
},
"then": {
"required": [
"type"
]
}
},
{
"if": {
"required": [
"type"
]
},
"then": {
"properties": {
"path": {
"type": "string",
"pattern": "/$"
}
}
}
}
]
}
},
"source_branch": {
"type": "string",
"description": "Branch the port was read from, when it is not the default one."
},
"standalone_directories": {
"type": "array",
"items": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"additionalProperties": false,
"required": ["handle", "source_ref"],
"properties": {
"handle": {"type": "string", "minLength": 1},
"source_ref": {"type": "string", "minLength": 1, "description": "Where the build reads the handle and resolves its files against it"}
}
}
]
},
"description": "What the standalone build resolves standalone_path against, as its code names it: a directory ($XDG_DATA_HOME/flycast), a setting (Dreamcast.BiosPath), an environment variable or the function returning the directory. A platform launcher record that links or passes a folder of its BIOS tree under one of these puts the standalone files in that folder."
},
"standalone_pools": {
"type": "object",
"additionalProperties": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"additionalProperties": false,
"required": ["folder", "source_ref"],
"properties": {
"folder": {"type": "string"},
"source_ref": {"type": "string", "minLength": 1, "description": "Where the build reads the setting as a search list"}
}
}
]
},
"description": "Settings the standalone build reads as a list of directories it searches one after the other, each mapped to the subfolder of the layout (relative to standalone_directories, empty for the whole of it) its directories stand for: openMSX's filepool entries are searched like share/systemroms, XRoar's rompath entries hold the ROMs themselves. A file in any entry is read, so several platform records naming entries give the first one a pack can fill."
},
"libretro_pools": {
"type": "object",
"additionalProperties": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"additionalProperties": false,
"required": ["folder", "source_ref"],
"properties": {
"folder": {"type": "string"},
"source_ref": {"type": "string", "minLength": 1, "description": "Where the build reads the option from its content"}
}
}
]
},
"description": "Options of the command line a libretro build is handed as its content that set a list of directories it searches, each mapped to the folder below the system directory whose files those directories stand for: libretro MAME hands MAME <system>/mame/bios unless the content's own -rompath replaces it."
},
"prose_written_at": {
"type": "string",
"pattern": "^[0-9a-f]{40}$",
"description": "The pin a reader confirmed every prose citation against. When the profile's history shows several pins under one text, profile_sync takes this one as the revision the text describes. It never overrides a single candidate."
},
"pin_frozen": {
"type": "string",
"description": "Why source_commit is held on purpose rather than followed. The profile is then judged against its own revision, like one pinned to a superseded tag: comparing it to HEAD says nothing and recaling would repoint its refs at code the build it documents never had."
},
"pin_build": {
"type": "array",
"minItems": 1,
"description": "The build file each platform that ships a pin_frozen or pin_follows build, or the build a config_reads entry is read at, reads its revision from, so check_freshness can read it again where the platform's YAML now stands and say when the platform builds another revision.",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["platform", "repo", "revision", "path", "variable", "value"],
"properties": {
"platform": {
"type": "string",
"description": "Registry slug of the platform (platforms/<platform>.yml)."
},
"repo": {
"type": "string",
"format": "uri",
"description": "The platform's own repository, the one its YAML is scraped from."
},
"revision": {
"type": "string",
"description": "Tag or commit of that repository the build file was read at."
},
"path": {
"type": "string",
"description": "The build file, from the repository root (package.mk, a Buildroot .mk, a RetroPie scriptmodule)."
},
"variable": {
"type": "string",
"description": "The variable the file sets to the revision it builds (PKG_VERSION, <PKG>_VERSION, rp_module_repo)."
},
"value": {
"type": "string",
"description": "What the variable held at revision, quotes and trailing comment removed."
}
}
}
},
"config_reads": {
"type": "array",
"description": "The configs the build loads and the keys it opens a file from, as a platform launcher record citing a config needs them: link (c) is where the file is found and loaded, link (d) where each key is read and its value opened. An entry naming platforms is read at their pin_build revision, one naming none at source_commit.",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["file", "source_ref", "keys"],
"dependentRequired": {"revision": ["platforms", "revision_from"], "binary_sha256": ["platforms", "revision_from"]},
"not": {"required": ["revision", "binary_sha256"]},
"properties": {
"file": {"type": "string", "minLength": 1, "description": "The config as the code finds it: a name, a glob for any file a flag passes (*.uae), a path, the flag itself, \"command line\" or \"core options\""},
"platforms": {"type": "array", "items": {"type": "string"}, "minItems": 1, "uniqueItems": true, "description": "Registry slugs of the platforms shipping the build these refs are read at, each with a pin_build entry unless revision names the build"},
"revision": {"type": "string", "pattern": "^[0-9a-f]{40}$", "description": "The commit these refs are read at, for platforms installing a package no build file of theirs pins (RetroBat's stable archives, a Flathub app)"},
"binary_sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$", "description": "The shipped binary these refs are read in, for a build whose source is not public (SSF, YabaSanshiro 1.20): its refs are virtual addresses of that file"},
"revision_from": {"type": "string", "minLength": 1, "description": "Where revision or binary_sha256 was read: the version string of the shipped binary, the Flathub manifest commit, the archive the binary comes from"},
"source_ref": {"type": "string", "minLength": 1},
"keys": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["key", "source_ref"],
"properties": {
"key": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "array", "items": {"type": "string", "minLength": 1}, "minItems": 1}], "description": "Spelled as a launcher record's passes_to spells it: [Section] Key, or Key"},
"source_ref": {"type": "string", "minLength": 1},
"condition": {"type": "string", "description": "What else the read depends on"}
}
}
}
}
}
},
"pin_follows": {
"type": "string",
"description": "Why source_commit follows the branch tip although a single platform ships the profile: that platform builds the tip, cited by its build file. Without it or pin_frozen, a bump refuses a profile one platform ships."
},
"data_root": {
"type": "object",
"minProperties": 1,
"propertyNames": {"enum": ["android", "ios", "windows", "macos", "linux"]},
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"required": ["path", "source_ref"],
"properties": {
"path": {"type": "string", "minLength": 1, "description": "The folder as the user finds it on that OS, with the environment variable or home prefix the code expands (%APPDATA%, ~, Android/data/<package>)."},
"source_ref": {"type": "string", "minLength": 1},
"note": {"type": "string"}
}
},
"description": "Per operating system, the folder the app reads its user data from, under which standalone_path destinations sit. Only the systems the app runs on are keyed."
},
"upstream_frozen": {
"type": "string",
"description": "Why upstream_commit is held on purpose rather than followed: the port vendors that upstream tree, synced to that release, or merged that commit. The upstream view is judged against its own revision and a bump leaves it, the way pin_frozen holds source_commit."
},
"version_source": {
"type": "object",
"additionalProperties": false,
"required": ["url", "pattern"],
"properties": {
"url": {"type": "string", "format": "uri"},
"pattern": {"type": "string", "description": "Regular expression whose first group is the latest version the page announces."},
"no_genuine_copy": {"type": "string", "description": "An announced version a search found only rebuilt or re-signed copies of. While the page announces it, the profile is not stale. A later version makes it stale again."}
},
"description": "For a project published outside any forge, the page that announces its releases. profile_sync --check-version compares the version read there with core_version."
},
"upstream_gone": {
"type": "string",
"description": "Why the declared upstream can no longer be reached, when that is settled rather than transient. Records the death instead of leaving the profile failing every pass. profile_sync reports the contradiction if the forge answers again."
},
"source_mirror": {
"type": "string",
"description": "Repository carrying the same tree, consulted after source and upstream. The only thing that keeps a profile checkable once its own forge is withdrawn or its host stops resolving."
}
},
"$defs": {
"version_basis": {
"type": "object",
"additionalProperties": false,
"required": [
"kind"
],
"properties": {
"kind": {
"enum": [
"file",
"tag",
"alias",
"package",
"none",
"unverified"
],
"description": "file: a pattern in one file at the pin. tag: the nearest tag in the pin's history. alias: the version of the profile it aliases. package: an artefact read outside any source tree. none: the code at the pin states no version and no tag reaches it. unverified: no reading could be made, for the reason why gives. core_version stays as written, unconfirmed."
},
"why": {
"enum": [
"no_pin",
"host_unsupported",
"host_gone",
"host_unreachable",
"pin_off_branch",
"no_artifact",
"no_source"
],
"description": "Why a basis is unverified: no pinned commit, a host the tools cannot read, a forge gone, a forge that did not answer, a pin on another branch than the build the profile describes, no build or package named as read, no source declared."
},
"repo": {
"enum": [
"source",
"upstream",
"source_mirror"
],
"description": "The declared repository the version describes, pinned by source_commit (source, source_mirror) or upstream_commit. Default source."
},
"url": {
"type": "string",
"format": "uri",
"description": "kind file: a repository outside the profile's own, read at commit (the package file of a build a platform ships). kind package: where the artefact was obtained."
},
"commit": {
"type": "string",
"pattern": "^[0-9a-f]{7,40}$",
"description": "The revision of url the file is read at."
},
"path": {
"type": "string",
"minLength": 1,
"description": "File read at the pin."
},
"pattern": {
"type": "string",
"minLength": 1,
"description": "Regular expression, multiline, whose groups hold the version."
},
"format": {
"type": "string",
"pattern": "\\{\\d+",
"description": "How the groups are laid out, {1}.{2} or {4:02d}. Default: group 1."
},
"match": {
"type": "string",
"minLength": 1,
"description": "Glob a tag must fit to count, as git describe --match takes it."
},
"tag": {
"type": "string",
"minLength": 1,
"description": "The nearest tag in the pin's history."
},
"distance": {
"type": "integer",
"minimum": 0,
"description": "Commits the pin has that the tag lacks."
},
"of": {
"type": "string",
"minLength": 1,
"description": "The profile this one aliases."
},
"artifact": {
"type": "string",
"minLength": 1,
"description": "The package, binary or archive the version was read from."
}
},
"allOf": [
{
"if": {
"properties": {
"kind": {
"const": "file"
}
}
},
"then": {
"required": [
"path",
"pattern"
]
}
},
{
"if": {
"properties": {
"kind": {
"const": "tag"
}
}
},
"then": {
"required": [
"tag",
"distance"
]
}
},
{
"if": {
"properties": {
"kind": {
"const": "alias"
}
}
},
"then": {
"required": [
"of"
]
}
},
{
"if": {
"properties": {
"kind": {
"const": "package"
}
}
},
"then": {
"required": [
"artifact"
]
}
},
{
"if": {
"properties": {
"kind": {
"const": "file"
}
},
"required": [
"url"
]
},
"then": {
"required": [
"commit"
]
}
},
{
"if": {
"properties": {
"kind": {
"const": "unverified"
}
}
},
"then": {
"required": [
"why"
]
}
}
]
}
}
}