Files
libretro/schemas/platform.schema.json
T
Abdessamad Derraz 3129eaf10c feat: bind config launcher records on evidence
A launcher record citing a config, option or feature file binds only
when the platform's code installs the file (installs), its launch code
was read for what replaces it (overrides), and the emulator's profile
shows where the shipped build loads it and reads each key
(config_reads, read at pin_build). Unproven records place no file and
hand no directory. verify, cross_reference and the platform page list
them apart, outside severity and --strict.
2026-11-11 11:03:47 +01:00

639 lines
22 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://abdess.github.io/retrobios/api/v1/schemas/platform.schema.json",
"title": "Platform Configuration",
"description": "Schema for retrogaming platform BIOS configuration files",
"type": "object",
"additionalProperties": false,
"required": [
"platform"
],
"properties": {
"inherits": {
"type": "string",
"description": "Parent platform config to inherit from (e.g., 'retroarch')"
},
"platform": {
"type": "string",
"description": "Platform display name"
},
"version": {
"type": "string",
"description": "Platform version"
},
"dat_version": {
"type": "string"
},
"cores": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
]
},
"standalone_cores": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"installable_cores": {
"description": "Buildbot libretro cores the platform's RetroArch core downloader installs on at least one board, from the RetroArch targets entry of that board's architecture.",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"dual_mode_cores": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true,
"description": "Emulators of standalone_cores the platform also launches as a libretro core: both layouts get their files"
},
"libretro_systems": {
"type": "object",
"description": "libretro core name -> the systems the platform's system list offers it for, as the launcher names them. A launcher handing each core <save directory>/<system> (save_directory.by_system in the registry) places a file the core reads below its save directory once in each of these folders",
"additionalProperties": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1,
"pattern": "^[^/\\\\]+$"
}
}
},
"core_system_dirs": {
"type": "object",
"description": "The libretro system directory the platform hands each core, keyed by that directory relative to the pack root. A platform that declares it gives a core no other directory: the core's files are placed below each directory listed for it, and a core listed nowhere gets none (MinUI hands each launch tag its own Bios/<TAG>/)",
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"required": [
"cores",
"source_ref"
],
"properties": {
"cores": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string"
},
"description": "Libretro cores the platform starts with this directory, by the name of their .so"
},
"devices": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
},
"description": "Devices whose build ships a launcher for this directory"
},
"source_ref": {
"type": "string",
"description": "file:line of the launcher that names the core, at the revision `source` pins"
}
}
}
},
"core_repositories": {
"type": "object",
"description": "Repositories each core of core_system_dirs is built from, read from the platform's build recipes",
"additionalProperties": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
}
}
},
"system_directory_ref": {
"type": "string",
"description": "file:line, at the revision `source` pins, of the code that sets the system directory core_system_dirs lists"
},
"homepage": {
"type": "string",
"format": "uri",
"description": "Platform homepage URL"
},
"source": {
"type": "string",
"description": "URL to source BIOS requirements list"
},
"base_destination": {
"type": "string",
"description": "Base directory for BIOS files on this platform"
},
"core_destination": {
"type": "string",
"minLength": 1,
"description": "With an empty base_destination, the directory core files go under (AmberELEC and EmuELEC declare bios/, neogeo/ and ports/ from /storage/roms, and their cores read bios/)"
},
"hash_type": {
"type": "string",
"enum": [
"sha1",
"md5",
"crc32",
"sha256"
],
"description": "Primary hash algorithm used by this platform"
},
"hash_rule": {
"type": "string",
"enum": [
"size_and_any_hash"
],
"description": "How a digest-mode frontend accepts a file when it is not one digest: size_and_any_hash requires the declared size, then any one of md5, sha1 and crc32 (RomM)"
},
"verification_mode": {
"type": "string",
"enum": [
"existence",
"md5",
"sha1"
],
"default": "existence",
"description": "How the platform verifies BIOS at runtime: existence (file exists), md5 (checks MD5 hash), sha1 (checks SHA1 hash)"
},
"systems": {
"type": "object",
"description": "Systems/consoles supported by this platform",
"additionalProperties": {
"$ref": "#/$defs/system"
}
},
"launchers": {
"type": "array",
"description": "What the platform's own launch code looks for and hands to each emulator or core, read by its scraper at the revision `source` pins",
"items": {
"$ref": "#/$defs/launcher"
}
},
"overrides": {
"type": "object",
"additionalProperties": false,
"description": "Override inherited system configs",
"properties": {
"systems": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/system"
}
}
}
},
"configs_root": {
"description": "Where the frontend keeps its emulators' configs, as its own path code builds it (Batocera's batoceraPaths CONFIGS): path as the OS spells it, from_bios relative to the BIOS folder. A launcher that starts an emulator from a folder below it (shadPS4's configs/shadps4) places that emulator's user folder there, and the install manifest writes such a file as root: configs.",
"type": "object",
"additionalProperties": false,
"required": [
"path",
"from_bios",
"source_ref"
],
"properties": {
"path": {
"type": "string",
"minLength": 1
},
"from_bios": {
"type": "string",
"minLength": 1
},
"source_ref": {
"type": "string",
"minLength": 1
}
}
}
},
"$defs": {
"launcher": {
"type": "object",
"additionalProperties": false,
"required": [
"emulator",
"build",
"kind",
"names",
"source_ref"
],
"properties": {
"emulator": {
"type": "string",
"description": "Emulator or core as the platform names it (comma-separated when one code path serves several)"
},
"build": {
"type": "string",
"enum": [
"standalone",
"libretro"
]
},
"kind": {
"type": "string",
"enum": [
"names_searched",
"fixed_name",
"core_option",
"passes_path",
"links",
"copies",
"moves",
"scans_dir",
"package"
],
"description": "names_searched: tries the names in order, first found wins. fixed_name: writes or opens one path per name. core_option: sets a core option whose value names the file. passes_path: hands over a directory. links, copies: links or copies a file to where the emulator reads it (a copy names its files under search_dir, the folder it copies from, passes_to is the target, and the case that skips it is in depends_on_option). moves: moves a file the user left in one folder to the folder the launcher links from. scans_dir: the emulator picks from a directory. package: names no file, records what a package builds (`repo`) and the systems it registers (`systems`)"
},
"package": {
"type": "string",
"description": "The platform package whose script this record comes from, when the platform installs emulators as packages"
},
"repo": {
"type": "string",
"description": "What the package fetches and builds, as its script declares it: method, URL, then branch or commit"
},
"systems": {
"type": "array",
"items": {
"type": "string"
},
"description": "Systems the package registers, under the platform's own names, in the order the script adds them. On a record handing a directory, the systems it is written for: the record applies to an emulator launched for one of them, and replaces there what the records naming no system hand"
},
"machines": {
"type": "array",
"items": {
"type": "string"
},
"description": "On a record naming systems, the machines the platform offers the emulator under them, as the emulator names them: an entry of a profile system spelled like one of them is launched for those systems"
},
"slot": {
"type": "string",
"description": "The key the launcher files this list under, such as a region or a machine"
},
"names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Names relative to search_dir, in the order the code tries or writes them. A {X} placeholder is expanded from `expands`"
},
"expands": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
},
"description": "Values a placeholder in `names` takes, in the order the code tries them for each name"
},
"case_insensitive": {
"type": "boolean",
"description": "Whether the launcher matches names regardless of case"
},
"search_dir": {
"type": "string",
"description": "Directory the launcher looks in, as the code resolves it. <system> stands for the platform system the emulator is launched for"
},
"passes_to": {
"type": "string",
"description": "Where the found file is handed to the emulator: config key, command-line flag or core option"
},
"fails_when_missing": {
"oneOf": [
{
"type": "boolean"
},
{
"type": "string"
}
],
"description": "False when the launcher starts without the file, else the message it raises"
},
"fails_scope": {
"type": "string",
"enum": [
"emulator"
],
"description": "emulator: the failure is raised only when every record of this emulator with the same source_ref found nothing"
},
"depends_on_option": {
"type": "string",
"description": "Options or conditions in the launcher code that decide whether this record applies"
},
"device": {
"type": "string",
"description": "Devices whose shipped config this record reads, comma-separated, set only where the configs of a package differ between devices"
},
"installs": {
"type": "object",
"additionalProperties": false,
"required": ["path", "source_ref"],
"properties": {
"path": {"type": "string", "minLength": 1, "description": "Where the config the record cites lands on the device, as the platform's code spells it"},
"source_ref": {"type": "string", "minLength": 1, "description": "path:lines of the code that puts it there"}
},
"description": "How the config file a record cites reaches the emulator: link (a) of the evidence a config record carries"
},
"kept_if_present": {
"type": "boolean",
"description": "True when the install leaves a file already there in place (cp if absent, rsync --ignore-existing): the record holds on a fresh install"
},
"overrides": {
"type": "array",
"items": {"type": "string"},
"description": "path:lines of launch code that rewrites the record's keys or replaces the installed config, empty when the launch path writes neither: link (b)"
},
"choices_from": {
"type": "string",
"description": "path:lines of the feature or option file (es_features, a core .opt) listing the values the option the record writes takes. It is never the record's evidence: source_ref cites the code writing the choice"
},
"source_ref": {
"type": "string",
"description": "path:lines in the platform's repository at the pinned revision"
}
}
},
"system": {
"type": "object",
"additionalProperties": false,
"properties": {
"core": {
"type": "string",
"description": "Emulator core name"
},
"cores": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true,
"description": "The emulators and cores the platform's system list offers this system, as the platform writes them, in its order"
},
"manufacturer": {
"type": "string",
"description": "Hardware manufacturer"
},
"name": {
"type": "string"
},
"native_id": {
"type": "string"
},
"dat_version": {
"type": "string",
"description": "Version of the DAT file used as source for BIOS hashes"
},
"source": {
"type": "string",
"description": "URL or reference to the source of BIOS requirements"
},
"release_year": {
"type": "integer",
"minimum": 1970,
"maximum": 2030,
"description": "Console release year"
},
"docs": {
"type": "string",
"format": "uri",
"description": "Documentation URL"
},
"includes": {
"type": "array",
"items": {
"type": "string"
},
"description": "Shared BIOS groups to include (from _shared.yml)"
},
"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"
}
}
}
},
"files": {
"type": "array",
"items": {
"$ref": "#/$defs/bios_file"
},
"description": "BIOS files required for this system"
},
"native_check": {
"type": "object",
"additionalProperties": false,
"description": "EmuDeck: the shape of the shell check written for this system",
"properties": {
"kind": {
"type": "string",
"enum": [
"md5",
"file-exists"
]
},
"function": {
"type": "string"
},
"var": {
"type": "string"
},
"array": {
"type": "string"
},
"firmware": {
"type": "string"
},
"keys": {
"type": "string"
}
}
}
}
},
"bios_file": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"destination"
],
"properties": {
"name": {
"type": "string",
"description": "BIOS filename"
},
"sha1": {
"type": "string",
"pattern": "^[a-f0-9]{40}$",
"description": "SHA1 hash"
},
"md5": {
"type": "string",
"pattern": "^[a-fA-F0-9]{32}(,[a-fA-F0-9]{32})*$",
"description": "MD5 hash (comma-separated for multi-hash)"
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "SHA256 hash"
},
"crc32": {
"type": "string",
"pattern": "^[a-f0-9A-F0-9]{8}$",
"description": "CRC32 hash"
},
"size": {
"type": "integer",
"minimum": 0,
"description": "File size in bytes"
},
"destination": {
"type": "string",
"description": "Destination path relative to base_destination"
},
"required": {
"type": "boolean",
"default": true,
"description": "Whether this BIOS is required for the core to function"
},
"extract": {
"type": "boolean",
"default": false,
"description": "Extract ZIP contents instead of copying the ZIP"
},
"storage": {
"type": "string",
"enum": [
"embedded",
"external",
"user_provided",
"large_file",
"release"
],
"default": "embedded",
"description": "Storage tier: embedded (in repo), external (download at build), user_provided (manual)"
},
"source_url": {
"type": "string",
"format": "uri",
"description": "Download URL for external storage tier"
},
"instructions": {
"type": "string",
"description": "Human-readable instructions (for user_provided or context)"
},
"zipped_file": {
"type": "string",
"description": "If set, the MD5 hash refers to this file inside the ZIP, not the ZIP itself"
},
"native_system": {
"type": "string",
"description": "System id the platform itself uses for this file"
},
"mirror_of": {
"type": "string",
"description": "Native system whose entry this one repeats. The platform's own file does not carry the copy"
},
"curated": {
"type": "boolean",
"description": "Added by our scraper from the cores' source, not declared in the platform's own file"
},
"shared_group": {
"type": "string",
"description": "Set on load, never written in a platform file: the entry joined the system from this group of _shared.yml, named by the system's includes. The platform's own file does not carry it"
},
"zip_digest": {
"const": "composite",
"description": "Set on load, never written in a platform file: the md5 of this ZIP is the md5 of its members concatenated in name order, as Recalbox computes it, never the md5 of the archive bytes"
},
"native_name": {
"type": "string",
"description": "Display name the platform gives its own system"
},
"group": {
"type": "string",
"description": "RetroBat: files sharing a group are alternatives. One held is enough and the others are reported OPTIONAL"
},
"md5_list": {
"type": "boolean",
"description": "Batocera: the platform writes md5 as a list of strings, any of which matches. md5 holds the items comma-joined, in order"
},
"alt_md5": {
"type": "string",
"pattern": "^[a-fA-F0-9]{32}(,[a-fA-F0-9]{32})*$",
"description": "Second accepted MD5 (Batocera altmd5, ROCKNIX altmd5)"
},
"core": {
"type": "string",
"description": "Cores the platform names for this file (comma-separated)"
},
"note": {
"type": "string",
"description": "Free-text note the platform attaches to this file"
},
"description": {
"type": "string",
"description": "Description the platform attaches to this file"
},
"hash_match_mandatory": {
"type": "boolean",
"description": "Recalbox: a hash mismatch is an error, not a warning"
},
"mandatory_declared": {
"type": "boolean",
"description": "Recalbox: mandatory was stated explicitly, not defaulted"
},
"required_label": {
"type": "string",
"description": "RetroDECK: the requirement wording, which is free text"
},
"component": {
"type": "string",
"description": "RetroDECK: the component whose manifest declares this file"
},
"alt_paths": {
"type": "array",
"items": {
"type": "string"
},
"description": "Further paths the platform accepts for the same file"
},
"native_path": {
"type": "string",
"description": "How the platform itself writes this file reference"
}
}
}
}
}