From 8f692436f57d1b00fbcd203829922fa241a4ed67 Mon Sep 17 00:00:00 2001 From: Givy120 Date: Fri, 27 Mar 2026 22:02:00 +0100 Subject: [PATCH 1/8] Add wide angle bonus to agility --- .../Difficulty/Evaluators/Aim/AgilityEvaluator.cs | 6 ++++++ .../Difficulty/Evaluators/Aim/SnapAimEvaluator.cs | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs index 98a5c7680e15..7ac257043d70 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs @@ -12,6 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim public static class AgilityEvaluator { private const double distance_cap = OsuDifficultyHitObject.NORMALISED_DIAMETER * 1.25; // 1.25 circles distance between centers + private const double wide_angle_multiplier = 0.5; /// /// Evaluates the difficulty of fast aiming @@ -31,6 +32,11 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current) double strain = distanceScaled * 1000 / osuCurrObj.AdjustedDeltaTime; + if (osuCurrObj.Angle != null) + { + strain *= 1 + SnapAimEvaluator.CalcWideAngleBonus(osuCurrObj.Angle.Value) * wide_angle_multiplier; + } + strain *= Math.Pow(osuCurrObj.SmallCircleBonus, 1.5); strain *= highBpmBonus(osuCurrObj.AdjustedDeltaTime); diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs index 75ecfe89ecc1..3105d16aff4c 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim { public static class SnapAimEvaluator { - private const double wide_angle_multiplier = 1.05; + private const double wide_angle_multiplier = 0.8; private const double acute_angle_multiplier = 2.41; private const double slider_multiplier = 1.5; private const double velocity_change_multiplier = 0.9; @@ -84,10 +84,10 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current, bool with DifficultyCalculationUtils.Smootherstep(currDistance, 0, diameter * 2); } - wideAngleBonus = calcWideAngleBonus(currAngle); + wideAngleBonus = CalcWideAngleBonus(currAngle); // Penalize angle repetition. - wideAngleBonus *= 0.25 + 0.75 * (1 - Math.Min(wideAngleBonus, Math.Pow(calcWideAngleBonus(lastAngle), 3))); + wideAngleBonus *= 0.25 + 0.75 * (1 - Math.Min(wideAngleBonus, Math.Pow(CalcWideAngleBonus(lastAngle), 3))); wideAngleBonus *= angleBonus; @@ -213,7 +213,7 @@ private static double vectorAngleRepetition(OsuDifficultyHitObject current, OsuD return Math.Pow(baseNerf + (1 - baseNerf) * vectorRepetition * maximum_vector_influence * stackFactor, 2); } - private static double calcWideAngleBonus(double angle) => DifficultyCalculationUtils.Smoothstep(angle, double.DegreesToRadians(40), double.DegreesToRadians(140)); + public static double CalcWideAngleBonus(double angle) => DifficultyCalculationUtils.Smoothstep(angle, double.DegreesToRadians(40), double.DegreesToRadians(140)); public static double CalcAcuteAngleBonus(double angle) => DifficultyCalculationUtils.Smoothstep(angle, double.DegreesToRadians(140), double.DegreesToRadians(40)); } From 2127ccc13cbacb19085e3cf2314207ce0ae78fbe Mon Sep 17 00:00:00 2001 From: Givy120 Date: Fri, 27 Mar 2026 22:04:53 +0100 Subject: [PATCH 2/8] Adjust uncomfy high bpm bonus --- .../Difficulty/Evaluators/Aim/SnapAimEvaluator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs index 3105d16aff4c..a4a59b5b019d 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs @@ -76,7 +76,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current, bool with acuteAngleBonus = CalcAcuteAngleBonus(currAngle); // Penalize angle repetition. - acuteAngleBonus *= 0.08 + 0.92 * (1 - Math.Min(acuteAngleBonus, Math.Pow(CalcAcuteAngleBonus(lastAngle), 3))); + acuteAngleBonus *= 0.08 + 0.88 * (1 - Math.Min(acuteAngleBonus, Math.Pow(CalcAcuteAngleBonus(lastAngle), 3))); // Apply acute angle bonus for BPM above 300 1/2 and distance more than one diameter acuteAngleBonus *= angleBonus * From 720c4fc877d0bbd3fd286aec71c9b5e5e4aa2759 Mon Sep 17 00:00:00 2001 From: Givy120 Date: Fri, 27 Mar 2026 22:38:24 +0100 Subject: [PATCH 3/8] Add rhythm check --- .../Difficulty/Evaluators/Aim/AgilityEvaluator.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs index 7ac257043d70..723f985ac64e 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim public static class AgilityEvaluator { private const double distance_cap = OsuDifficultyHitObject.NORMALISED_DIAMETER * 1.25; // 1.25 circles distance between centers - private const double wide_angle_multiplier = 0.5; + private const double wide_angle_multiplier = 0.6; /// /// Evaluates the difficulty of fast aiming @@ -32,9 +32,11 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current) double strain = distanceScaled * 1000 / osuCurrObj.AdjustedDeltaTime; - if (osuCurrObj.Angle != null) + if (osuCurrObj.Angle != null && osuPrevObj != null) { - strain *= 1 + SnapAimEvaluator.CalcWideAngleBonus(osuCurrObj.Angle.Value) * wide_angle_multiplier; + double wideAngleBonus = SnapAimEvaluator.CalcWideAngleBonus(osuCurrObj.Angle.Value); + wideAngleBonus *= DifficultyCalculationUtils.ReverseLerp(osuPrevObj.AdjustedDeltaTime, osuCurrObj.AdjustedDeltaTime * 0.5, osuCurrObj.AdjustedDeltaTime * 0.75); + strain *= 1 + wideAngleBonus * wide_angle_multiplier; } strain *= Math.Pow(osuCurrObj.SmallCircleBonus, 1.5); From 824519e308c0d698714b6788fc3e77d28f135aaa Mon Sep 17 00:00:00 2001 From: Givy120 Date: Fri, 27 Mar 2026 23:14:56 +0100 Subject: [PATCH 4/8] Balance a bit --- .../Difficulty/Evaluators/Aim/SnapAimEvaluator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs index a4a59b5b019d..0e5a2afe9f62 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim { public static class SnapAimEvaluator { - private const double wide_angle_multiplier = 0.8; + private const double wide_angle_multiplier = 0.85; private const double acute_angle_multiplier = 2.41; private const double slider_multiplier = 1.5; private const double velocity_change_multiplier = 0.9; @@ -76,7 +76,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current, bool with acuteAngleBonus = CalcAcuteAngleBonus(currAngle); // Penalize angle repetition. - acuteAngleBonus *= 0.08 + 0.88 * (1 - Math.Min(acuteAngleBonus, Math.Pow(CalcAcuteAngleBonus(lastAngle), 3))); + acuteAngleBonus *= 0.08 + 0.87 * (1 - Math.Min(acuteAngleBonus, Math.Pow(CalcAcuteAngleBonus(lastAngle), 3))); // Apply acute angle bonus for BPM above 300 1/2 and distance more than one diameter acuteAngleBonus *= angleBonus * From fe2ca84ab7698c41192fc51030cc8c6e9db312e1 Mon Sep 17 00:00:00 2001 From: Givy120 Date: Sat, 28 Mar 2026 02:31:35 +0100 Subject: [PATCH 5/8] Reduce buff on doubles --- .../Difficulty/Evaluators/Aim/AgilityEvaluator.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs index 723f985ac64e..d8a700a4a561 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs @@ -36,6 +36,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current) { double wideAngleBonus = SnapAimEvaluator.CalcWideAngleBonus(osuCurrObj.Angle.Value); wideAngleBonus *= DifficultyCalculationUtils.ReverseLerp(osuPrevObj.AdjustedDeltaTime, osuCurrObj.AdjustedDeltaTime * 0.5, osuCurrObj.AdjustedDeltaTime * 0.75); + wideAngleBonus *= DifficultyCalculationUtils.Smootherstep(distance, 0, OsuDifficultyHitObject.NORMALISED_DIAMETER); strain *= 1 + wideAngleBonus * wide_angle_multiplier; } From d94140f5507f896777fd62d63765dcfc44526797 Mon Sep 17 00:00:00 2001 From: Givy120 Date: Sat, 28 Mar 2026 03:25:10 +0100 Subject: [PATCH 6/8] Use min distance for doubles check --- .../Difficulty/Evaluators/Aim/AgilityEvaluator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs index d8a700a4a561..84078503fefe 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs @@ -36,7 +36,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current) { double wideAngleBonus = SnapAimEvaluator.CalcWideAngleBonus(osuCurrObj.Angle.Value); wideAngleBonus *= DifficultyCalculationUtils.ReverseLerp(osuPrevObj.AdjustedDeltaTime, osuCurrObj.AdjustedDeltaTime * 0.5, osuCurrObj.AdjustedDeltaTime * 0.75); - wideAngleBonus *= DifficultyCalculationUtils.Smootherstep(distance, 0, OsuDifficultyHitObject.NORMALISED_DIAMETER); + wideAngleBonus *= DifficultyCalculationUtils.Smootherstep(Math.Min(osuCurrObj.JumpDistance, osuPrevObj.JumpDistance), 0, OsuDifficultyHitObject.NORMALISED_DIAMETER); strain *= 1 + wideAngleBonus * wide_angle_multiplier; } From 630f3a6cc2032d2c184b3e80fcdb494731373f3e Mon Sep 17 00:00:00 2001 From: Givy120 Date: Mon, 30 Mar 2026 15:10:43 +0200 Subject: [PATCH 7/8] Base wide angle bonus on min velocity just as in snap --- .../Evaluators/Aim/AgilityEvaluator.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs index 84078503fefe..1ca75c9a7180 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs @@ -24,27 +24,31 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current) var osuCurrObj = (OsuDifficultyHitObject)current; var osuPrevObj = current.Index > 0 ? (OsuDifficultyHitObject)current.Previous(0) : null; + var osuPrevObj1 = current.Index > 1 ? (OsuDifficultyHitObject)current.Previous(1) : null; - double travelDistance = osuPrevObj?.LazyTravelDistance ?? 0; - double distance = travelDistance + osuCurrObj.LazyJumpDistance; - - double distanceScaled = Math.Min(distance, distance_cap) / distance_cap; - - double strain = distanceScaled * 1000 / osuCurrObj.AdjustedDeltaTime; + double strain = getStrain(osuCurrObj, osuPrevObj); if (osuCurrObj.Angle != null && osuPrevObj != null) { double wideAngleBonus = SnapAimEvaluator.CalcWideAngleBonus(osuCurrObj.Angle.Value); wideAngleBonus *= DifficultyCalculationUtils.ReverseLerp(osuPrevObj.AdjustedDeltaTime, osuCurrObj.AdjustedDeltaTime * 0.5, osuCurrObj.AdjustedDeltaTime * 0.75); - wideAngleBonus *= DifficultyCalculationUtils.Smootherstep(Math.Min(osuCurrObj.JumpDistance, osuPrevObj.JumpDistance), 0, OsuDifficultyHitObject.NORMALISED_DIAMETER); - strain *= 1 + wideAngleBonus * wide_angle_multiplier; + + double strainPrev = getStrain(osuPrevObj, osuPrevObj1); + strain += Math.Min(strain, strainPrev) * wideAngleBonus * wide_angle_multiplier; } strain *= Math.Pow(osuCurrObj.SmallCircleBonus, 1.5); - strain *= highBpmBonus(osuCurrObj.AdjustedDeltaTime); - return strain * DifficultyCalculationUtils.Smootherstep(distance, 0, OsuDifficultyHitObject.NORMALISED_RADIUS); + return strain * DifficultyCalculationUtils.Smootherstep(osuCurrObj.LazyJumpDistance, 0, OsuDifficultyHitObject.NORMALISED_RADIUS); + } + + private static double getStrain(OsuDifficultyHitObject osuCurrObj, OsuDifficultyHitObject? osuPrevObj) + { + double travelDistance = osuPrevObj?.LazyTravelDistance ?? 0; + double distance = travelDistance + osuCurrObj.LazyJumpDistance; + double distanceScaled = Math.Min(distance, distance_cap) / distance_cap; + return distanceScaled * 1000 / osuCurrObj.AdjustedDeltaTime; } private static double highBpmBonus(double ms) => 1 / (1 - Math.Pow(0.2, ms / 1000)); From 837e35f2c702573ee9f0e7b9713bf682da0f87e6 Mon Sep 17 00:00:00 2001 From: Givy120 Date: Mon, 30 Mar 2026 15:19:40 +0200 Subject: [PATCH 8/8] Slightly increase agility wide angle --- .../Difficulty/Evaluators/Aim/AgilityEvaluator.cs | 2 +- .../Difficulty/Evaluators/Aim/SnapAimEvaluator.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs index 1ca75c9a7180..181f7fe309be 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/AgilityEvaluator.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim public static class AgilityEvaluator { private const double distance_cap = OsuDifficultyHitObject.NORMALISED_DIAMETER * 1.25; // 1.25 circles distance between centers - private const double wide_angle_multiplier = 0.6; + private const double wide_angle_multiplier = 0.65; /// /// Evaluates the difficulty of fast aiming diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs index 0e5a2afe9f62..6cf27a184df9 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/Aim/SnapAimEvaluator.cs @@ -76,7 +76,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current, bool with acuteAngleBonus = CalcAcuteAngleBonus(currAngle); // Penalize angle repetition. - acuteAngleBonus *= 0.08 + 0.87 * (1 - Math.Min(acuteAngleBonus, Math.Pow(CalcAcuteAngleBonus(lastAngle), 3))); + acuteAngleBonus *= 0.08 + 0.86 * (1 - Math.Min(acuteAngleBonus, Math.Pow(CalcAcuteAngleBonus(lastAngle), 3))); // Apply acute angle bonus for BPM above 300 1/2 and distance more than one diameter acuteAngleBonus *= angleBonus *