docs: explain setups without a ZIP

FAQ entry, the release_pack field and how to revisit it from download
counts, the get/ pages, and RetroPie 4.8 now installs from a computer with
the Pi's network folder as --dest. The start pages are back under their
word ceilings.
This commit is contained in:
Abdessamad Derraz committed 2026-10-23 17:06:54 +02:00
1 parent a2fc09a89e
commit ba3d519189
9 files changed
+101 -57

No files matched your search

+7
View File
@@ -160,6 +160,7 @@ platforms:
myplatform:
config: myplatform.yml # platform YAML filename in platforms/
status: active # active or archived
release_pack: true # optional: a release publishes its ZIP
device_group: handheld # computer, gaming-os, handheld, fpga or server
scraper: myplatform # matches PLATFORM_NAME, null if hand-maintained
schedule: weekly # re-scrape cadence, run by hand: weekly, monthly, or null
@@ -682,6 +683,12 @@ A new platform is archived-by-default nowhere: `status: active` puts it in
`status: archived` to keep the configuration without the automation. Archived
platforms are excluded unless `--all` or `--include-archived` is passed.
A new platform has no release ZIP: `release_pack: true` is set for the setups
most people download, and the installer serves every other one from its
manifest. `generate_pack.py --platform myplatform` still builds its pack.
[Which platforms get a pack](release-process.md#which-platforms-get-a-pack)
says how the list is read from download counts.
Check the output for:
- The new platform appears in verify results
+24 -22
View File
@@ -9,13 +9,13 @@ order: 50
- **Yes** for PlayStation 1 and 2, Saturn and Neo Geo.
- **Better with it** for Dreamcast: some games need it.
- **Usually not** for NES or Super Nintendo cartridges.
- **Usually not** for NES or Super Nintendo.
[What is a BIOS?](what-are-bios-files.md)
## How do I know which BIOS I need?
Run the command with `--dry-run`. It lists the files, changing nothing.
Add `--dry-run`. It lists the files, changing nothing.
<!-- os-tabs -->
```sh
@@ -24,23 +24,21 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh |
## Do I need every file of a console?
No. A console often has one BIOS per region. To keep only yours, add your
region, like `--region us`.
No. To keep only your region's BIOS, add it, like `--region us`.
## Does the BIOS set the game's language?
Rarely. It comes from the game. Some games follow the console's setting, like
Flycast's **Language** option.
Rarely. It comes from the game. Some games follow the console's setting, like Flycast's **Language**
option.
## Zip or unzip? { #zip-or-unzip }
Unzip the ZIP you downloaded into the folder your setup's page names. Keep
Unzip it into the folder your setup's page names. Leave
the ZIPs inside zipped, like `neogeo.zip`.
## Does a BIOS work on every setup?
Usually. The command installs the version each setup expects, like its
`neogeo.zip`.
Usually. The command installs each setup's own version, like its `neogeo.zip`.
## My arcade game does not start
@@ -50,35 +48,39 @@ Reference: [Which version each emulator reads](technical-faq.md#which-mame-versi
## Keys, firmware or BIOS?
- **BIOS** or **firmware**: the console's own program, like `scph5501.bin`.
- Some newer consoles need a system update, like `PS3UPDAT.PUP`, installed from the
- Newer consoles need a system update, like `PS3UPDAT.PUP`, installed from the
emulator's menu.
- **Keys** unlock encrypted games, like `prod.keys` for Switch.
## Can I play without the BIOS?
Sometimes. Some emulators carry a stand-in, and some games then fail.
Sometimes, with an emulator's stand-in, but some games fail.
## Is the command safe? { #is-piping-the-installer-into-a-shell-safe }
- It stops if the installer does not match its expected fingerprint, then
checks each file before saving it.
- It writes in your BIOS folder, and for some emulators in your save folder.
- It stops if the installer does not match its expected fingerprint, and checks
each file.
- It writes in your BIOS folder, and for some emulators your save folder.
- It never touches a game or a save.
- It keeps any file it replaces in `retrobios-backup`, next to your BIOS
folder. `--restore` puts it back.
- It keeps each file it replaces in `retrobios-backup`. `--restore` puts it
back.
Read them first: [install.sh](https://github.com/Abdess/retrobios/blob/main/install.sh),
[install.ps1](https://github.com/Abdess/retrobios/blob/main/install.ps1),
[install.py](https://github.com/Abdess/retrobios/blob/main/install.py).
[How the installer checks itself](installer.md#what-the-bootstrap-does).
## Windows or my antivirus blocks the command
Download your setup's ZIP from [Get your files](../which-pack.md) instead.
Use your setup's ZIP, if it has one: [Get your files](../which-pack.md).
## Why is there no ZIP for my setup?
ZIPs are made for the setups most people download. The command installs every
setup's files and checks each one. `--dry-run` shows the list first.
## Fill an SD card from a computer?
Yes. Name your setup and the BIOS folder on the card. For RetroArch on a Switch
Yes. Name your setup and the card's BIOS folder. For RetroArch on a Switch
card in drive `E:`:
<!-- os-tabs windows: --platform retroarch --dest E:\retroarch\cores\system -->
@@ -89,7 +91,7 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh \
## No internet on the device?
Unzip your setup's ZIP into the folder its page names. To check each file, use
Fill its folder from a computer, as above, or unzip your ZIP and check it with
`--from-pack`: [Without a network](installer.md#without-a-network-offline-install).
## My setup is not in the list
@@ -100,11 +102,11 @@ Unzip your setup's ZIP into the folder its page names. To check each file, use
## Why is a file missing from the ZIP?
Some come with the emulator, so the ZIP leaves them out.
Some come with the emulator, so the ZIP skips them.
## My game shows a black screen
A BIOS file is often missing: [When a game does not start](troubleshooting.md).
Often a missing BIOS: [When a game does not start](troubleshooting.md).
## Is this legal?
+8 -10
View File
@@ -97,7 +97,7 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh |
## 4. Wait
You can stop with Ctrl+C at any time. Run the command again to carry on.
Ctrl+C stops it. Run the command again to carry on.
## 5. Read the last line
@@ -120,7 +120,7 @@ Add `--check` to the same command. It changes nothing.
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check
```
All good when every file is present and none is wrong:
All good:
```
109/109 present (109 verified, 0 wrong hash)
@@ -130,8 +130,8 @@ An empty folder also shows `0 wrong hash`, with `0/109 present`.
## Undo
It keeps every file it replaces in a `retrobios-backup` folder, next to your
BIOS folder. The end of the run prints the line that puts them back.
Every file it replaces goes to a `retrobios-backup` folder next to your BIOS
folder. The last lines say how to put them back.
## If it stops
@@ -150,8 +150,8 @@ The message shows the command that installs Python. Run it, then run the
installer again.
A RetroPie 4.8 image has Python 3.7.3, and its update command finds nothing
newer. Use the [RetroPie ZIP](../platforms/retropie.md#download) there,
unzipped into `~/RetroPie/BIOS/`.
newer. Run the command on a computer, with
`--platform retropie --dest \\RETROPIE\bios\`.
### Error: the downloaded installer does not match its expected fingerprint.
@@ -159,13 +159,11 @@ The download was cut short. Nothing was changed. Run the command again.
### Cannot create ...
You do not have the right to write there. Do what the message says. It names
what to run.
You cannot write there. Do what the message says.
### Not enough space on the drive holding ...
It stopped before writing. Free some space, or use `--dest` to pick another
drive.
Nothing was written. Free some space, or pick another drive with `--dest`.
### The game still does not start
+2 -1
View File
@@ -22,7 +22,8 @@ order: 60
: The folder where your setup looks for BIOS files.
**Pack**
: The ZIP file with every BIOS file for one setup.
: The ZIP file with every BIOS file for one setup. Made for the setups most
people download.
**Platform**
: A setup, as the project's data calls it.
+6 -6
View File
@@ -992,8 +992,8 @@ file rather than followed.
`install.py` runs on the user's machine, often an older handheld, so it stays
on Python 3.8 and the standard library alone. The RetroPie 4.8 images
(`retropie-buster-4.8-*.img.gz`) are Debian Buster, whose `python3` is 3.7.3:
there the bootstrap stops before running anything, and the RetroPie pack from
the releases page is the way to install
there the bootstrap stops before running anything, and the way to install is
the command run on a computer with the Pi's network folder as `--dest`
([first install](first-install.md#error-python-38-or-newer-is-required)).
Tests refuse any 3.9 syntax or API, and one runs the installer end to end under
a real 3.8 interpreter, which CI installs beside 3.12 so the check cannot skip.
@@ -1167,10 +1167,10 @@ left out.
`scripts/download.py --list` and `scripts/download.sh --list` print the packs of
a release. A pack's name lists every platform it serves. Releases up to
v2026.10.10 ship RetroArch and Lakka as one `RetroArch_Lakka` pack, and the
next ones give Lakka its own, since Lakka runs on Linux where two names that
differ by case are two files. The installer and the download scripts find the
right pack either way.
v2026.10.10 ship RetroArch and Lakka as one `RetroArch_Lakka` pack. Later
releases publish packs only for the setups most people download, so Lakka,
which runs on Linux where two names that differ by case are two files, is
served by the installer. The download scripts name the installer for a setup without a pack.
Parts named `Pack.part1of2.zip` are ordinary ZIPs: unzip each one into the same
folder, and check that all of them were downloaded. The name says how many
+2 -1
View File
@@ -14,7 +14,8 @@ everyday words (BIOS, emulator, core, hash) are in the [glossary](glossary.md).
**Pack**
: One ZIP file with every BIOS file a setup uses. A pack over 2 GB comes in
several parts, and every part is needed.
several parts, and every part is needed. A release publishes packs for the
setups the registry marks `release_pack`, and the installer serves the rest.
**Profile and source_ref**
: A profile records which files one emulator opens, read from its code.
+42 -4
View File
@@ -206,8 +206,9 @@ pipeline runs here, the archives are checked here, and `gh` uploads them.
```bash
# 1. Full pipeline, online, so data directories and MAME/FBNeo hashes are
# fresh. --include-archived builds RetroPie too, archived but still served,
# and holds its pack to the same consistency and integrity checks.
# fresh. It builds the packs of the platforms marked release_pack (see
# "Which platforms get a pack" below) and the install manifests of every
# platform, RetroPie included with --include-archived.
python scripts/pipeline.py --include-archived
# 2. A release file must be under 2 GiB. A larger pack becomes parts that are
@@ -276,6 +277,43 @@ gh release list --json tagName,createdAt \
| tail -n +2 | while read tag; do gh release delete "$tag" --yes --cleanup-tag; done
```
## Which platforms get a pack { #which-platforms-get-a-pack }
`release_pack: true` in `platforms/_registry.yml` is the list. `generate_pack.py
--all` builds those packs and no other, `--verify-packs` and the consistency
step of the pipeline check those, `release_record.py` refuses any other pack
in `dist/`, and `check_release.py` reports a marked platform without a pack.
The README, the download page, each setup page and the release notes read the
same field: a platform without it shows "No ZIP" and the command. Its install
manifest is written all the same, and `generate_pack.py --platform NAME` still
builds its pack for anyone who wants one.
The list follows downloads. In v2026.10.10, part 1 of each pack was fetched
7,251 times for RetroArch, 2,909 for EmuDeck, 1,988 for RetroBat, 1,933 for
Batocera and 1,003 for RomM, then 751 for RetroPie, 642 for Recalbox, 516 for
RetroDECK, 450 for MiSTer, 386 for ROCKNIX and 361 for BizHawk. The first five
are 83% of downloads for 17 GB of the 35 GB all packs weighed. MiSTer stays
for its 17 MB. To revisit the list, read the counts of the latest release,
counting a whole pack or the first part of a split one, so each download
counts once:
```bash
gh api repos/Abdess/retrobios/releases/latest --jq '.assets[]
| select(.name | test("_BIOS_Pack(\\.part1of[0-9]+)?\\.zip$"))
| "\(.download_count)\t\(.name)"' | sort -rn
```
Then add or remove the field and regenerate the README and the site.
Every platform has a page at `get/<platform>/` on the site, its permanent
download address. It lists the files of the pack the latest release holds,
read from `release.json`, or gives the command when there is no pack. The
README, the setup pages and the release notes link it, never an asset URL:
step 6 deletes the previous tag, and with it every link to its assets. Six of
the eight links one community wiki had to our packs answered 404 that way.
Committing `release.json` in step 5 rebuilds these pages, so the release
never touches them.
## Verifying a release
`SHA256SUMS.txt` is signed with a key used for nothing else. Its public half
@@ -320,8 +358,8 @@ fingerprint, `SHA256:jUcTBhDS5DhmheXuVhAzh3pb04uI0caOAaiZzWXvrk4`.
Rotating the key means committing the new public half to `allowed_signers`
and keeping the retired line, so signatures on past releases keep verifying.
One pack per platform, the full one: the platform's list plus everything its
cores load. Platform-only and per-emulator packs are build options, not
One pack per platform marked `release_pack`, the full one: the platform's list
plus everything its cores load. Platform-only and per-emulator packs are build options, not
release assets, since a lighter pack means a core that fails with no message.
The release notes are written by `release_notes.py`: the install commands,
the pack table and its parts sentence come from `release.json`, then what
+1 -1
View File
@@ -48,7 +48,7 @@ Every module in `tests/`, by the area it guards.
| Core regression suites | synthetic | `test_e2e`, `test_audit_regressions`, `test_tool_messages` |
| File resolution and identity | synthetic + collection | `test_adler32_resolution`, `test_agnostic_scan`, `test_agnostic_scan_mode`, `test_agnostic_scope`, `test_agnostic_substitute`, `test_archive_choice`, `test_archive_recipes`, `test_bios_companions`, `test_bundled_identity`, `test_casefold_cache`, `test_db_aliases`, `test_declared_names`, `test_derivations`, `test_directory_entries`, `test_extra_identity`, `test_foreign_tree`, `test_foreign_tree_names`, `test_frontend_digest`, `test_game_data_homonyms`, `test_hashing`, `test_identity`, `test_md5_pack_context`, `test_name_tiebreak`, `test_nec_filing`, `test_owner_resolution`, `test_path_suffix`, `test_resolution_evidence`, `test_sega_filing`, `test_shipped_content`, `test_twin_declarations`, `test_validated_choice`, `test_variant_choice`, `test_variant_identity`, `test_zipped_member` |
| Verification, cross-reference and profile checks | synthetic + profiles | `test_bios_layout`, `test_cache_independent_counts`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_core_size_refusal`, `test_cross_reference_sources`, `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_entry_categories`, `test_file_consumers`, `test_fileless_audit`, `test_flycast_layout`, `test_gap_settlement`, `test_hidden_extras`, `test_launcher_aliases`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_profile_repositories`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_links`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice`, `test_verify_release_asset` |
| Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `test_minui_platform`, `test_no_game_data`, `test_pack_conformance_dirs`, `test_pack_core_extras`, `test_pack_counts`, `test_pack_destinations`, `test_pack_failures`, `test_pack_file_names`, `test_pack_grouping`, `test_pack_integrity`, `test_pack_member_identity`, `test_pack_readme`, `test_platform_inheritance`, `test_platform_keys`, `test_required_only_archives`, `test_required_only_twins`, `test_save_root`, `test_split_extras`, `test_split_names`, `test_split_pack`, `test_system_pack_extras`, `test_system_pack_parity`, `test_torrentzip`, `test_which_pack` |
| Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `test_minui_platform`, `test_no_game_data`, `test_pack_conformance_dirs`, `test_pack_core_extras`, `test_pack_counts`, `test_pack_destinations`, `test_pack_failures`, `test_pack_file_names`, `test_pack_grouping`, `test_pack_integrity`, `test_pack_member_identity`, `test_pack_readme`, `test_platform_inheritance`, `test_platform_keys`, `test_release_packs`, `test_required_only_archives`, `test_required_only_twins`, `test_save_root`, `test_split_extras`, `test_split_names`, `test_split_pack`, `test_system_pack_extras`, `test_system_pack_parity`, `test_torrentzip`, `test_which_pack` |
| Slots and regions | synthetic + profiles | `test_region`, `test_region_agnostic_scan`, `test_region_groups`, `test_region_held`, `test_region_platform_index`, `test_region_required_only`, `test_slot`, `test_slots`, `test_slots_shipped_file` |
| Hardware targets and systems | synthetic + target files | `test_extract_targets`, `test_lakka_targets`, `test_libretro_slugs`, `test_system_ids`, `test_system_selection`, `test_target_names`, `test_target_scrapers`, `test_target_systems`, `test_target_verify` |
| Installer and downloads | loopback server | `test_check_release`, `test_download`, `test_install`, `test_install_cores`, `test_install_experience`, `test_install_offline`, `test_install_selection` |
+9 -12
View File
@@ -24,25 +24,23 @@ Read the count line:
1/109 present (0 verified, 1 wrong hash)
```
- **`wrong hash`**: another region, model, or damaged. Batocera says
`UNTESTED`.
- **`wrong hash`**: another region or model, or damaged.
- **Fewer present than the total**: files are missing.
- **A line under a file**, like `still zipped`, says what to fix.
- **`0 wrong hash`, all present**: go to step 3.
## 2. Fix the files
Run it again without `--check`. It adds missing files and replaces wrong ones.
Run it without `--check`. It adds missing files and replaces wrong ones.
## 3. Check the folder and the names
- **Right folder?** [Get your files](../which-pack.md) names the one your setup
reads.
- **Right folder?** [Get your files](../which-pack.md) names it.
- **Exact name?** `scph5501.bin` and `SCPH-5501.BIN` differ. On Linux,
capitals count too.
- **A `bios` folder inside your BIOS folder?** Move its files up one level.
- **Unzipped by hand on Linux?** Run the command once. It adds names that
differ by capitals only.
- **Unzipped by hand on Linux?** The command adds names that differ by
capitals.
- **A ZIP in parts, like `Pack.part1of2.zip`?** Unzip every part into one
folder.
@@ -58,17 +56,16 @@ version.
## The BIOS is fine, the game still fails
- **Another emulator?** Each one reads its own files. Its page lists them.
- **Another emulator?** Each reads its own files, listed on its page.
- **A BIOS setting?** Some emulators can skip the BIOS. In PCSX ReARMed, set
**BIOS Selection** to **Auto**.
- **A disc game in several files?** Open its `.cue` or `.m3u` file, not a
`.bin`.
- **A disc in several files?** Open its `.cue` or `.m3u`, not a `.bin`.
## If the command fails { #installation-script-fails }
- **Network error:** try again once github.com opens.
- **`The clock reads ...`:** the date is wrong. Let it sync over Wi-Fi, or set
it, then run again.
- **`The clock reads ...`:** the date is wrong. Sync it over Wi-Fi or set it,
then run again.
- **Permission denied:** do what the message says. It names what to run.
- **No setup found:** name it and its folder: