--standalone-copies named Linux and Windows folders for Azahar's aes_keys.txt and boot9.bin and Flycast's dc_boot.bin and dc_nvmem.bin, and nothing for macOS, where both emulators read a fixed folder: ~/Library/Application Support/Azahar/sysdata (common_paths.h:36,61) and ~/Library/Application Support/Flycast/data (osx-main.mm:83-101). A test now requires a macOS folder on every copy.
Basilisk II opens a file named ROM, checks its size, its version word and the code PatchROM rewrites, and no hash. By name the only candidate was the 128 KB Apple IIGS ROM, which the size gate rejects, so the pack shipped nothing. The collection's mac.rom (Performa/Quadra 630, version 0x067c) passes every gate, and the entry now names it as an alias. KEGS and GSplus keep the IIGS file.
DOSBox Pure builds every Sound Canvas companion name from the ROM1 file the user picks and reads the third wave ROM only for an SC-55 mk1 or CM-300 (midi_sc55.h:71-124). The profile put every model in the SC-55/ folder holding the mkII set, so WAVEROM3 could never be met. The mkII group stays there, and the v1.00 mk1 set the collection holds gets its own folder under the names the code builds from sc55_rom1.bin.
DSperate reads TWLFontTable.dat for DSiWare run without a NAND. The file sits in nand:/sys/ of the DSi NAND dumps the collection holds. Decrypted with the console ID and CID in each dump's nocash footer, as DSperate's own NAND reader does, the four western and Japanese consoles give one table, the Chinese and Korean ones their own: 863296, 581664 and 162688 bytes, the sizes and sha1 already known for them.
POM2 reads nine Virtual ][ sounds from roms/virtual_ii_sons/. All nine are inside VirtualII.dmg from virtualii.com (13.3). The five AIFF files are taken as they are. The four .raw files are signed 16-bit little-endian mono at 44100 Hz, as Virtual ]['s own playback code declares them, and are wrapped in a WAV header, the data chunk being the raw file byte for byte. pom2 verifies 78/78.
A platform named but not found fell back to a folder it never opens: ~/bios for RetroBat on Linux and for BizHawk picked from the menu, and on Windows the embedded systems' /userdata/bios, which resolves to the root of the current drive. Each run downloaded gigabytes and reported done. Where no folder on the OS is one the platform reads, a forced run now asks for --dest and the menu asks for a path with no default.
Lakka's image writes the board in /etc/os-release: LIBREELEC_DEVICE when built for a device, LIBREELEC_PROJECT otherwise, the very names of our Lakka targets. The installer read the board on Batocera, Recalbox and ROCKNIX only, so a Lakka RPi4 installed 5.7 GB of every board's files where its own needs 4.0.
The buildbot publishes .so cores for OpenDingux (mips32, its beta and RS-90 builds), RetroFW, MiyooCFW and webOS (armv7a, aarch64), 7 to 206 cores each. None was a target, so a handheld or TV user could not narrow a pack or an install to the board. They are scraped now, with opendingux, retrofw, miyoo and webos as aliases.
The buildbot now publishes gametank, a libretro port of GameTankEmulator by SundownerSport. The console has no boot ROM and the core opens no system file, only its flash save in the save directory. Every buildbot core name must reach a profile, or target filtering skips it.
The project bans a short list of marketing words in what it publishes, and no test read for them: the site's platform table described Recalbox's interface with one. The line now says what Recalbox does, and test_prose_style fails on any of those words in a tracked file.
The test skipped when slots stopped claiming pcem's ide_xt.bin. The profile declares it and the collection holds three copies, so that skip could only hide a claiming defect. It now skips only when the file is not collected and fails when it is not claimed.
CONTRIBUTING and the testing guide installed pyyaml and jsonschema only, while the CI test job also installs markdown. On a contributor's machine the wiki heading test skipped and the run read OK. Both name it now, and a test compares them to the packages the tests import.
profile_sync skipped a profile whose repository no longer answers, which carries no pin, or whose declared death the forge contradicts, with empty counts. --strict counted refs to review only, so the CI job meant to stop an unchecked new profile passed a mistyped repository. Such skips now fail a strict run. An unsupported host, a declared takedown and a profile without refs stay accepted.
auto_fetch caught every network error in its repository and archive.org steps and reported the file as needing a community contribution. Offline or rate-limited, --create-issues asked the public for files the tool never looked for, and the errors counter stayed at 0. A 404 is still an answer. Any other failure now marks the file as not fully searched and keeps it out of issues.
list_registered_platforms skipped a registered platform whose YAML was missing and returned an empty list without a registry. verify --all --strict, every --all build, the CI matrix and the site then ran over fewer platforms and exited 0, and install.py kept serving the stale manifest. Both now raise and name the file.
group_identical_platforms fingerprinted each file by destination, sha1 and md5. Two platforms whose lists differed only in required, zipped_file, size or crc32, or in how the frontend checks a file, would have shared the representative's pack and verify result. The fingerprint now carries every field of every entry and the platform's verification_mode and hash_rule. No current platform is regrouped.
load_profile_hashes and load_platform_hashes read hash fields by hand: crc32 was never indexed and a comma list of sha256 stayed one key. A contribution a profile names by crc32 alone (clk's Electron os.rom, among 626 entries) or by one of mesence's four sha256 was reported as referenced nowhere. Both indexes now read through parse_hash_list, and a crc32 counts where no stronger hash is declared, bounded by the declared size.
The integrity step compared a member's md5 by hand and ignored hash_rule, so under RomM's rule (size, then any of md5, sha1 and crc32) it would refuse a revision the builder rightly shipped on its sha1. The rule now lives in digest_verdict, which the path check and the pack member check both call. The member's archive digest is computed without the path cache, whose key a buffer's reused address made collide.
When the truth takes over an entry without a size of its own, the format writes it without the platform's size: System.dat's neocdz.zip lost size 953078 and no counter said so. Removed sizes are now counted and named, and the summary counts read 1 size, 2 sizes.
The attribute pattern took letters only, so md5 never entered the comparison and an element whose digest the truth corrects kept Recalbox's text. A test written before the change caught it. The RetroDECK fixture now names the core that reads its addition, as the placement rule requires.
Every <bios> element the model held was rendered again, so attribute order, alignment, a line break inside md5 and the case of a digest changed in 222 elements that stated the same thing. The diff deleted 451 lines for 136 corrections. An element whose attributes say what Recalbox wrote now keeps Recalbox's own text: 175 lines, the corrections.
Notes were keyed by file path, so a comment before one of the items reading an archive came back before every item reading it: bk's '# MAME' twelve times. A comment after the list's opening bracket matched neither rule and was dropped (enterprise's ep128emu-core). Notes are now keyed by file and archive member, written once, and a head-line comment goes with the first item.
Additions took the component their system's entries sit in, whatever core reads them. 104 armsx2 and yaps2 files went into PCSX2's manifest, beetle_psx and rustation dumps into DuckStation's, a directxbox image into xemu's, all counted as added. An addition now lands only where a core reading it is that component's emulator: 132 additions instead of 581.
ROCKNIX registers DuckStation twice, as the libretro core under retroarch and as duckstation-sa under its own emulator. The exporter looked a standalone runner up as a core name, so standalone DuckStation's 98 additions were written for users of the libretro core, PS2 images included, and standalone ARMSX2 was refused. A libretro runner now answers with the retroarch pair, a standalone with its emulator's own.
simple64 picks the PAL PIF for the European and Australian country codes, and New Zealand carts carry one of them. Citra MMJ's AUS font archives serve the region sold in Australia and New Zealand alike. Tagged australia, a leaf New Zealand is not under, --region new-zealand dropped them. They are tagged oceania, as every other PAL file is.
jgenesis picks it for GenesisRegion::Americas, md-emu for boot byte 0x7a, ares for an NTSC-U disc: one code for every disc of the Americas, Brazilian Tec Toy releases included. The three tagged it north-america alone, so --region brazil dropped the BIOS those discs need. genesis_plus_gx and picodrive already carried both.
cross_reference printed 20 runtime components bundled with their emulator as [MISSING] and counted them among the files to source. The collection leaves them out by design, as verify and the gaps page already say. They are now listed as [BUNDLED] and counted on their own line.
With no platform named, cross_reference passed no standalone cores, so every dual profile was laid out as libretro only. The CLI and the site's gaps page left out 133 files that Batocera and RetroBat run standalone and that no platform declares (eka2l1 90, dolphin 21, cemu 11). Both now pass the union of every platform's standalone cores.
Nixie's layouts at vpinball e4a79a5, PinMAME memmaps at tomlogic/pinball-memory-maps 68c1b337 and game definitions at vpinball/pinmame-game-defs 6eece7e5: the subset every platform build copies into third-party/. 1,280 files, each matched to its upstream git blob, documented as three directory entries.
The five native libraries the reprofile added, and the assets and libraries whose copies dated from 1.8.2-open, now come from the official build of 752b93a (release continuous, CI run 39297510978, signing certificate de1bd54d as on 1.8.2). Assets match the repository blobs byte for byte. The profile carries their hashes, and the bundled-identity table now records each fall exactly.
EmuHawk finds every firmware by SHA1 against FirmwareDatabase.FirmwareRecords, and its cores are its own builds. The registry and the scraper both listed libretro cores whose systems overlap BizHawk's, so the pack shipped Clock Signal, O2EM, FBNeo, VICE and Citra files into Firmware/ that EmuHawk never reads. Both lists are now empty, as MiSTer's are: the database alone decides.
generate_readme, generate_site and slots resolve against data/ but took no hold when run on their own, as the documented commands do. A refresh swapping a tree mid-read then gave counts from half of it. Each now holds the trees shared, like verify and the builder.
Opening and locking a partial download are two steps. Between them another run could finish, rename the same file into place and release its lock. The second run then locked the installed BIOS, read its full size as a finished partial and truncated it to download again. After the lock the partial's name must still point at the locked file, or the run downloads into a private copy.
ScoreView became Nixie with .nix layouts, B2SLegacy was removed, the PinMAME plugin ships memmaps/ and gamedefs/, the HRTF file is bundled, fonts are looked up by TextRenderer and a table gets a .info file. PinMAME refs are re-read at 5386aa17, the revision the build fetches.
The native build split into m3g/ and micro3d/ makefiles, micro3d moved to ru.woesss.j2me.micro3d, c++_shared now loads ahead of every native module and MIDI can play through a user sound bank (EAS or TinySoundFont). appcenter.cer is no longer read. The new libraries are marked unsourceable until the release's own copies are collected.
Upstream moved the mouse card firmware into MouseRom.h behind ENABLE_PERIPHERAL_MOUSE, renamed the generated ROM symbols from g_rom_* to rom_*, added a hard disk controller with its own firmware and an XDG fallback for the data path. Every reference is re-read at the new pin, and Master.dsk carries the hashes the upstream build test pins.
The consistency check compared the platform's own files only. It now also compares verify's core files and game data with the builder's count of files taken from the cores.
The report counted claims, not files: several cores claim one path (rom.key by three Amiga cores, openbios.bin with and without a region) and the builder ships one file there. RetroArch read 1130 core files, 48 more than its pack. Game data ignored the in_pack marker, so RomM read 351 game data files in a pack that holds none. verify now takes both counts from its replay of the builder's placement, one per pack path.
When the forge truncates the HEAD tree, the rename search cannot see every path, yet a bare filename it did not find was reported GONE. eden's fs_paths.h and path_util.cpp exist under src/common/fs/. Such a citation is now AMBIGUOUS with the reason, as the realign path already says unclear and never absent.
jgenesis, ioquake3, yquake2, playdiaemu, samcoupe, skyline and plastic wrap a citation as `path.ext` then `:N-M` on the next line. The collector only joined a line ending with a colon or comma, so these runs were never compared and a bump moved the pin past them silently. They are now read, as wrapped runs that hold the pin until rewritten.
hypseus-singe, flycast-dojo, lindbergh-loader and vvvvvv read gamecontrollerdb.txt without naming a hash. The name step only set aside copies in other emulators' trees, so a copy in a game's folder under Game Engines/ ranked with any neutral one, and index order handed them C-Dogs' 98-line database. A game folder's copy now ranks after a neutral copy. The community SDL_GameControllerDB is collected at commit ff333823 (git blob 25146be7) as that neutral copy.
The name step refuses a candidate outside the size an entry validates, but the path step returned any hashless file at the tail as path_exact, a proof slots arbitration trusts. A 32 KB cpc6128.rom at ZEsarUX's tail would have been served for its 48 KB composite. No profile hits it today.
PCSX2x6 reads bin/resources/GameIndex.yaml, an arcade database keyed by NM gameid. The shortened tail resources/GameIndex.yaml matched four files, and the resolver set aside the three in other emulators' trees before measuring ambiguity, so PCSX2's console database passed for path proof and shipped in the PCSX2x6 pack. Ambiguity is now read before that filtering. A tail indexed from an identical copy is kept even when the database records the other copy's path.
PCSX2x6's GameIndex.yaml and RedumpDatabase.yaml are collected from its repository at the pinned 583f0e90 (git blobs ed8232e3 and 8669b3af).