Record the phase 5 ScoreSaber merge and map OST hashes in the sync
ScoreSaber names official levels "ost_<LevelId>" where BeatLeader uses "<levelid>"; ssMapHash applies that for leaderboard snapshots and maps. The plan records the merge results and where it differs from the steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -733,6 +733,57 @@ profile and scores, and a replay opens in ArcViewer.
|
||||
|
||||
### Phase 5: Convert ScoreSaber scores and merge
|
||||
|
||||
**Built and checked on a scratch copy 2026-11-09; committed, deploy
|
||||
pending.** Server `50f7df6` (`Tools/ArchiveImporter/ScoreMerge.cs`, rules in
|
||||
the fork's `MIRROR.md`), website `5522f245` (SS badge, `/watch/` for `.dat`),
|
||||
exporter `ssMapHash` in this repo. All pushed. Result on the local archive: 3,710 leaderboards with one score
|
||||
each (3,566 BL + 141 SS-only BL leaderboards + 3 DLC levels BL lacks). Winners: 3,564 BL main,
|
||||
1 BL legacy, 139 SS legacy, 6 SS main; 2,022 SS scores were the same play as
|
||||
a BL score and dropped; 20 BL scores got an improvement recomputed against an
|
||||
earlier SS play. An unchanged rerun writes 0 rows. What differs from the
|
||||
steps below:
|
||||
|
||||
- Step 1: **no new columns.** Provenance goes in `Platform`
|
||||
(`scoresaber,<SS player id>`), and `Id` ≥ 1e9 marks SS scores. Columns
|
||||
would have needed a models-fork change, a migration, and edits to the ~90
|
||||
score projections before the website saw them; `Platform` already reaches
|
||||
every score response.
|
||||
- Step 2: OST levels are `ost_<LevelId>` on SS and `<levelid>` on BL; 5 of 8
|
||||
resolve that way. Me Porto Bonito, Nuthin' But A "G" Thang and Stressed Out
|
||||
(3 scores) aren't on BL (404), so the importer builds a song and leaderboard
|
||||
from the SS item (`<LevelId><diff><mode>` ids, no ratings, accuracy 0).
|
||||
The exporter now maps `ost_` hashes too (`scoresaber.ts` `ssMapHash`).
|
||||
HMD and controller come from SS `deviceHmd`/`deviceControllerLeft`. SS
|
||||
replays are served from `storage/ssreplays` → `archive/scoresaber`, so the
|
||||
URL is `/cdn/ssreplays/<player>/replays/<id>.dat`.
|
||||
- **Pp isn't upstream's.** Neither the fork's `rebalanced-pp` formula
|
||||
(median 0.94x, range 0.69–1.16x) nor upstream `master`'s (0.81x)
|
||||
reproduces the pp on archived BL scores; live BL's code is private. So the
|
||||
fold compares every candidate by **locally computed** pp, which keeps the
|
||||
order right, and BL winners keep upstream's pp. The 70 SS winners on
|
||||
ranked maps show local pp, and improvement pp deltas are local on both
|
||||
sides. Matching pp first sent two BL scores (KillerToy, Make Me) to worse
|
||||
SS plays.
|
||||
- Step 3: same-play duplicates (equal base score, ≤ 2 min apart; observed
|
||||
−30 s…+9 s) keep the BL copy. Each upstream `scoreImprovement` is turned
|
||||
back into the best it replaced and added as a candidate, so upstream's
|
||||
improvement stays exactly when that rebuilt best is also the fold's previous
|
||||
best. Older archived BL bests are candidates too.
|
||||
- Step 5: the badge sits next to the rank in both `ScoreRank.svelte` (rank 0
|
||||
already renders "-"). `/watch/` takes the map hash from the score
|
||||
(`/score/{id}` → `song.hash`) for `.dat` replays, from `?scoreId=` or
|
||||
1e9 + the id in the filename. Expanding an SS row shows its leaderboard and
|
||||
no stats tab; the page logs a JSON error for the 404 score stats, harmless.
|
||||
- Check: The Goddess Figure (Normal) is the case where a 2022 legacy SS
|
||||
play beats the BL score; it shows with the SS badge, and the BL Hard score
|
||||
there now reads "+76,821 vs 4 years ago" (vs the legacy SS play). An SS
|
||||
replay redirects to ArcViewer with the `.dat` and local zip and loads the map;
|
||||
watching it play still needs a real browser.
|
||||
|
||||
To deploy: nix-pleb bumps `plebleader-server`, `plebleader-website` and
|
||||
`plebsaber-stream` (sync CLI); switch. The next `plebleader-sync`
|
||||
run re-imports with the merge.
|
||||
|
||||
ScoreSaber scores become BeatLeader `Score` rows, and each leaderboard keeps
|
||||
exactly one score. BeatLeader already shows how a score compares with the
|
||||
previous best (`ScoreImprovement`), so after the merge that comparison covers
|
||||
|
||||
Reference in New Issue
Block a user