From 3309ab2be32441415d3432aa6d0476a8b1604bb0 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Sun, 13 Jun 2021 15:18:35 +0200 Subject: [PATCH 01/10] balance changes --- .../Difficulty/OsuDifficultyCalculator.cs | 4 +- .../Difficulty/OsuPerformanceCalculator.cs | 7 ++- .../Difficulty/Skills/Aim.cs | 4 +- .../Difficulty/Skills/OsuSkill.cs | 44 +++++++++++++++++++ .../Difficulty/Skills/Speed.cs | 2 +- 5 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 75d6786d95a3..b83e504a7a34 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -32,8 +32,8 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat if (beatmap.HitObjects.Count == 0) return new OsuDifficultyAttributes { Mods = mods, Skills = skills }; - double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; - double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; + double aimRating = Math.Sqrt((skills[0] as OsuSkill).OsuDifficultyValue()) * difficulty_multiplier; + double speedRating = Math.Sqrt((skills[1] as OsuSkill).OsuDifficultyValue()) * difficulty_multiplier; double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; HitWindows hitWindows = new OsuHitWindows(); diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 44a9dd2f1f59..90ded2b837e3 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -106,22 +106,25 @@ private double computeAimValue() else if (Attributes.ApproachRate < 8.0) approachRateFactor += 0.01 * (8.0 - Attributes.ApproachRate); - aimValue *= 1.0 + Math.Min(approachRateFactor, approachRateFactor * (totalHits / 1000.0)); + approachRateFactor = 1.0 + Math.Min(approachRateFactor, approachRateFactor * (totalHits / 1000.0)); // We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR. if (mods.Any(h => h is OsuModHidden)) aimValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate); + double flashlightBonus = 1.0; if (mods.Any(h => h is OsuModFlashlight)) { // Apply object-based bonus for flashlight. - aimValue *= 1.0 + 0.35 * Math.Min(1.0, totalHits / 200.0) + + flashlightBonus = 1.0 + 0.35 * Math.Min(1.0, totalHits / 200.0) + (totalHits > 200 ? 0.3 * Math.Min(1.0, (totalHits - 200) / 300.0) + (totalHits > 500 ? (totalHits - 500) / 1200.0 : 0.0) : 0.0); } + aimValue *= Math.Max(flashlightBonus, approachRateFactor); + // Scale the aim value with accuracy _slightly_ aimValue *= 0.5 + accuracy / 2.0; // It is important to also consider accuracy difficulty when doing that diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index cb819ec09067..b7bb10a87e67 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances. /// - public class Aim : StrainSkill + public class Aim : OsuSkill { private const double angle_bonus_begin = Math.PI / 3; private const double timing_threshold = 107; @@ -47,7 +47,7 @@ protected override double StrainValueOf(DifficultyHitObject current) Math.Max(osuPrevious.JumpDistance - scale, 0) * Math.Pow(Math.Sin(osuCurrent.Angle.Value - angle_bonus_begin), 2) * Math.Max(osuCurrent.JumpDistance - scale, 0)); - result = 1.5 * applyDiminishingExp(Math.Max(0, angleBonus)) / Math.Max(timing_threshold, osuPrevious.StrainTime); + result = 1.35 * applyDiminishingExp(Math.Max(0, angleBonus)) / Math.Max(timing_threshold, osuPrevious.StrainTime); } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs new file mode 100644 index 000000000000..d113f7135f62 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using osu.Game.Rulesets.Difficulty.Preprocessing; +using osu.Game.Rulesets.Difficulty.Skills; +using osu.Game.Rulesets.Mods; +using System.Linq; + +namespace osu.Game.Rulesets.Osu.Difficulty.Skills +{ + public abstract class OsuSkill : StrainSkill + { + public OsuSkill(Mod[] mods) : base(mods) + { + } + + public double OsuDifficultyValue() + { + double difficulty = 0; + double weight = 1; + + double strainMultiplier; + List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList(); + + double baseLine = 0.6; + + for (int i = 0; i <= 9; i++) + { + strainMultiplier = baseLine + Math.Log10(i+1) * (1.0 - baseLine); + strains[i] = strains[i] * strainMultiplier; + } + + // Difficulty is the weighted sum of the highest strains from every section. + // We're sorting from highest to lowest strain. + foreach (double strain in strains.OrderByDescending(d => d)) + { + difficulty += strain * weight; + weight *= DecayWeight; + } + + return difficulty * 1.06; + } + } +} diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index fbac080fc6c9..975a633badb0 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. /// - public class Speed : StrainSkill + public class Speed : OsuSkill { private const double single_spacing_threshold = 125; From 4c949d9829ae58eddf0e7df9227d66b0fc189bcd Mon Sep 17 00:00:00 2001 From: emu1337 Date: Sun, 13 Jun 2021 21:20:08 +0200 Subject: [PATCH 02/10] reduced diffspike nerf --- osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs index d113f7135f62..d52b95d3ec65 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs @@ -22,7 +22,7 @@ public double OsuDifficultyValue() double strainMultiplier; List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList(); - double baseLine = 0.6; + double baseLine = 0.68; for (int i = 0; i <= 9; i++) { From fea7b029aa31da7037d9aa91d330412ab800dd40 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Mon, 14 Jun 2021 19:18:49 +0200 Subject: [PATCH 03/10] refactored diffspike nerf --- .../Difficulty/OsuDifficultyCalculator.cs | 4 ++-- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 2 +- .../Skills/{OsuSkill.cs => OsuStrainSkill.cs} | 16 +++++++++------- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) rename osu.Game.Rulesets.Osu/Difficulty/Skills/{OsuSkill.cs => OsuStrainSkill.cs} (64%) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index b83e504a7a34..fdcc6f44a675 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -32,8 +32,8 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat if (beatmap.HitObjects.Count == 0) return new OsuDifficultyAttributes { Mods = mods, Skills = skills }; - double aimRating = Math.Sqrt((skills[0] as OsuSkill).OsuDifficultyValue()) * difficulty_multiplier; - double speedRating = Math.Sqrt((skills[1] as OsuSkill).OsuDifficultyValue()) * difficulty_multiplier; + double aimRating = Math.Sqrt((skills[0] as OsuStrainSkill).OsuDifficultyValue()) * difficulty_multiplier; + double speedRating = Math.Sqrt((skills[1] as OsuStrainSkill).OsuDifficultyValue()) * difficulty_multiplier; double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; HitWindows hitWindows = new OsuHitWindows(); diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index b7bb10a87e67..a95bf4fa947b 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances. /// - public class Aim : OsuSkill + public class Aim : OsuStrainSkill { private const double angle_bonus_begin = Math.PI / 3; private const double timing_threshold = 107; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs similarity index 64% rename from osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs rename to osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index d52b95d3ec65..f1c7ae340335 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -8,9 +8,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { - public abstract class OsuSkill : StrainSkill + public abstract class OsuStrainSkill : StrainSkill { - public OsuSkill(Mod[] mods) : base(mods) + protected virtual int ReducedSectionCount => 9; + protected virtual double ReducedStrainBaseline => 0.68; + protected virtual double DifficultyMultiplier => 1.06; + + public OsuStrainSkill(Mod[] mods) : base(mods) { } @@ -22,11 +26,9 @@ public double OsuDifficultyValue() double strainMultiplier; List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList(); - double baseLine = 0.68; - - for (int i = 0; i <= 9; i++) + for (int i = 0; i < ReducedSectionCount; i++) { - strainMultiplier = baseLine + Math.Log10(i+1) * (1.0 - baseLine); + strainMultiplier = ReducedStrainBaseline + Math.Log10(i * 9.0 / ReducedSectionCount + 1) * (1.0 - ReducedStrainBaseline); strains[i] = strains[i] * strainMultiplier; } @@ -38,7 +40,7 @@ public double OsuDifficultyValue() weight *= DecayWeight; } - return difficulty * 1.06; + return difficulty * DifficultyMultiplier; } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 975a633badb0..0d8400badc74 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. /// - public class Speed : OsuSkill + public class Speed : OsuStrainSkill { private const double single_spacing_threshold = 125; From e987a511bad01745370702f7104cc955e165ce1d Mon Sep 17 00:00:00 2001 From: emu1337 Date: Mon, 14 Jun 2021 19:22:35 +0200 Subject: [PATCH 04/10] diffspike & wide angle balance --- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 2 +- osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index a95bf4fa947b..e063276ec514 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -47,7 +47,7 @@ protected override double StrainValueOf(DifficultyHitObject current) Math.Max(osuPrevious.JumpDistance - scale, 0) * Math.Pow(Math.Sin(osuCurrent.Angle.Value - angle_bonus_begin), 2) * Math.Max(osuCurrent.JumpDistance - scale, 0)); - result = 1.35 * applyDiminishingExp(Math.Max(0, angleBonus)) / Math.Max(timing_threshold, osuPrevious.StrainTime); + result = 1.4 * applyDiminishingExp(Math.Max(0, angleBonus)) / Math.Max(timing_threshold, osuPrevious.StrainTime); } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index f1c7ae340335..136c4ae309b2 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -10,9 +10,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { public abstract class OsuStrainSkill : StrainSkill { - protected virtual int ReducedSectionCount => 9; - protected virtual double ReducedStrainBaseline => 0.68; - protected virtual double DifficultyMultiplier => 1.06; + protected virtual int ReducedSectionCount => 10; + protected virtual double ReducedStrainBaseline => 0.7; + protected virtual double DifficultyMultiplier => 1.08; public OsuStrainSkill(Mod[] mods) : base(mods) { From be68950c307f1ffa355b1e6fef021b27f73a36c4 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Wed, 16 Jun 2021 03:34:46 +0200 Subject: [PATCH 05/10] refactoring --- .../Difficulty/OsuDifficultyCalculator.cs | 4 ++-- .../Difficulty/OsuPerformanceCalculator.cs | 9 +++++---- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 1 - .../Difficulty/Skills/OsuStrainSkill.cs | 17 +++++++++-------- .../Difficulty/Skills/Speed.cs | 1 - .../Rulesets/Difficulty/Skills/StrainSkill.cs | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index fdcc6f44a675..75d6786d95a3 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -32,8 +32,8 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat if (beatmap.HitObjects.Count == 0) return new OsuDifficultyAttributes { Mods = mods, Skills = skills }; - double aimRating = Math.Sqrt((skills[0] as OsuStrainSkill).OsuDifficultyValue()) * difficulty_multiplier; - double speedRating = Math.Sqrt((skills[1] as OsuStrainSkill).OsuDifficultyValue()) * difficulty_multiplier; + double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; + double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; HitWindows hitWindows = new OsuHitWindows(); diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 90ded2b837e3..74840853c007 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -113,14 +113,15 @@ private double computeAimValue() aimValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate); double flashlightBonus = 1.0; + if (mods.Any(h => h is OsuModFlashlight)) { // Apply object-based bonus for flashlight. flashlightBonus = 1.0 + 0.35 * Math.Min(1.0, totalHits / 200.0) + - (totalHits > 200 - ? 0.3 * Math.Min(1.0, (totalHits - 200) / 300.0) + - (totalHits > 500 ? (totalHits - 500) / 1200.0 : 0.0) - : 0.0); + (totalHits > 200 + ? 0.3 * Math.Min(1.0, (totalHits - 200) / 300.0) + + (totalHits > 500 ? (totalHits - 500) / 1200.0 : 0.0) + : 0.0); } aimValue *= Math.Max(flashlightBonus, approachRateFactor); diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index e063276ec514..16a18cbcb90c 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -3,7 +3,6 @@ using System; using osu.Game.Rulesets.Difficulty.Preprocessing; -using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index 136c4ae309b2..93101bf3c33d 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -1,7 +1,8 @@ -using System; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; using System.Collections.Generic; -using System.Text; -using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Mods; using System.Linq; @@ -14,22 +15,22 @@ public abstract class OsuStrainSkill : StrainSkill protected virtual double ReducedStrainBaseline => 0.7; protected virtual double DifficultyMultiplier => 1.08; - public OsuStrainSkill(Mod[] mods) : base(mods) + protected OsuStrainSkill(Mod[] mods) + : base(mods) { } - public double OsuDifficultyValue() + public override double DifficultyValue() { double difficulty = 0; double weight = 1; - double strainMultiplier; List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList(); + // We are reducing the highest strains first to account for extreme difficulty spikes for (int i = 0; i < ReducedSectionCount; i++) { - strainMultiplier = ReducedStrainBaseline + Math.Log10(i * 9.0 / ReducedSectionCount + 1) * (1.0 - ReducedStrainBaseline); - strains[i] = strains[i] * strainMultiplier; + strains[i] *= ReducedStrainBaseline + Math.Log10(i * 9.0 / ReducedSectionCount + 1) * (1.0 - ReducedStrainBaseline); } // Difficulty is the weighted sum of the highest strains from every section. diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 0d8400badc74..872bb0601d6d 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -3,7 +3,6 @@ using System; using osu.Game.Rulesets.Difficulty.Preprocessing; -using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs index 71cee3681276..d4fcefab9b17 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs @@ -109,7 +109,7 @@ private void startNewSectionFrom(double time) /// /// Returns the calculated difficulty value representing all s that have been processed up to this point. /// - public sealed override double DifficultyValue() + public override double DifficultyValue() { double difficulty = 0; double weight = 1; From 18fe05b7b5856e210fa2f91f368d2ec317bd777f Mon Sep 17 00:00:00 2001 From: emu1337 Date: Wed, 16 Jun 2021 15:13:46 +0200 Subject: [PATCH 06/10] diffspikes balance --- osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 4 ++-- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index 93101bf3c33d..565cc5805f26 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -12,8 +12,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills public abstract class OsuStrainSkill : StrainSkill { protected virtual int ReducedSectionCount => 10; - protected virtual double ReducedStrainBaseline => 0.7; - protected virtual double DifficultyMultiplier => 1.08; + protected virtual double ReducedStrainBaseline => 0.75; + protected virtual double DifficultyMultiplier => 1.06; protected OsuStrainSkill(Mod[] mods) : base(mods) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 872bb0601d6d..f0eb199e5f6d 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -22,6 +22,8 @@ public class Speed : OsuStrainSkill protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; + protected override int ReducedSectionCount => 5; + protected override double DifficultyMultiplier => 1.04; private const double min_speed_bonus = 75; // ~200BPM private const double max_speed_bonus = 45; // ~330BPM From 41662a16431eba5ddee0c75f7dbc870f1537fda1 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Wed, 16 Jun 2021 19:54:22 +0200 Subject: [PATCH 07/10] refactored for clarity --- osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index 565cc5805f26..56c00d263d8f 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -6,6 +6,7 @@ using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Mods; using System.Linq; +using osu.Framework.Utils; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { @@ -30,7 +31,9 @@ public override double DifficultyValue() // We are reducing the highest strains first to account for extreme difficulty spikes for (int i = 0; i < ReducedSectionCount; i++) { - strains[i] *= ReducedStrainBaseline + Math.Log10(i * 9.0 / ReducedSectionCount + 1) * (1.0 - ReducedStrainBaseline); + strains[i] *= ReducedStrainBaseline + + Math.Log10(Interpolation.Lerp(1, 10, Math.Clamp((float)i / ReducedSectionCount, 0, 1))) + * (1.0 - ReducedStrainBaseline); } // Difficulty is the weighted sum of the highest strains from every section. From 2665a873f87e7bf2528f26507a0eb4f289b6a845 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Wed, 16 Jun 2021 19:55:19 +0200 Subject: [PATCH 08/10] fixed an error with extremely short maps --- osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index 56c00d263d8f..5a40524e8a9a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -29,7 +29,7 @@ public override double DifficultyValue() List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList(); // We are reducing the highest strains first to account for extreme difficulty spikes - for (int i = 0; i < ReducedSectionCount; i++) + for (int i = 0; i < Math.Min(strains.Count, ReducedSectionCount); i++) { strains[i] *= ReducedStrainBaseline + Math.Log10(Interpolation.Lerp(1, 10, Math.Clamp((float)i / ReducedSectionCount, 0, 1))) From 8c4e60e5ccca84571b0aa5494e665519e7d652b7 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Thu, 17 Jun 2021 21:41:06 +0200 Subject: [PATCH 09/10] xmldoc and refactoring --- .../Difficulty/Skills/OsuStrainSkill.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index 5a40524e8a9a..e47edc37cca9 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -12,8 +12,20 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { public abstract class OsuStrainSkill : StrainSkill { + /// + /// The number of sections with the highest strains, which the peak strain reductions will apply to. + /// This is done in order to decrease their impact on the overall difficulty of the map for this skill. + /// protected virtual int ReducedSectionCount => 10; + + /// + /// The baseline multiplier applied to the section with the biggest strain. + /// protected virtual double ReducedStrainBaseline => 0.75; + + /// + /// The final multiplier to be applied to after all other calculations. + /// protected virtual double DifficultyMultiplier => 1.06; protected OsuStrainSkill(Mod[] mods) @@ -31,9 +43,8 @@ public override double DifficultyValue() // We are reducing the highest strains first to account for extreme difficulty spikes for (int i = 0; i < Math.Min(strains.Count, ReducedSectionCount); i++) { - strains[i] *= ReducedStrainBaseline - + Math.Log10(Interpolation.Lerp(1, 10, Math.Clamp((float)i / ReducedSectionCount, 0, 1))) - * (1.0 - ReducedStrainBaseline); + double scale = Math.Log10(Interpolation.Lerp(1, 10, Math.Clamp((float)i / ReducedSectionCount, 0, 1))); + strains[i] *= Interpolation.Lerp(ReducedStrainBaseline, 1.0, scale); } // Difficulty is the weighted sum of the highest strains from every section. From 403909b598e4c735a1a1e47c429593eb54164b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 18 Jun 2021 12:49:49 +0200 Subject: [PATCH 10/10] Update SR test values in line with diffspike changes --- .../OsuDifficultyCalculatorTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs index afd94f457004..8d8387378e74 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs @@ -15,13 +15,13 @@ public class OsuDifficultyCalculatorTest : DifficultyCalculatorTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; - [TestCase(6.9311451172574934d, "diffcalc-test")] - [TestCase(1.0736586907780401d, "zero-length-sliders")] + [TestCase(6.7568168283591499d, "diffcalc-test")] + [TestCase(1.0348244046058293d, "zero-length-sliders")] public void Test(double expected, string name) => base.Test(expected, name); - [TestCase(8.7212283220412345d, "diffcalc-test")] - [TestCase(1.3212137158641493d, "zero-length-sliders")] + [TestCase(8.4783236764532557d, "diffcalc-test")] + [TestCase(1.2708532136987165d, "zero-length-sliders")] public void TestClockRateAdjusted(double expected, string name) => Test(expected, name, new OsuModDoubleTime());