Warning
When binary logging is on and the connecting user lacks SUPER, trigger DDL is refused unless the global log_bin_trust_function_creators flag is 1. Run this on your MariaDB as an admin/root user (not the romm app user):
SET GLOBAL log_bin_trust_function_creators = 1;SET GLOBAL is lost on DB restart. Either add to your MariaDB my.cnf under [mysqld]:
log_bin_trust_function_creators = 1Or grant the app user the privilege (MariaDB 10.5+):
`GRANT BINLOG ADMIN ON *.* TO 'romm'@'%';` -- or: GRANT SUPER ON *.* TO 'romm'@'%';Warning
If your reverse proxy caches responses itself, or overrides/strips Cache-Control, it will defeat our built-in cache and serve a stale index.html that points at bundles the new image no longer ships, which usually shows up as a blank page or a broken UI after upgrading. After upgrading, purge your proxy's or CDN's existing cache once so clients stop being served entries stored under the old (header-less) behaviour.
Highlights
Emulator streaming
Launches a game into a native emulator running in a separate container and streams the picture, sound, and input back to your browser. Unlike EmulatorJS, the emulation runs server-side on real emulator binaries (PCSX2, Dolphin, Xemu), so the heavy lifting happens on the host rather than in the client. #3211
Important
Emulator streaming is in early development, and documentation is coming soon! If you really want to try it today, refer to this pull request in the rommapp/docs repo.
Per-field artwork priority overrides
Optional per-field artwork priority to prioritize metadata sources differently for covers, screenshots, and manuals, which fall back to the shared scan.priority.artwork. #3838
scan:
priority:
cover: # Cover art only
- igdb
- ss
screenshot: # Screenshots only
- ss
- igdb
manual: # Game manuals only
- launchbox
region_mode: prefer_rom_tags Region tags win over priority listScan settings UI
Brand new UI to edit the whole scan.* section of config.yml. #3854
Manual cover search filters
Client-side filters to the manual cover-search dialog to quickly narrow SteamGridDB results instead of scrolling through dozens of community covers. #3857
Minor changes
- feat: add file deletion to the Files tab on the game details page by @zurdi15 with @Copilot in #3753
- feat(v2): add reduced-effects mode for low-power devices by @gantoine in #3766
- feat(v2): link Hasheous provider to game detail page by @gantoine in #3783
- feat: add soundtrack gallery filter by @gantoine in #3790
- feat(playmatch): support self-hosted Playmatch instances by @gantoine in #3827
- feat: Support Range requests for multi-file ROM downloads by @tmgast in #3167
- feat: add "Open in Flashpoint" game action by @gantoine in #3845
- feat: Surface never-scanned platform folders in the scan picker by @gantoine in #3847
- feat(platforms): add editable platform descriptions by @Spinnich in #3855
- feat(v2): add random-ROM button to collections by @gantoine in #3860
- feat(v2): show smart and virtual collections on the home screen by @gantoine in #3859
- feat(scan): reassociate renamed/moved ROMs with missing entries by file hash by @gantoine in #3861
- feat(v2): auto-mark now-playing on launch + confirm launching shelved games by @gantoine in #3867
- feat: add music favorites and playlists API by @tmgast in #3896
- feat: add
scan.priority.region_modeto let config regions drive media selection by @gantoine in #3917 - feat: add Scan Settings to the user dropdown menu by @gantoine in #3923
- feat(tasks): allow orphaned resource cleanup to run on a schedule by @XenuIsWatching in #3970
Note
Environment variables
| variable | default | description |
|---|---|---|
| PLAYMATCH_API_URL | https://playmatch.retrorealm.dev/api/v2
| Use self-hosted instance of Playmatch |
| STREAMING_BROKER_SECRET | -
| Required for emulator streaming |
| STREAMING_SAVE_TIMEOUT | 45
| Save request timeout (in seconds) |
| ROMM_CORS_ALLOWED_ORIGINS | Comma-separated list of allowed CORS origins (empty allows all) | |
| ROMM_SESSION_SECURE_COOKIE | 'false
| Mark session and CSRF cookies Secure (enable when served over HTTPS) |
| MAX_ASSET_UPLOAD_SIZE_BYTES | 536870912
| Max size of a save/state/screenshot upload request in bytes (0 disables the limit) |
| MAX_AUTOCLEANUP_LIMIT | 100
| Max number of saves a client can keep per slot when autocleanup is on (minimum 1) |
Fixes
- fix(scan): resolve "Reg-" prefixed region shortcodes to full names by @TowyTowy in #3754
- fix(playmatch): handle empty heartbeat query by @DevYukine in #3756
- fix(db): pin explicit collation in virtual_collections view for MariaDB 11.6+ by @kthistlewood in #3759
- fix(v2): render match-rom covers at full width in Safari by @gantoine in #3763
- fix(migrations): make DDL idempotent on partial-failure reruns by @gantoine in #3767
- fix(v2): link IGDB provider to game page by slug by @gantoine in #3782
- fix(v2): batch gallery cover fetches into windows by @gantoine in #3765
- fix(ss): tolerate ScreenScraper's invalid JSON escapes by @gantoine in #3778
- fix(backend): lightweight eager-load for /roms/{id}/simple by @gantoine in #3779
- fix(platforms): include TGDB handler in tgdb_id fallback for supported platforms by @TowyTowy in #3785
- fix: respect configured IGDB region priority by @gantoine in #3791
- fix(retroachievements): resolve m3u playlists to natively hashed discs by @Spinnich in #3804
- fix(retroachievements): extract non-zip archives before RAHasher hashing by @Spinnich in #3813
- fix(metadata): search the whole filename for Sony serial codes by @TowyTowy in #3802
- fix(docker): proxy nginx to gunicorn over TCP instead of unix socket by @gantoine in #3810
- fix(frontend): base v2 verified badge on real DB hash matches by @gantoine in #3815
- fix(v2): render visible labels on device-auth and token expiry selects by @gantoine in #3818
- fix(igdb): don't match series games to their base title by @gantoine in #3817
- fix(scan): make v2 per-ROM "Update metadata" run the update scan type by @gantoine in #3819
- fix(v2): batch gallery hydration into windows and cap concurrency by @gantoine in #3824
- fix(v2): clear gallery selection after deleting ROMs by @gantoine in #3828
- fix(player): keep origin save bound and surface save slots in v2 EmulatorJS by @gantoine in #3831
- fix: Missing last platform-stats progressbar by @AlmostEasyGoing in #3834
- fix(netplay): correct room-list and socket URLs behind a reverse proxy by @gantoine in #3839
- fix: don't re-stamp updated_at for unchanged ROMs during scans by @gantoine in #3843
- fix: load selected file with correct extension for multi-file roms by @gantoine in #3844
- Fix v2 gallery not refetching when filter logic operator changes by @gantoine in #3840
- Fix wrong error wording for flag-only providers in setup wizard by @gantoine in #3841
- Fix slot-less save upload DB/file desync by @gantoine in #3846
- fix: enforce hidden-ROM/platform visibility on asset download and streaming endpoints by @gantoine in #3853
- fix(v2): ignore phantom/non-standard gamepads in nav polling by @gantoine in #3852
- fix(v2): overlay body-scroll-lock leaks + Library Stats label clipping by @gantoine in #3858
- fix(collections): lazy-load collection mosaic artwork by @gantoine in #3870
- fix(v2): keep collection visibility toggle in sync after save by @gantoine in #3871
- fix(db): don't use STR_TO_DATE in a generated column (MariaDB 12.3) by @gantoine in #3879
- fix(v2): take the hotkey-mute playing flag from EmulatorJS' start hook by @gantoine in #3878
- fix(archives): read RAR archives through bsdtar so they can be hashed by @gantoine in #3887
- fix(nginx): cache only fingerprinted assets, revalidate the rest by @Spinnich in #3892
- fix(v2): hide empty platforms in Server Stats breakdown by @Spinnich in #3899
- fix(scan): reconcile rom_files in place instead of purging them by @gantoine in #3900
- fix(scan): emit a client update for ROMs that are no longer missing by @gantoine in #3903
- Fix/server stats duplicate slug key by @Spinnich in #3906
- Fix Playmatch health check failing on plain-text response by @gantoine in #3916
- Stop storing fanart and title_screen twice when screenshots are enabled by @gantoine in #3918
- fix(v2): restore backdrop-filter blur in production builds by @zurdi15 in #3922
- Keep config.yaml EmulatorJS core settings active after user changes settings by @gantoine in #3920
- fix(migrations): pin device FK column collations to match devices.id by @gantoine in #3929
- fix(backend): make roms_facets/collection migrations idempotent by @gantoine in #3930
- fix(roms): list the smart collections a ROM belongs to on its detail view by @Spinnich in #3936
- fix(player): guard v2 EmulatorJS against stale saved disc id by @Spinnich in #3940
- fix(player): render ScreenScraper bezel in v2 EmulatorJS player by @Spinnich in #3944
- fix: default EmulatorJS netplay username to the RomM account by @gantoine in #3919
- fix: set page titles across v2 views by @gantoine in #3955
- fix: hide v2 actions the backend won't allow, with Playwright cover in CI by @gantoine in #3957
- fix: enforce hidden-rom visibility on rom child routes by @gantoine in #3960
- fix: always allow changing the virtual collection type in v2 settings by @gantoine in #3961
- fix: ROMM_AUTH_SECRET_KEY auto-generation under nounset by @gantoine in #3967
- fix: serve each PKG file as its own FPKGi entry by @gantoine in #3966
- fix(resources): handle write failures when the disk is full by @XenuIsWatching in #3969
- fix(tasks): skip orphaned resource cleanup when the database looks empty by @gantoine in #3971
- fix(v2): use full document navigation for EmulatorJS player by @seffignoz in #3973
- fix(scan): refuse concurrent scans and stop queued ones by @XenuIsWatching in #3974
- fix(frontend): only treat top-level game folder files as media assets by @gantoine in #3976
- fix(platforms): hide empty platforms behind a toolbar filter by @gantoine in #3982
- fix(docker): stop valkey rewriting its whole RDB every few minutes by @gantoine in #3983
- fix(gallery): pack placeholder covers at the active boxart ratio by @gantoine in #3987
- fix(launchbox): stop the cloud provider from silently matching nothing by @gantoine in #3986
Other changes
- docs: add agent repository instructions by @gantoine in #3755
- Reduce RQ worker registry sweep verbosity and frequency by @gantoine in #3731
- chore(i18n): add linter enforcing alphabetically sorted locale files by @gantoine in #3757
- perf(backend): index roms (platform_id, fs_size_bytes) by @gantoine in #3780
- perf(roms): make full rom id index opt-out on GET /api/roms by @gantoine in #3781
- revert(v2): hydrate gallery cards per-card via /roms/{id}/simple by @gantoine in #3789
- perf(backend): make roms_metadata fast via generated columns by @gantoine in #3826
- feat(platforms): add windows9x support by @gantoine in #3880
- chore: add security-audit skill for vetting diffs by @gantoine in #3872
- perf(backend): mirror ROM filter values into a narrow trigger-maintained table by @gantoine in #3885
- perf(backend): materialize virtual collection membership by @gantoine in #3886
- perf(stats): aggregate Server Stats breakdowns from roms_facets by @Spinnich in #3910
- perf(tasks): walk resource directories with os.scandir by @XenuIsWatching in #3972
- security: harden CORS, session cookies, filename sanitization, and upload limits by @Sunil56224972 in #3952
- build(deps): bump pillow from 12.2.0 to 12.3.0 by @dependabot[bot] in #3863
- build(deps): bump pydantic-settings from 2.14.1 to 2.14.2 by @dependabot[bot] in #3868
- build(deps-dev): bump fast-uri from 3.1.2 to 3.1.4 in /frontend by @dependabot[bot] in #3927
- build(deps): bump linkify-it from 5.0.1 to 5.0.2 in /frontend by @dependabot[bot] in #3926
- build(deps): bump postcss from 8.5.15 to 8.5.23 in /frontend by @dependabot[bot] in #3959
New Contributors
- @kthistlewood made their first contribution in #3759
- @AlmostEasyGoing made their first contribution in #3834
- @SaveEditors made their first contribution in #3945
- @XenuIsWatching made their first contribution in #3970
- @seffignoz made their first contribution in #3973
Full Changelog: 5.0.0...5.1.0