emulatorLauncher 228731e0 lists ten PS2 BIOS in one group: one held file
is enough and Program.cs reports the others OPTIONAL. The scraper keeps
group and optional, verify and the pack check apply the same rule.
With no required firmware among the bundled entries the line read
'20 (20 more, --verbose lists them)'. It now reads '20 (--verbose lists
them)', and reading-reports.md quotes the run as it prints.
Only verify.py and generate_pack.py moved to the repository root. From
any other folder slots, region_audit, provenance_report and bundled_only
said database.json was missing and to rebuild it, identity and
list_platforms named a missing folder, and game_rules ended on a
FileNotFoundError traceback. work_from_repo_root moves to common.py and
the eight tools call it: defaults are read from the root, a path the
user typed from where it was typed.
Without --verbose each missing core file was followed by a bare '[size]'
line that told the reader nothing. It now reads 'validates size', the
verbose wording without the expected values.
'Bundled with their emulator, not collected: 154' listed the 14 required
firmware names and nothing said the rest existed. The line now ends with
'139 more, --verbose lists them', as the Core files line does.
MiSTer and BizHawk declare cores: []. --region, --one-per-slot and
--no-game-data read the profiles of the cores a platform runs, so their
packs and manifests withdrew nothing under a name and README that said
they had. generate_pack and verify now refuse the flags for a named
platform and leave it out under --all.
A mistyped --system said '--list-systems lists all 579' and the listing
prints 532: the hint counted every spelling across profiles, and
system_index merges the ones that differ in case or separator before
printing. Both verify.py and generate_pack.py now pass that count to
suggest_names, whose listed parameter exists for this case.
The closing summary of verify --all grouped platform to names: sfiii2a.zip,
missing on 15 platforms, was printed 15 times on a 1 060-character line and
counted 24 files for 10 distinct ones. It now groups by file and names the
platforms by the shorter side (every platform but BizHawk, MinUI, MiSTer
FPGA).
_ships and _emulator_ships resolved without the data directories, the
archive index and the slot override the builder uses: 400 platform
declarations and 178 emulator entries read as missing while the pack
held them.
RetroPie was the only platform with status: archived, which kept it out
of verify --all, slots, the pipeline and list_platforms unless
--include-archived was typed. release_pack already decides which packs a
release publishes and the installer serves every platform, so the status
set nothing apart. The field, its schema entry and the flag are gone, and
RetroPie is covered by every full run like any other platform.
reading-reports quotes a RetroDECK run, which now prints the bundled count and 30 missing game data instead of 38. The comment introducing the bundled names also loses its semicolon.
verify counted game data installed with its emulator as missing, which cross_reference files as bundled: 24 of Batocera's 427. Bundled firmware already left the lists, and the line naming it never printed. Every bundled entry is now counted on that line, required firmware named and the rest under --verbose.
The previous commit counted a name with no resolved copy as not held, which also dropped release assets the builder holds while no copy is on disk (test_install_selection AHeldFileTheInstallerCannotFetch). Only the case-insensitive name match now leaves out copies in another emulator's tree, as resolve_local_file does.
dosbox-x's et4000.bin matched only pcem's et4000.BIN. resolve_local_file, asked as dosbox-x, refuses another emulator's tree in its case-insensitive step, so the pack and installer leave it out, while the gap report and verify's core files resolved without the asker and counted it held. Both now resolve as the profile, and the manifests of Batocera and KNULLI no longer flag it held.
The --destinations branch of _main rebound held, the ExitStack that
holds the data directory locks, to the dict it writes. It is now
named destinations, and a test refuses a rebinding of the stack.
A platform entry that resolves only through a data directory tree read as missing with no cause on a checkout where data/ was never refreshed, while an online pack build refreshes the trees and packs it. verify_platform now reports the uncached trees and prints them when files are missing.
generate_emulator_pack resolves with offline=offline and fetches a release asset the cache lacks, while verify_emulator resolved offline and called it missing. verify --emulator now applies pending_release_asset as verify --platform does, accepts --offline, and the pipeline compares emulator packs offline on both sides.
cross_reference --platform listed core files the platform's launcher already settles, as Batocera's DuckStation scph1002a.bin while the PAL slot holds scph5502.bin. It now hands the launcher layer the same entries verify does, and counts what it settles as set aside.
Step 5 builds the --required-only, --no-game-data, --region, --target
and --system packs of every platform in memory and compares their paths
with verify run under the same narrowing. verify_platform gains
required_only, generate_pack a record mode. A run samples three regions,
targets and systems per platform (155 packs, about 3 minutes);
--full-narrowings compares all 1,150 (25 minutes). A test fails when
_narrowings() gains a dimension that is neither compared nor exempted.
Step 5 built emulator packs one profile at a time, where two profiles never share a path. It now also builds each system pack that gathers several profiles and compares it with verify. The first run found five standalone MSX and ColecoVision packs where verify skipped the data tree of a profile the system filter left without files, and credited msx-emu's copies the pack never wrote. verify now places those trees too: 541 system packs, all equal.
verify --platform recalbox --system nec-pc-engine printed no Core files line while the pack held six syscard copies for geargrafx: the section returned on an empty gap report before reading packed_extras. It now prints the pack's counts whenever they are not zero.
install.py took --list-platforms, generate_pack.py --list and verify.py
nothing. Both tools now take --list-platforms and print the same list
from common.py. generate_pack.py keeps --list (finding 80).
A system the target leaves no core for was verified 0/0 with exit 0,
and generate_pack blamed the platform for lacking it. Both read
platform_scope_systems and system_scope_error now (findings 13, 14).
verify_entry_existence returned no path, so RetroArch, Lakka and
RetroPie pages showed no Served by line. It now returns the resolved
path as the hash modes do. verify.py --all prints the same bytes and
its JSON is unchanged.
Batocera, KNULLI, Recalbox, RetroBat and RetroDECK hand a libretro core <saves>/<system> at each launch. Each copy lands below every system that runs the core. EmuDeck keeps one unsorted saves/retroarch/saves. The unsupported platforms record why.
load_from: save_dir entries of a libretro build were left out of every
pack. They now go below the platform's save folder (registry
save_directory: RetroArch saves/, Lakka savefiles/, by core), the
manifest marks them root: save, and verify replays the same placement.
Platforms keeping saves per system or per game list them as omitted.
A system that lists the cores it runs is settled by those cores alone, so an unprofiled core of another system no longer leaves its entries open. Readers whose core runs the entry's system are named first, and cores that only share the file name are listed as such.
Two test modules still unpacked nine values from verify_pack_against_platform. The category evidence joined readers with semicolons, which the prose rule refuses on generated pages, and three comments used clause semicolons.
The install manifest marks each game data file "category": "game_data":
a platform entry only game data profile entries read, or a core file its
profile declares game data. Firmware carries no category. Every manifest
says "categorized": true so the installer can refuse an older list.
generate_pack.py --no-game-data cuts those files from the platform list
and the core profiles before the build, names each one with the cores that
read it as game data, and tags the pack _NoGameData through _narrowings.
verify.py and the pack check take the same cut, so --verify-packs and the
report describe the pack the builder wrote. Modes without a platform
(--emulator, --system alone, --from-md5) and --all-variants refuse it.
Held entries carry their category and readers too, not only missing ones, so each platform page says which cores read every file it lists and where the code does it. Severity still applies to firmware gaps only.
Each missing platform entry now carries its evidence: the profile entries that read it with their source reference, the cores of its system examined without finding a reader, or why the question stays open. verify --verbose prints it, --json carries it and the platform pages show it.
A platform list can name a game's data files or a file no core it runs opens. Verify gives each missing entry a category read from the profiles of the platform's cores: firmware, game data or unread. Only firmware gaps carry a severity and fail --strict; the others are counted on their own line, and the pack check no longer counts them as pack errors. Missing firmware stays a conformance error.
A platform can hand each libretro core a system directory of its own
(core_system_dirs). platform_layouts then gives one view per directory,
so the gap report, the builder, the manifest, slots and cross_reference
place a core's files below each folder it is handed, and a core handed
none gets no file. Resolution strips the folder again and searches the
collection by the core's own path.