Skip to content

Conversation

Altaks
Copy link

@Altaks Altaks commented Oct 16, 2025

This PR adds an accuracy filter on the beatmaps carousel search bar.

This filter allows players to filter the beatmaps based on the accuracy they've achieved during their best score.

This filter recognizes the keywords acc and accuracy, and the value can be described in several formats :

  • acc>=90.97 corresponds to 90.97% accuracy
  • accuracy<=95.84% corresponds to 95.84% accuracy
  • acc>0.90 corresponds to 90% accuracy

Beatmaps that have not yet been played are considered to have an accuracy of 0%, so a player searching for acc<x or acc<=x will still see unplayed maps.

The best scores achieved by the offline ("Guest") player are taken into account when filtering.

Example

osu_2025-10-16_10-53-41


With a filter of acc>96%, we obtain the only beatmap where the accuracy of the best score is greater than “96%”:

osu_2025-10-16_10-54-02


With a filter acc>91, we only get the two beatmaps where the user has an accuracy greater than 91%:

osu_2025-10-16_13-49-01

osu_2025-10-16_13-47-16


Same goes for accuracy>0.9, since it's only the value format that changes :

osu_2025-10-16_10-54-45


With a "less than" filter, such as accuracy<91, we only get beatmaps with a maximum accuracy of less than 91%, as well as beatmaps that have not yet been played :

osu_2025-10-16_11-02-31

osu_2025-10-16_10-55-35

@dani211e
Copy link
Contributor

dani211e commented Oct 16, 2025

Beatmaps that have not yet been played are considered to have an accuracy of 0%, so a player searching for acc<x or acc<=x will still see unplayed maps.

Having '<' include maps with no scores feels like weird UX imo, especially since there's already an explicit played=1/0 filter for played/unplayed maps.
Although the latter only considers maps that have entered gameplay in lazer as played, and ignores imported scores for consideration. (which could be considered a bug)


public Func<List<BeatmapCollection>> AllCollections { get; set; } = () => [];
public Func<FilterCriteria, Dictionary<Guid, ScoreRank>> BeatmapInfoGuidToTopRankMapping { get; set; } = _ => new Dictionary<Guid, ScoreRank>();
public Func<FilterCriteria, Dictionary<Guid, double>> BeatmapInfoGuidToTopRankAccuracyMapping { get; set; } = _ => new Dictionary<Guid, double>();
Copy link
Collaborator

@bdach bdach Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am incredibly reluctant to even approach this PR for two reasons:

  • This PR will be immediately and inevitably followed by requests to filter by total score, pp, count of GREATs/GOODs, FCs, etc.
  • This approach of spamming dictionaries for every user-score-related filter does not feel like it will scale.

So this PR is opening a whole swath of scope creep that I do not want to spend time burrowed in while other, possibly more important, stuff still needs doing.

A starting point that could maybe persuade me to consider this change is to limit the number of beatmap-info-to-score-data dictionaries to one. The value in this case would be an object containing the best rank, accuracy, pp, etc. achieved on the beatmap (...like ScoreInfo even? depends on how this filter should work - see other review comment below)

Note that this may still result in prohibitively bad performance in the long run, but at least code-quality wise it's a start.


var allLocalScores = r.GetAllLocalScoresForUser(criteria.LocalUserId)
.Filter($@"{nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $0", criteria.Ruleset?.ShortName)
.OrderByDescending(s => s.TotalScore)
Copy link
Collaborator

@bdach bdach Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and also this is a particular sticking point. This makes this filter based on "accuracy achieved on user's top score as determined by total score" not "user's best accuracy ever on this map". You remarked on that in the OP, but my question would be - is that what users want? I dunno. Arguable? Maybe they want to be able to do both?

Like the local leaderboards support sorting in the second interpretation of the phrase here, so I feel like this will be confusing to understand for users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants