Files
libretro/platforms
Abdessamad Derraz 74f4e301a6 fix: one card reading and one offline wording
card_choice is the one reading of a card's root for --dest, the setup
list with --dest, a card listed, browsed, typed or numbered: a blank
stick named for KNULLI, ROCKNIX or a system no card file names gets its
folder below the root and the same note on the screen and in line mode,
kept on Create the folder? and the plan. The MinUI family refuses a blank
--dest. A card mounted as BIOS is that card, a folder inside another
system's card is refused up to the drive's mount point, a list named for
another system's card gets a note, a refused --dest emits an error
event. AmberELEC and EmuELEC get a card setup.

Offline, every surface says missing, not failed: no retry line, no
--from after --from, Nothing installed when nothing was, --check counts
what needs the internet, a suggested command keeps --offline.

Drive letters under WSL for every path option, shown as D:\.

The setup list names each card system's devices and puts the cards after
RetroArch when nothing is found (Onion: 4 presses at 40x12, was 10), the
filter and the line menu take a device name, one match is chosen in one
press. Line mode names the BIOS folder and the card picked, leaves the
save directory files out before its menu, offers f) to copy from a
folder. Confirm shows no Install while it counts, Back from the systems
lands on Install, help keeps its column, one spelling per device.
2026-10-27 06:10:48 +01:00
..

Platform Configs

How platform YAML files work and where subdirectory requirements come from.

Files

  • _registry.yml -- platform metadata (name, status, display order)
  • _shared.yml -- shared file groups with canonical destinations
  • <platform>.yml -- per-platform BIOS declarations
  • Inheritance: lakka.yml inherits retroarch, retropie.yml inherits retroarch

Shared groups (_shared.yml)

The subdirectory a BIOS goes into is determined by the libretro core, not the platform. NP2kai expects np2kai/BIOS.ROM whether you're on RetroArch, Batocera, or Recalbox. Only base_destination varies (system/ vs bios/).

Shared groups define files with correct destinations once. Platforms reference them via includes: [group_name] in their system definitions. load_platform_config() in common.py resolves includes at load time, deduplicating by filename.

When to use shared groups: whenever 2+ platforms share files that a core expects in a specific subdirectory. The group carries the correct destination so platforms can't drift.

For RetroArch specifically, libretro_scraper.py injects includes: references and applies subdirectory prefixes via CORE_SUBDIR_MAP during generation. Manual edits to retroarch.yml will be overwritten on next scrape.

Data directories (_data_dirs.yml)

Some cores need entire directory trees, not just individual BIOS files. Dolphin needs dolphin-emu/Sys/ (GameSettings, DSP firmware, fonts), PPSSPP needs PPSSPP/ (font assets, shaders), blueMSX needs Databases/ and Machines/ (machine configs).

These are defined in _data_dirs.yml as a central registry with upstream source URLs. The pack generator auto-refreshes from upstream before building (use --offline to skip). Data directories live in data/ (not bios/) and are NOT indexed in database.json.

Adding a data directory:

  1. Add entry to _data_dirs.yml with source URL, extraction path, cache location
  2. Reference via data_directories: [{ref: key, destination: path}] in platform systems
  3. For scraper-generated platforms, add to SYSTEM_DATA_DIRS in the scraper
  4. Run python scripts/refresh_data_dirs.py --key <name> to populate the cache

Subdirectory reference

Each entry documents where the requirement comes from. Check these source files to verify or update the paths.

Core Subdirectory Source
NP2kai np2kai/ libretro-np2kai/sdl/libretro.c
PX68k keropi/ px68k/libretro/libretro.c
QUASI88 quasi88/ quasi88/src/libretro.c
Kronos kronos/ libretro-kronos/libretro/libretro.c
ep128emu ep128emu/rom/ ep128emu-core/src/libretro.cpp
Flycast dc/ flycast/shell/libretro/libretro.cpp
FBNeo NeoCD neocd/ fbneo/src/burn/drv/neogeo/neo_run.cpp
Fuse fuse/ fuse-libretro/fuse/settings.c
hatari hatari/tos/ hatari/src/tos.c

Full libretro docs: https://docs.libretro.com/library/<core>/

Adding a platform

  1. Create platforms/<name>.yml
  2. Set base_destination (system or bios), verification_mode, hash_type
  3. Use includes: [group] for systems with subdirectory requirements
  4. Use inherits: retroarch to share RetroArch's file set
  5. Add platform-specific overrides in overrides.systems
  6. Test: python scripts/verify.py --platform <name>

Adding a shared group

  1. Add the group to _shared.yml with a source ref comment
  2. Include: filename, destination with subdirectory prefix, required flag, hashes
  3. Reference via includes: [group_name] in platform system definitions
  4. For scraper-generated platforms, add the mapping in the scraper's SYSTEM_SHARED_GROUPS dict so it persists across regeneration

Verification modes

Platform Mode Native logic Upstream source
RetroArch existence path_is_valid() -- file exists core_info.c
Lakka existence inherits RetroArch idem
RetroPie existence inherits RetroArch idem
Batocera md5 md5sum() + checkInsideZip() batocera-systems
RetroBat md5 MD5 check via JSON config batocera-systems.json
EmuDeck md5 MD5 whitelist per system checkBIOS.sh
Recalbox md5 multi-hash comma-separated es_bios.xml + Bios.cpp
RetroDECK md5 MD5 per file via component manifests api_data_processing.sh
RomM md5 size + any hash (MD5/SHA1/CRC32) firmware.py
ROCKNIX md5 md5sum() + checkInsideZip() with altmd5 rocknix-systems
MiSTer FPGA md5 MD5 of the file at its destination process_db_index_worker.py
BizHawk sha1 SHA1 per firmware entry FirmwareDatabase.cs