Romm
ROMM Collection Manager
#R0MM ver 0.30rc
PySide6 Desktop ROM Organization System
#Recent Changes (2026-03-02)
- Fixed a PySide6 Tools tab crash when clicking "Refresh" in Collections/DATs (missing AppState refresh aliases).
- Fixed torrent search button stuck state and invokeMethod warnings in PySide6 Downloads tab.
- PySide6 startup now restores lightweight UI state immediately, but only restores heavy scan results/DAT session data when a saved snapshot exists and the user explicitly accepts the restore prompt.
- Restored a working torrent searcher in the Downloads tab with selectable Apibay/custom mirrors; magnets are sent to the JD queue.
- Downloads tab split into Torrent (search + magnets) and Direct/JD (Myrient catalog + JDownloader queue) sub-tabs.
- Downloads tab layout is now responsive for non-maximized windows: Torrent uses a compact control grid, Direct/JD uses a horizontal-or-vertical splitter, and the selected sub-tab plus staged inputs persist in UI state.
- Dashboard is now always the initial view on startup and was refocused into a real home screen: quick start, next actions, session snapshot, and transfer status, without the old news-feed dependency.
- Windows path display in PySide6 was normalized visually to backslashes in
Import & ScanOperation Preview and related elided labels/tooltips, soD:/...now renders asD:\.... - Temporary local runtime artifacts under
.tmp/are now ignored by Git so repository snapshots stay clean. - The built-in metadata scraper was removed from the active PySide6 flow.
Collectionnow prepares local Skraper manifests instead of fetching metadata remotely, andLocal DATis back to local-only suggestions. - PySide6 navigation was re-split:
Import & Scanis nowRom Managerand contains the scan/organize setup plus a transientScan Resultssub-tab that only appears after a scan in the current session. The top-levelCollectionview is now a system-grouped library browser for identified games, with per-game metadata/art refresh driven by the configured scraper source and a persistent metadata cache indata/metadata_cache.json. Rom Managernow treats scan state as a manual snapshot workflow: the current session can be saved/loaded explicitly from the UI, while automatic per-change session writes were removed to avoid large JSON stalls.- Scan progress now does a fast pre-count pass before hashing, so the Nerve Center can show the real planned workload first and the active progress bar no longer sits at
100%during file discovery. - Large PySide6 table refreshes were trimmed by disabling hot-path per-row insert churn (
setRowCount(...)+ sorting pause) and by pushing DAT activation/removal onto the existing background DAT worker queue instead of blocking the UI thread. Rom Managerleft-side setup controls now live inside a discreet vertical scroll area for smaller/non-maximized windows, preventing theOrganization Strategiesblock from being clipped. The strategy checkboxes also gained a tiny height bump so labels no longer visually eat into each other.Collectionnow uses an explicit Skraper bridge flow instead of an internal scraper: the main action understands selection context and exports the selected game, multiple selected games, or the currently focused system into a Skraper-ready manifest under the configured export folder. The detail pane still shows any already-cached local metadata/art, but the app no longer performs remote metadata fetches itself.- PySide6 startup is now always clean: there is no restore-session prompt anymore, no automatic snapshot load on boot, and no auto-restore of old working form state. The app opens directly on Dashboard with only lightweight window geometry/language restored; loading prior scan/DAT state is manual via
Rom Manager > Load Snapshot. New Sessionnow clears only the in-memory working session and keeps the saved snapshot on disk, soSave Session/Load Snapshotremains a simple manual workflow instead of destroying the last saved state.- The old ScreenScraper/TheGamesDB credential flow is no longer part of the active UI. It was replaced by a lightweight
Skraper Setupmodal with only two fields: optional localSkraper.exepath and the export folder used for generated manifests/title lists.Open Skrapernow launches the configured executable when present, or falls back to the Skraper website. - PySide6 session controls were moved out of
Rom Managerand into theDashboardheader. The old top-right dashboard shortcut buttons were removed, andLoad Snapshot,Save Session, andNew Sessionnow live in that top-right slot instead. - Non-PySide6 frontends and leftover Flutter scaffolding were archived under
_OLD/so the active release tree now focuses on the native PySide6 desktop build only. - Older
build/anddist/artifacts plus refactor helper scripts were archived under_OLD/, and the activer0mm_pyside6.specnow excludes Tk/legacy frontend modules so the rebuiltdist/R0MM/R0MM.exeis slimmer and PySide6-only. - Frozen PySide6 builds no longer bundle/copy the repository
data/tree intodist/R0MM/data/on first launch. The packaged app now creates only the empty runtime folder skeleton (dats,collections,imports, etc.) and generates defaults at runtime, so no developer DATs, collections, snapshots, or session residue leak into a fresh.exe. - The Nerve Center label previously shown as
Saude do Bancowas renamed toTaxa de Identificacaoto match what it actually measures: identified files as a percentage of current session results. - The special DAT
R0MM - Local Overridesis now pinned to the top of the active DAT list and rendered with a subtle in-theme highlight so the user's manual-match overlay is always easy to spot.
#Desktop launch modes
You can start the active desktop interface directly:
python main.pypython main.py --pyside6python -m rommanager(opens PySide6 directly)
PySide6 UI files:
rommanager/gui_pyside6_views.pyrommanager/gui_pyside6_style.qss
Windows build:
- A dedicated PySide6 build entrypoint is available at
r0mm_pyside6_entry.py. - PyInstaller spec file:
r0mm_pyside6.spec. - The packaged app now treats
data/as portable beside the frozen.exe. On first launch, bundled defaults from the PyInstaller runtime bundle are copied intodist/R0MM/data/, which then remains writable and persistent. - Use the final packaged executable at
dist/R0MM/R0MM.exe. Do not launch the intermediate PyInstaller executable frombuild/; that stub is not a distributable app and can fail with missing DLL paths.
Backup options:
- Full backup to
backups/(zip, timestamped). - Incremental-friendly backup that excludes
build/,.dart_tool/,.venv/, andbackups/. - Script:
backups/backup.ps1(run withpowershell -ExecutionPolicy Bypass -File backups/backup.ps1).
#Local Agent Access & Autonomy (Developer Sessions)
This project is frequently edited with a local coding agent. What the agent can test is determined by the session runtime (sandbox, GUI support, approvals), not only by repository code.
What the agent can usually do in a standard local session:
- Read and edit files inside the invoked project folder.
- Run shell commands and project scripts (subject to sandbox/approval policy).
- Run headless/smoke checks (imports,
py_compile, CLI commands,QT_QPA_PLATFORM=offscreentests). - Analyze terminal tracebacks and runtime logs.
What may still be limited even with full repository access:
- Interactive desktop GUI validation (PySide6/Flet) if the session does not provide GUI control/desktop streaming.
- Visual click-through testing unless the session supports screenshots + input events or remote desktop control.
- Installing dependencies or fetching online resources if network access is disabled.
To maximize agent autonomy in a trusted local session:
- Use a session mode with unrestricted filesystem access (or equivalent full access) for the project workspace.
- Enable network access when installs/updates/docs lookup are required.
- Allow command execution without repeated prompts, or approve persistent command prefixes used in this repo.
- Prefer the project virtual environment Python (
.venv\\Scripts\\python.exe) for all validation commands.
Recommended recurring command approvals/prefixes (if your session supports them):
git.venv\\Scripts\\python.exepypytestflutter
PySide6/Flet validation notes:
- The agent can launch the process and capture terminal output/crashes.
- The agent can perform headless smoke tests where supported.
- Full visual verification still requires a GUI-capable session or user-provided screenshots/logs.
Runtime/tool prerequisites for deeper testing:
- Python dependencies installed (
PySide6,flet,flask, etc.). - External tool binaries available in
PATHwhen testing Tools features (for examplechdman,dolphin-tool). - Small DAT/ROM fixtures for reproducible import/scan tests.
Practical workflow when GUI control is unavailable:
- Let the agent patch code and run headless checks.
- Run the desktop app locally and share traceback/log/screenshot output.
- The agent uses the observed runtime error to apply the next fix quickly.
#1. Overview
R0MM ver 0.30rc is a web application for scanning, identifying, analyzing, and organizing ROM collections using DAT files (XML/Logiqx and clrmamepro text DAT).
It supports:
- No-Intro
- Redump
- TOSEC
- XML-based DAT format (Logiqx-compatible)
- Plain text DAT format (clrmamepro style)
The system consists of:
- A Flask backend
- A React-based frontend
- ROM scanning + CRC32 hashing
- DAT parsing and matching engine
- Organization strategies with preview and undo
- Collection completeness analysis
The application runs locally and exposes a web interface.
#2. Architecture
#Backend: Flask Application
Core modules identified in the project:
models– data structuresparser– DAT parsing (XML + clrmamepro text)scanner– filesystem ROM scanning + hashingmatcher– ROM ↔ DAT matching logicutils– helpersshared_config– configuration layerrouter– API endpointsconfig– runtime configrun_server()– server bootstrap
The server starts on:
127.0.0.1
Default Flask configuration uses:
- host
- port
- debug
- threaded
The backend exposes API endpoints consumed by the frontend.
#Frontend: React Interface
Single-page interface rendered into #root.
Main sections:
- Identified ROMs
- Unidentified Files
- Missing ROMs
- Organization Controls
UI is styled using Tailwind-like utility classes.
#3. Core Functionalities
#3.1 DAT Loading
-
Accepts XML DAT and clrmamepro text DAT files
-
Parses games and ROM entries
-
Extracts metadata:
- Game name
- ROM name
- System
- Region
- Size
- CRC32
#3.2 ROM Scanning
Scans selected folder and computes:
- File size
- CRC32 hash
- Filename
- Path
Files are matched against loaded DAT entries.
#3.3 Matching Results
Results are separated into three logical groups:
#Identified
ROMs successfully matched against DAT:
Columns shown:
- Original file
- ROM name
- Game
- System
- Region
- Size
- CRC32
- Status
#Unidentified
Files scanned but not matched:
Columns:
- Filename
- Path
- Size
- CRC32
Selectable for further action.
#Missing
DAT entries not found in collection.
Includes completeness stats:
- Total in DAT
- Found count
- Percentage complete
- Visual progress bar
#4. Organization Engine
User-selectable organization strategies:
| Strategy ID | Description |
|---|---|
system |
Per-system folders |
1g1r |
1 Game 1 ROM (best version selection) |
region |
Region-based folders |
alphabetical |
A-Z folders |
emulationstation |
ES / RetroPie layout |
flat |
Rename only (no subfolders) |
Note: Organization output paths are sanitized for Windows-safe filenames (invalid characters like : or ? are replaced). Preview mirrors the sanitized destination paths.
#Actions
Two file operations supported:
- Copy
- Move
#Workflow
-
Load DAT
-
Scan ROM folder
-
Review identified / unidentified / missing
-
Select strategy
-
Set output folder
-
Choose Copy or Move
-
Click:
- Preview (dry run)
- Organize! (execute)
-
Optional: Undo
#5. Organization Controls
UI includes:
- Output folder field
- Strategy selector
- Action selector (Copy / Move)
- Preview button
- Organize button
- Undo button
Preview prevents accidental destructive operations.
Undo reverses last organization action.
#5.1 Tools UI (PySide6)
Tools actions are wired to core service methods. Some advanced tools currently return a “not implemented” response until the core implementations are completed.
Core tool contracts (stubs with type hints + docstrings):
- DAT Diff (Compare)
- DAT Merger
- Batch Convert (CHD/RVZ)
- Apply TorrentZip
- Deep Clean (Remove Junk)
- Find Duplicates (By Hash)
Tool implementations:
- DAT diff/merge implemented in Python.
- Batch convert requires external binaries in PATH:
chdman(CHD) anddolphin-tool(RVZ). - TorrentZip uses a deterministic ZIP repack (no external dependency).
#6. Completeness Tracking
For loaded DAT:
- Total entries in DAT
- Matched entries
- Percentage calculation
- Visual progress bar
This allows tracking full-set completion.
#7. Web Server Execution
Entry function:
run_server()
Prints:
- Host
- Port
- URL (http://127.0.0.1:PORT)
- Stop instruction (Ctrl+C)
The app runs as a local web service.
#8. Intended Use Case
Designed for users who:
- Maintain multi-system ROM collections
- Use curated DAT sets
- Want structured organization
- Want completeness visibility
- Need deterministic matching (CRC-based)
#9. Key Technical Characteristics
- DAT parsing (XML + clrmamepro text)
- CRC32 matching
- Browser-based UI
- Flask REST backend
- Modular architecture
- Strategy-based file output
- Undo capability
- Preview safety layer
#10. Version Identifier
Displayed in footer:
R0MM ver 0.30rc
Indicates this is a second-generation web-based rewrite, likely replacing a previous CLI or desktop version.
#11. Summary
R0MM ver 0.30rc is a local web application that:
- Parses DAT files
- Scans ROM collections
- Matches via CRC32
- Displays identified, unidentified, and missing ROMs
- Calculates completeness
- Organizes ROMs using selectable strategies
- Supports preview and undo
- Runs via Flask on localhost
It is a full-stack ROM management tool intended for structured archival organization.
#12. Language Selection
The app now includes a language selector in desktop menus:
- English (default)
- Português Brasileiro
Where to change:
- Launcher window:
Languagemenu - Tkinter desktop app:
Languagemenu - Flet desktop app: language dropdown in the left navigation panel
- PySide6 desktop app: language dropdown in the status bar
Default language at startup is English.
Language switching refreshes labels in the PySide6 Import/Scan view (including section titles) and the drawer feedback.
Module entry behavior:
python -m rommanagernow opens the PySide6 desktop app directly.
#13. BlindMatch mode
BlindMatch allows scanning without any DAT file.
How it works (best effort):
- User provides the system name (for example: SNES).
- The app infers region from filename tokens such as
(U),US,(E),(J),BR, etc. - All scanned files are treated as identified in this mode.
- There are no "missing ROMs" and no "unidentified" results in BlindMatch mode.
Available in:
- CLI:
--blindmatch-system <SYSTEM> - PySide6 UI: BlindMatch toggle + system input
#15. Advanced Settings foundation
R0MM now includes a shared settings foundation (~/.rommanager/settings.json) used by CLI and PySide6 runtime initialization.
Implemented foundations:
- Collection profiles by objective: historical_preservation, mister_playset, retroarch_frontend, full_set_no_hacks.
- Region/variant policy (global + per-system priority).
- Naming template engine for organized output (
{name},{game},{region},{system},{crc}). - Optional curated metadata database support (CLI:
--metadata-db). - Audit trail logging for organization actions (
~/.rommanager/logs/audit.log). - Collection health checks (duplicates, unknown extension, missing/zero files) via CLI
--health-check. - Museum organization strategy (
museum) for generation/system/region hierarchy. - Accessibility settings placeholders (font scale, high contrast, dense tables, reduced motion).
CLI additions:
--settings-file <path>--profile <preset_name>--health-check--metadata-db <path>
#16. Archived Frontends
The Flet/Web/Tkinter frontends are no longer part of the active release tree. They were archived under:
_OLD/docs/FLET_AGENT_PROTOCOL.md_OLD/rommanager/gui_flet.py_OLD/rommanager/web.py_OLD/rommanager/gui.py
The active release target is PySide6 only.
#UI Notes (PySide6)
-
Cyberpunk Industrial theme: base #1E1E1E, surface #2D2D2D, accents #39FF14, alerts #FF00FF.
-
Library drawer is persistent; empty state remains visible when no row is selected.
-
Drawer alert border toggles for Unidentified/Missing selections.
-
Nerve Center now displays a live log monitor that tails the runtime log file in real time (tab changes, scans, and errors are logged).
-
Nerve Center includes a GhostTyper easter egg (retro quotes typing animation) above the live log monitor.
-
PySide6 no longer silences terminal output; startup/runtime exceptions and Qt warnings/errors are printed to stderr, while runtime logs remain mirrored in the Nerve Center log monitor.
-
Fixed PySide6 startup crash in Nerve Center by initializing
ghost_labelbefore bindingGhostTyper. -
Nerve Center refactored into 3 aligned columns (Hardware, Active Operation, Live Console) and now embeds the GhostTyper prompt line inside the terminal frame.
-
Dashboard tab no longer duplicates system monitors; global runtime telemetry lives only in the Nerve Center footer.
-
Active Operation column now includes path elision (fixed-width middle truncation), session speed/anomaly telemetry, and an emergency
[ ABORT ]kill switch for long scans. -
Proactive path overflow guards were added to PySide6 labels that display file paths (Library drawer details and organize progress subtitle).
-
Nerve Center columns are now encapsulated as symmetrical module frames (shared
#090909chassis + border) to remove the floating-text/gridline mismatch and unify visual weight. -
Nerve Center sizing is now constrained (Hardware 220px, Operation 300px fixed; Terminal expands), and PySide6 main window enforces
setMinimumSize(1280, 720)to preserve GhostTyper/terminal readability. -
Nerve Center event stream now uses semantic log colors by prefix:
[*]green (normal/navigation),[?]magenta (user interaction/dialog waits),[!]red (critical/error). -
PySide6 Dashboard was rebuilt as a 4-card Command Center (DAT Syndicate, Bounty Board, Storage Heatmap, The Wire) with industrial telemetry cards (
CardPaneldepth#1A1A1A, square borders, green/magenta badges). -
Dashboard data now loads asynchronously via
AppState.refresh_dashboard_intel()using real CoreService intel providers (local DAT age checks, missing-ROM bounty stats, filesystem storage telemetry from saved collections/current session, and live RSS parsing with offline fallback). -
PySide6 Dashboard Bounty Board now uses real
QProgressBartelemetry bars (no ASCII bars), DAT statuses render as semantic badges, and The Wire feed blends into the card with a transparent terminal surface. -
PySide6 typography was tightened for telemetry readability: global UI font is now Sans-Serif, while JetBrains Mono is reserved for data surfaces (tables, logs, paths, hashes, dashboard telemetry values).
-
PySide6 GUI now applies localized tooltips across main navigation, Dashboard, Library, Import & Scan, and Tools panels (including heavy-operation controls), with tooltip text refreshed on language change.
-
PySide6 i18n audit fixed missing keys that were leaking raw placeholders in Import & Scan (
DAT add,scan,scan archives, BlindMatch placeholder/help, folder selection titles); visible dialog filter labels now reuse localized UI strings. -
Nerve Center click logging no longer duplicates lines: global click events are now written once via
monitor_action(...)and displayed only through the runtime-log tail (the direct console append path for clicks was removed). -
Tools tab no longer contains its own "Live Console"; tool results/logs are now centralized in the Nerve Center monitor only.
-
Tab changes (main sidebar, Library tabs, Tools tabs) now emit directly through
state.log_message, guaranteeing they appear in the Nerve Center even if the runtime-log tail misses generic click events. -
Policy exception added for a user-authorized, rate-limited
MyrientFetcherintegration (strict max 4 concurrent connections, graceful halt support). -
Nerve Center Active Operation column now supports a "Hydra Queue" (up to 4 dynamic Myrient transfer lines) with
[ HALT TRAFFIC ]control, wired toAppState.download_progressandhalt_traffic(). -
ToolsView now includes a dedicated
Downloadstab for Myrient/Hydra workflows (output folder + URL list parser with optionalURL | custom-filename, queue action, local status list, and halt button). -
Downloads tab now includes guided line creation (
Add URL...) and a Myrient listing-based link resolver (Base URL+Resolve Missing -> Queue) that can match Missing ROM rows against a Myrient directory index and auto-send matches to the Hydra Queue. -
Add URL...now opens a dedicated Myrient directory browser modal (async listing load, folder navigation, filter, multi-select) and appends selected file links into the Downloads queue input. -
Downloads tab now also includes an inline
Myrient Catalogpanel that splits a loaded listing intoSystems(directories) andDATfiles, lets the user browse a selected system directory, and sends selected files directly to the Hydra Queue. -
Myrient catalog no longer depends on manual base URL entry: the app now ships with built-in Myrient root presets and auto-detects/auto-loads a working catalog root when the Myrient Catalog drawer is opened (manual base URL remains as an advanced override).
-
The
Myrient Catalogis hidden by default inside a drawer (toggle-open on demand); root loads auto-select the first system and auto-load its entries. Myrient listing parsing was hardened (anchors with/without quotes and directory detection via link text). -
Fixed false "Another operation is already running" conflicts in the downloader: Myrient directory listing / link-resolution now run on a dedicated Myrient worker queue (separate from the generic Tools worker), so root->system autoload chaining and downloader actions no longer trip the generic busy guard.
-
LibraryView (Missing tab) now exposes a
Get Linksaction that sends selected (or optionally all visible) missing rows toTools > Downloads, where they can be resolved/queued for Myrient download. -
Heartbeat polling disabled; status updates are event-driven.
-
GhostTyper now includes a blinking cursor animation.
-
GhostTyper cursor uses a thin glyph for a lighter blink.
-
Nerve Center log monitor is per-session only (starts at end of log file on launch).
-
Nerve Center height fixed across views; GhostTyper line and log monitor share a seamless surface (no separator).
-
Nerve Center monitor and GhostTyper line share the same dark gray surface to avoid visual separation.
-
Nerve Center log monitor now records all user clicks via a global event filter.
-
Nerve Center height reduced by ~30% and click events mirror instantly into the on-screen monitor.
-
GhostTyper label now uses explicit JetBrains Mono styling with solid #39FF14 and transparent background.
-
GhostTyper moved under Database Health; Nerve Center log monitor now matches the app background.
-
Myrient downloader throughput tuned: progress updates are now throttled (reducing PySide6 UI/event-loop spam), download chunks increased to 1 MiB, and fresh downloads skip the preflight HEAD request (HEAD is still used for resume/size checks).
-
HALT TRAFFICno longer leaves the downloader permanently latched off; a new batch clears the halt flag automatically after active jobs drain. -
Myrient downloader backend was reworked to use local
rclone.exe(copyurl) instead of the Python HTTP transfer loop. Hydra Queue and the Downloads tab remain the same UX, but transfers now run throughrclonewith the same 4-slot queue limit and a single-stream-per-file profile (--multi-thread-streams 1) to respect Myrient guidance. -
The PySide6 downloader still drives live Hydra Queue / Downloads status rows, but progress/speed are now inferred from local file growth while
rcloneruns (avoiding stdout progress parsing stalls). -
PySide6 now persists UI state into
data/settings.json(ui_state.pyside6) with autosave + flush on close: main window geometry/view/language/search, Library tab + splitter, Import & Scan form inputs/toggles, and Tools fields (including Downloads URLs/base URL/output folder/catalog drawer + tabs). The app restores these values on next launch. -
Myrient/rclone downloads now write explicit per-file runtime log lines (
start,done,halted,error) viamonitor_action, so the Nerve Center anddata/logs/runtime-YYYY-MM-DD.logcapture the real failure reason instead of only genericERRORstatuses. -
On Myrient
fN.erista.meconnection/timeout failures, the rclone downloader now retries automatically once againstmyrient.erista.me(same path) before surfacing an error. The Downloads list also shows a shortened error reason inline and keeps the full rclone error text in the item tooltip. -
Myrient/rclone transport now normalizes queued/catalog URLs to the canonical
myrient.erista.mehost before download (avoiding brittle directfN.erista.melinks), uses--multi-thread-streams 0to respect the FAQ guidance (one connection/chunk), and enables rclonecopyurlcompatibility flags (--disable-http2,--bind 0.0.0.0,--user-agent curl) with short retries/timeouts so failures surface quickly in the UI/logs. -
Myrient transfers now prefer the FAQ-aligned
rcloneHTTP remote path (copyto --http-url ... :http:...) instead ofcopyurlfor Myrient file downloads. This keeps R0MM on the supported rclone HTTP-remote workflow while preserving exact destination filenames and the same Hydra Queue UX. -
When
rclonereports a Myrient CDN timeout on a redirected host (for examplef3.erista.me), R0MM now parses the failing URL from the rclone error line and performs limited automatic CDN host hopping (fN -> fM, same path) before surfacing the error. This mitigates route-specific failures where one Myrient file server is unreachable but others are fine. -
After runtime logs showed every Myrient timeout failing on
dial tcp4 ...even across CDN host hops, the rclone compatibility profile stopped forcing--bind 0.0.0.0(IPv4-only source bind). R0MM now leaves source-address selection to the OS so Windows can use the best available route/protocol (including IPv6 where available). -
If Myrient downloads still fail after rclone retries/CDN host-hop attempts, R0MM can hand off to the Windows native HTTP stack (
PowerShell Invoke-WebRequest) as a secondary transport fallback. This fallback is now opt-in via environment variableR0MM_ENABLE_PS_IWR_FALLBACK=1so default downloader behavior remains fully rclone-based for better throughput. -
The Downloads tab now runs in JDownloader-only mode (local Flashgot/Extern API at
127.0.0.1:9666). The Hydra/rclone download actions were removed from the UI; queue submission is now only through[ SEND TO JDOWNLOADER ]. -
The Downloads tab now includes
[ DOWNLOAD JDOWNLOADER ], which opens the official JDownloader download page in the default browser for quick setup on fresh machines. -
The Myrient directory browser was restored in
Add URL...so links can be picked directly from Myrient listings and appended to the JDownloader queue input. -
JDownloader enqueue now probes local endpoint variants (
127.0.0.1/localhost) and returns actionable diagnostics when unreachable (instead of only raw socket refusal), including an explicit hint to enable/check Extern/FlashGot on:9666. -
Endpoint error diagnostics now include bootstrap launch context (mode/PID) when R0MM successfully invoked JDownloader but
:9666/flashgotdid not answer. -
Tools > Downloads now exposes a GUI runtime panel for JDownloader (endpoint override, explicit
JDownloader2.exepath override, bootstrap mode, bootstrap timeout, throughput-tuning toggle, and tuning profile). These settings are persisted in PySide6 UI state and applied per-queue submission without requiring CLI/env configuration. -
The queue path now includes automatic local API self-heal on endpoint failures: R0MM updates JDownloader
RemoteAPIConfig(Extern enabled + localhost-only + deprecated API enabled), retries bootstrap, and automatically retries queue handoff once before surfacing an error. -
Tools > Downloads includes
[ Repair JD API ]to trigger the same self-heal manually from GUI. -
Local endpoint probing now also includes IPv6 localhost (
[::1]) alongside127.0.0.1/localhostto avoid false negatives on systems where JDownloader binds only IPv6 loopback. -
API repair can now force a controlled JDownloader restart when config changes require restart before
:9666/flashgotbecomes reachable. -
During repair, R0MM forces a GUI bootstrap attempt to surface any JDownloader permission prompts that cannot be accepted in headless mode.
-
If the local JDownloader endpoint is down, R0MM now attempts automatic local bootstrap: it tries to locate
JDownloader2.exeusingR0MM_JDOWNLOADER_BIN, PATH, Windows uninstall registry entries, and common install folders, then starts it in background before retrying queue handoff. -
Bootstrap binary resolution now rejects non-executable registry artifacts (for example
.icoDisplayIconvalues) and only accepts trusted launcher names (JDownloader2.exe/JDownloader.exe), preventingWinError 193on auto-start. -
Bootstrap mode is configurable via
R0MM_JDOWNLOADER_BOOT_MODE:gui(default, launches JDownloader executable directly),auto(tries headless first and, if:9666does not come up in time, terminates the spawned headless process and retries with GUI), orsilent/headless(no GUI fallback). -
Windows launch visibility fix: hidden-window startup flags are applied only to headless/silent launches. GUI launches are no longer hidden.
-
Bootstrap wait timeout is configurable with
R0MM_JDOWNLOADER_BOOT_TIMEOUT(seconds, clamped to6..180, default30). This controls how long R0MM waits for127.0.0.1:9666before switching/failing. -
In
auto, the first headless readiness window is intentionally short (6..12s) to avoid long stalls before GUI fallback. -
AppState now monitors JDownloader handoff targets by polling destination files (
.part/final) and emits livedownload_progressupdates (QUEUED/DOWNLOADING/DONE+ inferred speed and percent when size hints are available), so Nerve Center and Tools status rows reflect ongoing JDownloader transfers. -
R0MM now applies an optional JDownloader throughput tuning profile before enqueue (
R0MM_JDOWNLOADER_TUNE=1, default on). Defaultbalancedprofile setsmaxsimultanedownloads=4,maxsimultanedownloadsperhost=4,maxdownloadsperhostenabled=true,maxchunksperfile=4, and disables JD speed limiter. Profile can be changed withR0MM_JDOWNLOADER_TUNE_PROFILE=conservative|balanced|aggressive. -
Nerve Center Hydra Queue now recognizes JDownloader handoff rows as terminal
ADDEDstates ([JD ] ... LINKGRABBER), and rotates/prunes them like other completed statuses to prevent row buildup during large batch submissions. -
JDownloader queue submission now runs asynchronously in PySide6 (
QThread) and emits handoff phase progress events (prepare/bootstrap/collect/enqueue/repair/retry/done/error) so the UI remains responsive during bootstrap/endpoint waits. -
Nerve Center Operation module now shows a dedicated handoff progress bar/status line while JDownloader queue submission is in progress; this prevents the app from looking frozen during long bootstrap checks.
-
Tools > Downloads now defaults the Myrient base URL to
https://myrient.erista.me/files(also used as fallback when restored UI state has an empty base URL). -
Tools > DAT Operations now replaces "DAT Sources" with a dedicated
DAT Downloaderpanel. The app fetches DAT catalogs for No-Intro, Redump, and TOSEC (libretro mirrors), allows multi-select download, recognizes DAT family, and can auto-import downloaded files into the local DAT Library. -
DAT Downloader now supports one-step quick download by name or URL: user types the desired DAT (for example
Nintendo - SNES) and clicksDownload by Name/URL; R0MM resolves best match in the selected family and downloads/imports automatically. -
DAT Downloader tasks now run on a dedicated async queue (separate from generic Tools workers), removing false "Outra operação já está em andamento" conflicts in quick-search/refresh flows and reducing wait time with cached + parallel family catalog fetches.
-
Imported DATs are now automatically loaded into the active matcher in PySide6 flows (manual import path and downloader auto-import), so the app uses them immediately without requiring a second manual load step.
-
Import & Scan no longer performs DAT import/deletion; it is now focused on selecting which DATs are ON/OFF for the next scan.
-
Sidebar naming update (PySide6):
Libraryis nowCollection/Coleçãoin the main left navigation. -
DAT flow split (PySide6):
Import & Scannow only toggles DATs ON/OFF for the next scan; all DAT management (import file/folder, enable/disable, delete with confirmation, open DAT download folder) is centralized inTools > DAT Operations. -
DAT library discovery now includes all DAT-like files recursively under the app DAT folder (
data/datsand subfolders), so dropped files appear automatically in the DAT Library list. -
DAT toggle UX now supports all three interaction paths (button, context menu, and double-click) and marks invalid entries as
[ERR]with clear feedback when enabling is blocked by parse errors. -
DAT parser now supports clrmamepro plain-text DAT files (including downloader output like Genesis/No-Intro sets). DAT library refresh also revalidates previously invalid entries, so old
[ERR]rows recover automatically after parser updates. -
DAT import/downloader no longer creates duplicate library rows when the source DAT is already inside
data/dats(for example_downloads); and PySide6 DAT lists now collapse duplicate identities so[OFF]clones are hidden while an equivalent[ON]entry exists. -
Nerve Center now shows explicit scan activity in the Operation module: an immediate "starting scan" indicator plus a live progress bar/counter (
current/total) during scanning, so long scans no longer look idle/frozen before first results. -
Nerve Center scan indicator was visually realigned to the terminal aesthetic: scan progress now renders as a mono ASCII bar line (same style family as Disk/DB/Hydra) while preserving the same scan-state behavior (
starting+ livecurrent/totalupdates). -
Nerve Center scan telemetry now exposes scan phases explicitly:
Scanning(file hashing) andComparing(DAT matching), with a dedicated compared-files counter (Compared X/Y) so long multi-DAT scans no longer look stalled after hashing ends. -
Scan startup latency was reduced for large folders: file discovery now streams directly into hashing/matching (no full pre-list pass), so progress leaves "Starting scan..." almost immediately instead of waiting for a complete recursive file list.
-
Multi-DAT matching path was optimized for large mixed-system scans:
MultiROMMatchernow keeps merged global hash indexes (CRC+size / MD5 / SHA1) for O(1) lookup across loaded DATs instead of iterating matcher-by-matcher per file. -
Scanner now skips obvious non-ROM/document/media/source extensions by default while preserving compatibility for known ROM extensions, ZIP archives, and extensionless files; this reduces wasted hashing work in mixed folders.
-
PySide6 now updates Library results incrementally during the
Comparingphase (without waiting for scan completion), so identified/unidentified tables populate live as files are matched. -
A local recursive scan fixture folder
TESTE/is included in the workspace for smoke tests with mixed content (multi-system ROM-like files, archives, and non-ROM files). -
Collection > Unidentified agora tem
Add to DAT (_EDIT_): escolhe o DAT ativo, edita todos os campos (jogo/ROM/sistema/região/CRC/MD5/SHA1/tamanho/status) e grava num DAT derivado com prefixo_EDIT_ao lado do original (auto-import + auto-load + rematch). -
Editor
_EDIT_inclui assistência de metadados: sugestões a partir dos DATs carregados (fuzzy) e dicas online (Wikipedia OpenSearch; falha tratada quando offline), sempre com escolha explícita do usuário antes de gravar.