diff --git a/osu.Game.Tests/NonVisual/FormatUtilsTest.cs b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs
index a12658bd8b..0fcf754cf6 100644
--- a/osu.Game.Tests/NonVisual/FormatUtilsTest.cs
+++ b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs
@@ -21,5 +21,18 @@ namespace osu.Game.Tests.NonVisual
{
Assert.AreEqual(expectedOutput, input.FormatAccuracy().ToString());
}
+
+ [TestCase(3, "3.00")]
+ [TestCase(3.3, "3.30")]
+ [TestCase(3.55, "3.55")]
+ [TestCase(3.553, "3.55")]
+ [TestCase(3.557, "3.55")]
+ [TestCase(3.9999, "3.99")]
+ [TestCase(3.999999, "3.99")]
+ [TestCase(4, "4.00")]
+ public void TestStarRatingFormatting(double input, string expectedOutput)
+ {
+ Assert.AreEqual(expectedOutput, input.FormatStarRating().ToString());
+ }
}
}
diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs
index f7250c6833..fa7d6595e9 100644
--- a/osu.Game/Utils/FormatUtils.cs
+++ b/osu.Game/Utils/FormatUtils.cs
@@ -36,7 +36,16 @@ namespace osu.Game.Utils
/// Formats the supplied star rating in a consistent, simplified way.
///
/// The star rating to be formatted.
- public static LocalisableString FormatStarRating(this double starRating) => starRating.ToLocalisableString("0.00");
+ public static LocalisableString FormatStarRating(this double starRating)
+ {
+ // for the sake of display purposes, we don't want to show a user a "rounded up" star rating to the next whole number.
+ // i.e. a beatmap which has a star rating of 6.9999* should never show as 7.00*.
+ // this matters for star rating medals which use hard cutoffs at whole numbers,
+ // which then confuses users when they beat a 6.9999* beatmap but don't get the 7-star medal.
+ starRating = Math.Floor(starRating * 100) / 100;
+
+ return starRating.ToLocalisableString("0.00");
+ }
///
/// Finds the number of digits after the decimal.