Skip to content

feat: name games from the serial on the disc, not the filename - #65

Merged
casmith merged 1 commit into
mainfrom
feat/canonical-titles
Sep 5, 2026
Merged

feat: name games from the serial on the disc, not the filename#65
casmith merged 1 commit into
mainfrom
feat/canonical-titles

Conversation

@casmith

@casmith casmith commented Sep 5, 2026

Copy link
Copy Markdown
Owner

A rip is called whatever whoever made it felt like typing. That name became the VCD's filename, the launcher's, and the entry in OPL's menu:

SCUS_941.88.hot-shots-golf-u-scus-94188.VCD
SLUS_010.59.marvel-vs.-capcom-clash-of-the-super-heroes-slus-01059.VCD
SLUS_000.67.SLUS_00067.VCD

The serial inside the image is not arbitrary — it is stamped on the disc and read out of SYSTEM.CNF. The OPL CFG databases, generated from Redump, map it to the name the game is actually called. Resolved against a real library:

filename serial title
hot-shots-golf-u-scus-94188 SCUS_941.88 Hot Shots Golf
king-of-fighters-99-u-slus-01332 SLUS_013.32 The King of Fighters '99
marvel-vs.-capcom-clash-of-the-super-heroes-slus-01059 SLUS_010.59 Marvel vs. Capcom - Clash of Super Heroes
megaman-legends-2-slus-01140 SLUS_011.40 Mega Man Legends 2
SLUS_00067 SLUS_000.67 Castlevania - Symphony of the Night
Disc 1 SLUS_005.94 Metal Gear Solid
FF7 SCUS_941.63 Final Fantasy VII

Both platforms are covered — PS2 resolves SLUS_210.50 to Burnout 3 Takedown, SCUS_974.72 to Shadow of the Colossus.

Normalisation

  • Redump moves the article to the end so titles sort alphabetically — King of Fighters '99, The. That is a sorting convention, not a name.
  • Its (Disc 1) is dropped: ps2hdd appends its own _CD1 from the disc number it worked out, and would otherwise write ... (Disc 1)_CD1.
  • A tag that is not a disc marker is part of the name and stays — Point Blank (Demo).

It also fixes the 64-byte limit

Two launchers in the library this came from exceeded OPL's APP_BOOT_MAX, so their entries appeared and did nothing. Real titles are shorter than slugs with the serial repeated on the end — the longest of those twelve falls from 70 characters to 58, and all twelve now fit.

Degrading

An explicit --title still wins. Everything else falls back to the old behaviour rather than failing: a serial the database doesn't carry, no network, or install.canonical_titles = false.

A lookup that fails on transport is not cached — one offline moment should not be permanent. One that returns nothing is — a library of homebrew should not re-ask forever.

The demo gets an offline lookup. It fakes the disk and the external tools; it must not consult a real database either, or its output depends on the network and on what someone else's repository says today. The test helpers do the same, so nothing in the suite reaches out.

Tests

internal/titles is covered with a fake transport: the Title= field is read, the cache prevents a second request, differently punctuated serials share one entry, the two platforms don't share answers, absence is remembered, transport failure is not, and the cache round-trips across processes.

At the app level, TestInstallNamesAPS1TitleFromItsSerial installs a disc whose file is called Disc 1 and asserts the VCD is named from the serial. Mutation-checked: removing the lookup compiles and fails it with __.POPS holds [… SLUS_005.94.SLUS_005.94.VCD] — the old behaviour exactly. --title precedence and the disabled-config fallback are covered too.

Full suite, go vet, gofmt and scripts/demo-smoke.sh pass.

Note

This affects new installs. Titles already on the drive keep their names until reinstalled.

Sources: PS1-OPL-CFG-Database, PS2-OPL-CFG-Database

https://claude.ai/code/session_018eBAB3V9GRxNwgpQcpGje4

A rip is called whatever whoever made it felt like typing.
"hot-shots-golf-u-scus-94188", "SLUS_00067", "Disc 1", "FF7". That name
became the VCD's filename, the launcher's, and the entry in OPL's menu.

The serial inside the image is not arbitrary. It is stamped on the disc
and read out of SYSTEM.CNF, and the OPL CFG databases -- generated from
Redump -- map it to the name the game is actually called. So the title
now comes from the disc:

  hot-shots-golf-u-scus-94188        -> Hot Shots Golf
  king-of-fighters-99-u-slus-01332   -> The King of Fighters '99
  SLUS_00067                         -> Castlevania - Symphony of the Night
  Disc 1                             -> Metal Gear Solid
  FF7                                -> Final Fantasy VII

Two normalisations. Redump moves the article to the end so titles sort
alphabetically -- "King of Fighters '99, The" -- which is a sorting
convention and not a name. And its "(Disc 1)" is dropped, because
ps2hdd appends its own "_CD1" from the disc number it worked out and
would otherwise write "... (Disc 1)_CD1".

This also fixes something else. Two of the launcher names in the library
this came from were over the 64 bytes OPL allows for a boot filename, so
their entries appeared and did nothing. Real titles are shorter than
slugs with the serial repeated on the end: the longest of those twelve
falls from 70 characters to 58.

An explicit --title still wins. Everything else degrades to the old
behaviour rather than failing: a serial the database does not carry, no
network, or install.canonical_titles = false, and the filename-derived
title is used exactly as before. A lookup that fails is not cached,
because one offline moment should not be permanent; one that returns
nothing is, because a library of homebrew should not re-ask forever.

The demo environment gets an offline lookup. It fakes the disk and the
external tools, and it must not consult a real database either -- its
output would then depend on the network and on what someone else's
repository says today.

Claude-Session: https://claude.ai/code/session_018eBAB3V9GRxNwgpQcpGje4
@casmith
casmith force-pushed the feat/canonical-titles branch from b43ef6c to 5a3408d Compare September 5, 2026 14:46
@casmith
casmith merged commit e7f9e11 into main Sep 5, 2026
5 checks passed
@casmith
casmith deleted the feat/canonical-titles branch September 5, 2026 14:53
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.

1 participant