Skip to content

RPCS3 compatibility for PS3 games, AI sales figures, edit-toggle and Achievements width fixes - #24

Merged
milnet01 merged 1 commit into
mainfrom
claude/nice-galileo-yny6pc
Oct 29, 2026
Merged

milnet01 merged 1 commit into
mainfrom
claude/nice-galileo-yny6pc

Conversation

@milnet01

Copy link
Copy Markdown
Owner

What

  • RPCS3 compatibility for PS3 games. Library cards, the PlayStation 3 console page, the quick view and the game page show RPCS3's status (Playable / Ingame / Intro / Loadable / Nothing) and the date it was last tested. The status comes from the RPCS3 installed on this computer. Only PS3 games with a ROM on disk are looked up; imported games are skipped.
  • Sales figures. New games.units_sold column (migration 023). The AI is asked for it during a scrape's gap-fill and in AI Fill, using free published sources. The game page and the quick view show it.
  • Fix: the Franchise / Series switch did nothing (reported on Dreamcast D-2), and neither did the Platform Availability switch.
  • Fix: Achievements tabs were different widths.
  • Other fixes found on the way (see How).

Why

All four were user requests. In the toggle bug, both switches' <label class="toggle-switch" for="…"> pointed at the text input instead of the checkbox it wraps. For a Standalone game that input is hidden, so a click was sent to a hidden field and the switch never changed. This affected every Standalone game, not only D-2. The Library's quick-edit modal had the same bug.

The width bug: each tab's grid-4 cap came from its own card size. RA, Steam and Xbox capped at 1463px, PSN at 1563px and RPCS3 at 1845px.

How

  • services/rpcs3_compat.py reads <RPCS3 config dir>/GuiConfigs/compat_database.dat. I checked RPCS3's source (game_compatibility.cpp, settings.cpp, main_window.ui): this file holds the raw rpcs3.net/compatibility?api=v1&export JSON, keyed by the serial with no dash (BLUS30443). RPCS3 downloads it only from Manage > Databases > Download Compatibility Database. RetroDB never downloads it. The status isn't stored; the file is re-read only when its mtime or size changes, and its path is looked up at most once a minute. When the file is missing, the game page explains how to get it.
  • Serials use the existing games.disc_serial (standalone_settings._disc_ids is now public as disc_ids). The game page and quick view read a missing serial on demand. A Library or console page with unread PS3 serials starts one background thread to fill them in. disc_serial now also reads PARAM.SFO for PSN and installed folders, and a serial in the file or folder name ([BLUS30443]).
  • _rpcs3_dirs now matches RPCS3's fs::get_config_dir(): a portable/ folder beside the program, the program's own folder (Windows) and macOS Application Support. Per-game RPCS3 settings on Windows and macOS benefit from this too.
  • Sales: the prompt asks for lifetime copies sold on that platform, from free sources: publisher reports, platform best-seller lists, Famitsu/Media Create, Circana as reported in the press, Wikipedia, then VGChartz. When only a multi-platform total is published, the AI returns null. parse_units_sold() normalises answers like "2.4 million", "~850k" and "2,400,000". The value goes through the same fill-only COALESCE path as the scores. I looked for a free sales API: Wikidata's "units sold" (P2664) is mostly cross-platform totals and couldn't be reached to test from the session, so I didn't add it.
  • Achievements: all five tabs now carry .achievements-page and share its card tokens.
  • Found on the way:
    • AI Fill's rating-inference step called .strip() on integer columns, which crashed for a game with a score but no age rating.
    • AI Fill kept a hand-copied field list; it now uses AI_FILLABLE_FIELDS.
    • The edit-toggle labels and the Library card completion/score tooltips are now translated.
    • After a quick-view save, the user-score badge was dropped; score badges now come from one helper.

Version / changelog: this opens 3.34.0. PRs 21–23 already push the open 3.33.0 entry past the 10-item limit, so this work doesn't add to it. When those merge first, expect a small conflict here in config.example.py (APP_VERSION/APP_LAST_UPDATE) and at the top of data/changelog.yaml. Resolve it by keeping both entries, 3.34.0 above 3.33.0. The 3.34.0 entry is not yet in the 20 per-locale changelogs (3.33.0 isn't either); those go in at release time, as was done for 3.32.0.

Mandatory-workflow checklist

  • Version bumped in config.example.py (APP_VERSION 3.34.0 + APP_LAST_UPDATE). config.py is untracked.
  • Changelog entry added at the top of data/changelog.yaml
  • CSS rebuilt
  • JS rebuilt
  • Tests run: 2262 passed, 1 skipped (that skip also happens on main)
  • Lockfile: n/a
  • CLAUDE.md updated: two notes on units_sold and RPCS3 compatibility. No routes, templates or bundles were added.
  • i18n catalogs regenerated; check_i18n_fresh.py passes. retrodb.spec lists migration 023.

Verification

  • pytest full suite, ruff check ., node --check on the changed JS, and scripts/ci_local.sh --docs. New tests: tests/test_rpcs3_compat.py, tests/test_units_sold.py, plus PARAM.SFO and file-name cases in tests/test_disc_serial.py.
  • Ran the dev server on a throwaway DB with a fake PS3 library ([BLUS30443] and [BCES00797] folders, one with no serial, one PSN-imported row) and a fake RPCS3 config folder. Checked with Playwright at 1600px and 375px:
    • Library and PS3 console page: Playable and Ingame badges appear after the background serial fill, with the right tooltips. No badge on the no-serial or imported game. Console has no errors. This run caught a real bug, now fixed: the card code ran without the helper in scope because bundles are wrapped in IIFEs.
    • Game page and quick view show ⭐ score, "2 400 000 sold" and "RPCS3: Playable". With the list file removed, the game page shows the "no compatibility list" hint.
    • Game-page edit window: clicking the Franchise switch on a Standalone game now changes it to "Part of a Series" and shows the input, and clicking again goes back. The Platform Availability switch toggles. The Library quick-edit Franchise switch toggles.
    • Achievements widths at 2560px: before, RPCS3 was 1845, PSN 1563, Steam 1463, Xbox 1463. After, all are 1463, and RetroAchievements is also 1463.
  • Not tested: a real RPCS3 install and real dumps, and a live AI provider call for sales. The prompt and the parser are covered by unit tests only.

Generated by Claude Code

… width fixes (3.34.0)

RPCS3 compatibility
- services/rpcs3_compat.py reads the local RPCS3's
  GuiConfigs/compat_database.dat (the rpcs3.net export RPCS3 downloads via
  Manage > Databases > Download Compatibility Database), re-read only when
  the file changes, and looks games up by disc serial. Never stored, never
  downloaded by RetroDB. Local PS3 ROMs only; imported games are skipped.
- Shown on Library and console cards, the quick view and the game page;
  the game page hints how to get the list when RPCS3 has none.
- Serials: PARAM.SFO for PSN/installed folders, and a serial in a file or
  folder name ([BLUS30443]); missing serials are read in the background.
- _rpcs3_dirs also looks beside rpcs3.exe (Windows), in a portable folder
  and in macOS Application Support, matching RPCS3's get_config_dir().

Sales figures
- games.units_sold (migration 023), asked of the AI in the scrape's
  gap-fill and in AI Fill, from free published sources; parse_units_sold()
  normalises "2.4 million", "~850k" and the like. Shown on the game page
  and in the quick view. AI Fill now uses AI_FILLABLE_FIELDS instead of a
  copy of it.

Fixes
- Franchise / Series and Platform Availability switches in the edit
  windows did nothing: their <label for> pointed at the hidden text input,
  not the checkbox. Their labels are now translated.
- Achievements tabs each capped the page from their own card size
  (RA/Steam/Xbox 1463px, PSN 1563px, RPCS3 1845px); all now share
  .achievements-page's tokens.
- AI Fill's rating inference called .strip() on integer columns.
- Library card completion and score tooltips are translated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013s5ztLcay7qP1ezTvc85UA
@milnet01
milnet01 merged commit 35a2569 into main Oct 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants