From 3d5dc60cfe06aaaffbf51fceb208ac719c8f9f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 2 Oct 2025 13:27:43 +0200 Subject: [PATCH] Fix selection being changed on re-entering song select when a converted beatmap is selected Closes https://github.com/ppy/osu/issues/34062. The root cause of the issue is that `OnEntering()` calls `onArrivingAtScreen()`, which calls `ensureGlobalBeatmapValid()`, which would call `checkBeatmapValidForSelection()` with a `FilterCriteria` instance retrieved from the `FilterControl`. The problem with that is at the time that this call chain is happening, `FilterControl` is not yet loaded, which means in particular that it has not bound itself to the config bindable, as that happens on `LoadComplete()`: https://github.com/ppy/osu/blob/bff07010d1f9874125baf2918f02c5cf61a5ea60/osu.Game/Screens/SelectV2/FilterControl.cs#L198 To resolve this, retrieve the bindable in `SongSelect` itself, which ensures it is valid for reading at the time the above call chain happens. --- osu.Game/Screens/SelectV2/SongSelect.cs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/SelectV2/SongSelect.cs b/osu.Game/Screens/SelectV2/SongSelect.cs index 64262ed6ab..0f6e4e61d0 100644 --- a/osu.Game/Screens/SelectV2/SongSelect.cs +++ b/osu.Game/Screens/SelectV2/SongSelect.cs @@ -155,6 +155,7 @@ namespace osu.Game.Screens.SelectV2 private readonly RealmPopulatingOnlineLookupSource onlineLookupSource = new RealmPopulatingOnlineLookupSource(); private Bindable configBackgroundBlur = null!; + private Bindable showConvertedBeatmaps = null!; [BackgroundDependencyLoader] private void load(AudioManager audio, OsuConfigManager config) @@ -302,6 +303,8 @@ namespace osu.Game.Screens.SelectV2 updateBackgroundDim(); }); + + showConvertedBeatmaps = config.GetBindable(OsuSetting.ShowConvertedBeatmaps); } private void requestRecommendedSelection(IEnumerable groupedBeatmaps) @@ -522,7 +525,7 @@ namespace osu.Game.Screens.SelectV2 if (!this.IsCurrentScreen()) return; - if (!checkBeatmapValidForSelection(beatmap, carousel.Criteria)) + if (!checkBeatmapValidForSelection(beatmap)) return; // To ensure sanity, cancel any pending selection as we are about to force a selection. @@ -573,7 +576,7 @@ namespace osu.Game.Screens.SelectV2 // Refetch to be confident that the current selection is still valid. It may have been deleted or hidden. var currentBeatmap = beatmaps.GetWorkingBeatmap(Beatmap.Value.BeatmapInfo, true); - bool validSelection = checkBeatmapValidForSelection(currentBeatmap.BeatmapInfo, filterControl.CreateCriteria()); + bool validSelection = checkBeatmapValidForSelection(currentBeatmap.BeatmapInfo); if (validSelection) { @@ -594,9 +597,8 @@ namespace osu.Game.Screens.SelectV2 { // In the case a difficulty was hidden or removed, prefer selecting another difficulty from the same set. var activeSet = currentBeatmap.BeatmapSetInfo; - var criteria = filterControl.CreateCriteria(); - var validBeatmaps = activeSet.Beatmaps.Where(b => checkBeatmapValidForSelection(b, criteria)).ToArray(); + var validBeatmaps = activeSet.Beatmaps.Where(checkBeatmapValidForSelection).ToArray(); if (validBeatmaps.Any()) { @@ -614,12 +616,9 @@ namespace osu.Game.Screens.SelectV2 return validSelection; } - private bool checkBeatmapValidForSelection(BeatmapInfo beatmap, FilterCriteria? criteria) + private bool checkBeatmapValidForSelection(BeatmapInfo beatmap) { - if (criteria == null) - return false; - - if (!beatmap.AllowGameplayWithRuleset(Ruleset.Value, criteria.AllowConvertedBeatmaps)) + if (!beatmap.AllowGameplayWithRuleset(Ruleset.Value, showConvertedBeatmaps.Value)) return false; if (beatmap.Hidden) @@ -777,7 +776,7 @@ namespace osu.Game.Screens.SelectV2 // This avoids a flicker of a placeholder or invalid beatmap before a proper selection. // // After the carousel finishes filtering, it will attempt a selection then call this method again. - if (!CarouselItemsPresented && !checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo, filterControl.CreateCriteria())) + if (!CarouselItemsPresented && !checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo)) return; if (carousel.VisuallyFocusSelected) @@ -834,7 +833,7 @@ namespace osu.Game.Screens.SelectV2 bool isFirstFilter = filterDebounce == null; // Criteria change may have included a ruleset change which made the current selection invalid. - bool isSelectionValid = checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo, criteria); + bool isSelectionValid = checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo); filterDebounce = Scheduler.AddDelayed(() => carousel.Filter(criteria, !isSelectionValid), isFirstFilter || !isSelectionValid ? 0 : filter_delay); }