diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs
index 9186685f0c..422e306450 100644
--- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs
+++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs
@@ -207,7 +207,7 @@ namespace osu.Game.Beatmaps.ControlPoints
///
/// The list to search.
/// The time to find the control point at.
- /// The active control point at .
+ /// The active control point at . Will return null if there are no control points, or if the time is before the first control point.
public static T BinarySearch(IReadOnlyList list, double time)
where T : class, IControlPoint
{
diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs
index 00bc7453d8..54079c7895 100644
--- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs
+++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs
@@ -4,6 +4,7 @@
#nullable disable
using System;
+using System.Linq;
using osu.Framework.Lists;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Timing;
@@ -73,6 +74,13 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms
///
/// The time which the should affect.
/// The .
- private MultiplierControlPoint controlPointAt(double time) => ControlPointInfo.BinarySearch(controlPoints, time) ?? new MultiplierControlPoint(double.NegativeInfinity);
+ private MultiplierControlPoint controlPointAt(double time)
+ {
+ return ControlPointInfo.BinarySearch(controlPoints, time)
+ // The standard binary search will fail if there's no control points, or if the time is before the first.
+ // For this method, we want to use the first control point in the latter case.
+ ?? controlPoints.FirstOrDefault()
+ ?? new MultiplierControlPoint(double.NegativeInfinity);
+ }
}
}