Repository navigation
Add B50 Support - #71
Conversation
Arcaea v7.0 reworked the potential system: B30 + R10 is replaced by B50 (top 10 entries counted twice), and single-play potential now adds a +0.2 clear bonus for any state other than TRACK_LOST. ArcaeaScoringMode is keyed by the date each rule took effect so the key can be persisted as-is and stays chronologically ordered. A missing clear type counts as TRACK_LOST: historical records without a reliable clear state must not gain the bonus, so the default keeps B50 values conservative rather than inflating them.
The scoring mode describes how a database's play results are interpreted (official servers use B50 while private servers may stay on B30 + R10), so it belongs to the database itself rather than app preferences. Storing it in the properties table keeps it traveling with the database file and makes a per-database scope automatic. Unset or unknown keys fall back to the latest mode (B50).
PotentialRepository gains b50(), b10() and a scoring-mode-aware potential(). B50 follows the official v7.0 formula (best50 sum plus best10 sum, divided by 60, so the top 10 count twice) over the clear-bonus-inclusive play rating; B30_R10 keeps (b30 + r10) weighting. Best-per-chart ranking becomes scoring-mode aware: under B50 a cleared play can outrank a higher-scoring TRACK_LOST play of the same chart, so the per-chart best must be selected by the bonus-inclusive rating. The minimum-fields query now carries clear_type for that comparison. The B30 list call site passes B30_R10 explicitly; behavior is unchanged.
potentialToText now takes the decimal scale directly (default 3) instead of a DecimalMode, which no caller customized. There is no community consensus on potential display precision and some tools show the raw value, so 3 decimals is used everywhere by default; the overview main potential switches per scoring mode separately. The chart recommend result row used a hardcoded "%.2f" format; it now goes through potentialToText like every other ptt display.
The overview card follows the scoring mode stored in the database: B30 + R10 shows the legacy averages with the official 0.01 precision, B50 shows the B50/B10 averages with 0.001. The overall potential value comes from PotentialRepository.potential() which already switches on the mode. Also annotate MinimumPlayResultPotentialFields.clearType with @ColumnInfo so Room maps the new query column.
The scoring mode is a property of the active database, so the switch lives in the database manage screen instead of the app settings. Adds a generic radio-button SelectPreferencesWidget beside the existing preference widgets.
Under B50 the best list shows the clear-bonus-inclusive ratings and the entry is titled Best50; the R30 entry is hidden since the recent queue does not participate in B50. The score list also rates each record by the active mode's rules. Behavior under B30 + R10 is unchanged.
Under the B50 rules the clear state changes the single-play potential by the clear bonus, so the calculator takes it as an input (default: no clear type, i.e. no bonus). The result is shown to 6 decimals as a tool output, independent of the official display precision.
A record without a clear type is rated as TRACK LOST under the B50 rules, which is invisible to the user. The new CLEAR_TYPE_MISSING warning surfaces such records in the play result editor and lists so they can be filled in; it only appears under B50, where it affects the rating. The warning stays out of the plain validate(): OCR import uses it as a data-quality gate, and a missing clear type is valid data there.
The initial target play rating mirrors the player's current level; use the b50 average under B50 instead of the b30 average, which no longer represents it.
…lator Part of the previous calculator commit did not land: the result was still computed without the clear type and formatted at 4 decimals, and the clear-type row was missing so the selector dialog was unreachable.
Class names, package declaration, enum entry, route, string keys and references now say best_list; the screen title no longer switches per scoring mode since the entry name is mode-neutral.
Renders as a TextPreferencesWidget row: the label as title, the current selection as the description line and a trailing expand icon, matching the other preference-driven selectors instead of an ad-hoc text row.
A fresh database has no `scoring_mode` row either, so it follows the fallback value until the user touches the mode selector. That fallback can change in a later release, and a database nobody configured would silently move with it. PropertyRepository.DEFAULT_SCORING_MODE names the fallback, so the callback that writes it and the read path that falls back to it cannot drift apart.
|
Model not found: deepseek/deepseek-v4-flash. Did you mean: deepseek-flash, deepseek-v4-pro? |
|
/opencode Review this PR |
|
Model not found: deepseek/deepseek-v4-flash. Did you mean: deepseek-flash, deepseek-v4-pro? |
|
/opencode Review this PR |
This reverts commit d525a9c. # Conflicts: # .github/workflows/opencode.yml
|
/opencode Review this PR |
PR Review: Add B50 Support (#71)I reviewed the full diff, then compiled
The instrumented tests ( Overall the feature is well-structured, documented ( Blocking
Medium
Low / Nits
Happy to expand on any of these. |
The repository no longer re-derives averages for every consumer.
- Remove unstable references
Review: new commits
|
| fun validate( | ||
| playResult: PlayResult, | ||
| chartInfo: ChartInfo?, | ||
| scoringMode: ArcaeaScoringMode, | ||
| ): List<ArcaeaPlayResultValidatorWarning> { | ||
| val clearTypeMissing = | ||
| if ( | ||
| scoringMode == ArcaeaScoringMode.B50 && | ||
| ArcaeaPlayResultValidatorClearTypeMissingWarning.conditionsMet(playResult, chartInfo) | ||
| ) { | ||
| listOf(ArcaeaPlayResultValidatorClearTypeMissingWarning) | ||
| } else { | ||
| emptyList() | ||
| } |
There was a problem hiding this comment.
Consider future refactors?


No description provided.