From f241d9c84e8dbaa23bd5d29284d59087eb0bbd28 Mon Sep 17 00:00:00 2001 From: StanR <8269193+stanriders@users.noreply.github.com> Date: Tue, 3 Mar 2026 04:14:31 +0500 Subject: [PATCH] Fix combined slider velocity calculation (#36773) This changes how the current/previous velocity is being calculated in Aim. Currently it's being calculated as an addition of 2 velocities together which isn't really correct, instead here velocity is being calculated as a (combined distances) / (combined times). On practice this buffs underweighted slider maps while overweighted ones stay about the same https://pp.huismetbenen.nl/rankings/players/use-proper-slider-velocity --- .../Difficulty/Evaluators/AimEvaluator.cs | 14 +++++--------- .../Preprocessing/OsuDifficultyHitObject.cs | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/AimEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/AimEvaluator.cs index b9436b448b..4e28b28b88 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/AimEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/AimEvaluator.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators { private const double wide_angle_multiplier = 1.5; private const double acute_angle_multiplier = 2.6; - private const double slider_multiplier = 1.5; + private const double slider_multiplier = 2.9; private const double velocity_change_multiplier = 0.9; private const double wiggle_multiplier = 1.02; // WARNING: Increasing this multiplier beyond 1.02 reduces difficulty as distance increases. Refer to the desmos link above the wiggle bonus calculation @@ -46,10 +46,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators // But if the last object is a slider, then we extend the travel velocity through the slider into the current object. if (osuLastObj.BaseObject is Slider && withSliderTravelDistance) { - double travelVelocity = osuLastObj.TravelDistance / osuLastObj.TravelTime; // calculate the slider velocity from slider head to slider end. - double movementVelocity = osuCurrObj.MinimumJumpDistance / osuCurrObj.MinimumJumpTime; // calculate the movement velocity from slider end to current object - - currVelocity = Math.Max(currVelocity, movementVelocity + travelVelocity); // take the larger total combined velocity. + double sliderDistance = osuLastObj.LazyTravelDistance + osuCurrObj.LazyJumpDistance; + currVelocity = Math.Max(currVelocity, sliderDistance / osuCurrObj.AdjustedDeltaTime); } // As above, do the same for the previous hitobject. @@ -58,10 +56,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators if (osuLastLastObj.BaseObject is Slider && withSliderTravelDistance) { - double travelVelocity = osuLastLastObj.TravelDistance / osuLastLastObj.TravelTime; - double movementVelocity = osuLastObj.MinimumJumpDistance / osuLastObj.MinimumJumpTime; - - prevVelocity = Math.Max(prevVelocity, movementVelocity + travelVelocity); + double sliderDistance = osuLastLastObj.LazyTravelDistance + osuLastObj.LazyJumpDistance; + prevVelocity = Math.Max(prevVelocity, sliderDistance / osuLastObj.AdjustedDeltaTime); } double wideAngleBonus = 0; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index b9b985fdc7..cee768b06f 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -199,7 +199,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing if (BaseObject is Slider currentSlider) { // Bonus for repeat sliders until a better per nested object strain system can be achieved. - TravelDistance = LazyTravelDistance * Math.Pow(1 + currentSlider.RepeatCount / 2.5, 1.0 / 2.5); + TravelDistance = LazyTravelDistance * Math.Max(1, Math.Pow(currentSlider.RepeatCount, 0.2)); TravelTime = Math.Max(LazyTravelTime / clockRate, MIN_DELTA_TIME); }