From cff9dab650b8bc0e453be6b312a96b778fdcbc93 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Tue, 14 Dec 2021 03:11:04 +0000
Subject: [PATCH 01/31] Remove combo scaling and change miss penalty
---
.../Difficulty/OsuPerformanceCalculator.cs | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 8d45c7a8cc..6de6572b93 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -101,13 +101,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= lengthBonus;
- // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
- aimValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), effectiveMissCount);
-
- // Combo scaling.
- if (Attributes.MaxCombo > 0)
- aimValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
+ aimValue *= Math.Pow(0.97, effectiveMissCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -151,13 +146,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
speedValue *= lengthBonus;
- // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
- speedValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
-
- // Combo scaling.
- if (Attributes.MaxCombo > 0)
- speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
+ speedValue *= Math.Pow(0.97, effectiveMissCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -238,9 +228,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(h => h is OsuModHidden))
flashlightValue *= 1.3;
- // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
- flashlightValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
+ flashlightValue *= Math.Pow(0.97, effectiveMissCount);
// Combo scaling.
if (Attributes.MaxCombo > 0)
From 86ad42a7440ec0a1478e2030209c2675985e3220 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Tue, 14 Dec 2021 17:47:41 +0000
Subject: [PATCH 02/31] Nerf length bonus
---
osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 6de6572b93..6ade8c1732 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double aimValue = Math.Pow(5.0 * Math.Max(1.0, rawAim / 0.0675) - 4.0, 3.0) / 100000.0;
// Longer maps are worth more.
- double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
+ double lengthBonus = 0.95 + 0.25 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
aimValue *= lengthBonus;
@@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double speedValue = Math.Pow(5.0 * Math.Max(1.0, Attributes.SpeedStrain / 0.0675) - 4.0, 3.0) / 100000.0;
// Longer maps are worth more.
- double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
+ double lengthBonus = 0.95 + 0.25 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
speedValue *= lengthBonus;
From 489aa43b1bab6efeb0ed05e97ec66181dfe3b4f4 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Tue, 14 Dec 2021 19:57:36 +0000
Subject: [PATCH 03/31] Make miss penalty harsher
---
.../Difficulty/OsuPerformanceCalculator.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 6ade8c1732..0459c64c0e 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -96,13 +96,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double aimValue = Math.Pow(5.0 * Math.Max(1.0, rawAim / 0.0675) - 4.0, 3.0) / 100000.0;
// Longer maps are worth more.
- double lengthBonus = 0.95 + 0.25 * Math.Min(1.0, totalHits / 2000.0) +
+ double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
aimValue *= lengthBonus;
if (effectiveMissCount > 0)
- aimValue *= Math.Pow(0.97, effectiveMissCount);
+ aimValue *= Math.Pow(0.96, effectiveMissCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -142,12 +142,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double speedValue = Math.Pow(5.0 * Math.Max(1.0, Attributes.SpeedStrain / 0.0675) - 4.0, 3.0) / 100000.0;
// Longer maps are worth more.
- double lengthBonus = 0.95 + 0.25 * Math.Min(1.0, totalHits / 2000.0) +
+ double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
speedValue *= lengthBonus;
if (effectiveMissCount > 0)
- speedValue *= Math.Pow(0.97, effectiveMissCount);
+ speedValue *= Math.Pow(0.96, effectiveMissCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -229,7 +229,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
flashlightValue *= 1.3;
if (effectiveMissCount > 0)
- flashlightValue *= Math.Pow(0.97, effectiveMissCount);
+ flashlightValue *= Math.Pow(0.96, effectiveMissCount);
// Combo scaling.
if (Attributes.MaxCombo > 0)
From bac4cfed50be4e3d1e0264ce0cd9099c3132d4b5 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Thu, 16 Dec 2021 18:37:57 +0000
Subject: [PATCH 04/31] Use frost's miss count penalty
---
.../Difficulty/OsuPerformanceCalculator.cs | 21 ++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 0459c64c0e..bba53c92fc 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= lengthBonus;
if (effectiveMissCount > 0)
- aimValue *= Math.Pow(0.96, effectiveMissCount);
+ aimValue *= calculateMissPenalty(effectiveMissCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
speedValue *= lengthBonus;
if (effectiveMissCount > 0)
- speedValue *= Math.Pow(0.96, effectiveMissCount);
+ speedValue *= calculateMissPenalty(effectiveMissCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -229,7 +229,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
flashlightValue *= 1.3;
if (effectiveMissCount > 0)
- flashlightValue *= Math.Pow(0.96, effectiveMissCount);
+ flashlightValue *= calculateMissPenalty(effectiveMissCount);
// Combo scaling.
if (Attributes.MaxCombo > 0)
@@ -265,6 +265,21 @@ namespace osu.Game.Rulesets.Osu.Difficulty
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
}
+ private double calculateMissPenalty(double missCount)
+ {
+ double leniency = 2.0;
+
+ if (missCount > totalHits - leniency)
+ return 0;
+
+ double missApprox = erfInvApprox((totalHits - leniency - missCount) / totalHits);
+ double fcApprox = erfInvApprox((totalHits - leniency) / totalHits);
+
+ return Math.Pow(missApprox / fcApprox, 1.5);
+ }
+
+ private double logit(double x) => Math.Log(x / (1 - x));
+ private double erfInvApprox(double x) => (Math.Sqrt(Math.PI) / 4) * logit((x + 1) / 2);
private int totalHits => countGreat + countOk + countMeh + countMiss;
private int totalSuccessfulHits => countGreat + countOk + countMeh;
}
From 60e2a8ed4b2f0f38dafe0cc9bc6ab8c55128b189 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Tue, 21 Dec 2021 17:54:26 +0000
Subject: [PATCH 05/31] Use MathNet for miss penalty calculation, and use old
penalty formula for Flashlight
---
.../Difficulty/OsuPerformanceCalculator.cs | 14 +++++++-------
osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj | 4 ++++
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index bba53c92fc..90caa64512 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -9,6 +9,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
+using MathNet.Numerics;
namespace osu.Game.Rulesets.Osu.Difficulty
{
@@ -228,8 +229,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(h => h is OsuModHidden))
flashlightValue *= 1.3;
+ // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
- flashlightValue *= calculateMissPenalty(effectiveMissCount);
+ flashlightValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
// Combo scaling.
if (Attributes.MaxCombo > 0)
@@ -267,19 +269,17 @@ namespace osu.Game.Rulesets.Osu.Difficulty
private double calculateMissPenalty(double missCount)
{
- double leniency = 2.0;
+ double leniency = 4.3;
if (missCount > totalHits - leniency)
return 0;
- double missApprox = erfInvApprox((totalHits - leniency - missCount) / totalHits);
- double fcApprox = erfInvApprox((totalHits - leniency) / totalHits);
+ double missApprox = SpecialFunctions.ErfInv((totalHits - leniency - missCount) / totalHits);
+ double fcApprox = SpecialFunctions.ErfInv((totalHits - leniency) / totalHits);
- return Math.Pow(missApprox / fcApprox, 1.5);
+ return Math.Pow(missApprox / fcApprox, 3.5);
}
- private double logit(double x) => Math.Log(x / (1 - x));
- private double erfInvApprox(double x) => (Math.Sqrt(Math.PI) / 4) * logit((x + 1) / 2);
private int totalHits => countGreat + countOk + countMeh + countMiss;
private int totalSuccessfulHits => countGreat + countOk + countMeh;
}
diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
index 98f1e69bd1..018bdb93df 100644
--- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
+++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
@@ -15,4 +15,8 @@
+
+
+
+
\ No newline at end of file
From 5640918c8c7c8af2e29feec4c7ad6d501619dafc Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Sun, 26 Dec 2021 23:51:49 +0000
Subject: [PATCH 06/31] New miss penalty formula, using relevant difficult
notes in each skill (targets diffspikes)
---
.../Difficulty/OsuDifficultyAttributes.cs | 6 ++++++
.../Difficulty/OsuDifficultyCalculator.cs | 9 +++++++++
.../Difficulty/OsuPerformanceCalculator.cs | 16 ++++------------
.../Difficulty/Skills/OsuStrainSkill.cs | 7 +++++++
4 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
index 4b2e54da17..6102f4a8b2 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
@@ -24,6 +24,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty
[JsonProperty("slider_factor")]
public double SliderFactor { get; set; }
+ [JsonProperty("aim_difficult_strain_count")]
+ public int AimDifficultStrainCount { get; set; }
+
+ [JsonProperty("speed_difficult_strain_count")]
+ public int SpeedDifficultStrainCount { get; set; }
+
[JsonProperty("approach_rate")]
public double ApproachRate { get; set; }
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
index ed42f333c0..ac228b0a32 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
@@ -40,6 +40,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
+ int aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).RelevantDifficultStrains();
+ int speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).RelevantDifficultStrains();
+
+ // Total number of strains in a map can vary by clockrate, and this needs to be corrected for.
+ aimDifficultyStrainCount = (int)(aimDifficultyStrainCount * clockRate);
+ speedDifficultyStrainCount = (int)(aimDifficultyStrainCount * clockRate);
+
if (mods.Any(h => h is OsuModRelax))
speedRating = 0.0;
@@ -78,6 +85,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
SpeedStrain = speedRating,
FlashlightRating = flashlightRating,
SliderFactor = sliderFactor,
+ AimDifficultStrainCount = aimDifficultyStrainCount,
+ SpeedDifficultStrainCount = speedDifficultyStrainCount,
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
OverallDifficulty = (80 - hitWindowGreat) / 6,
DrainRate = drainRate,
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 90caa64512..3efb8951b3 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= lengthBonus;
if (effectiveMissCount > 0)
- aimValue *= calculateMissPenalty(effectiveMissCount);
+ aimValue *= calculateMissPenalty(effectiveMissCount, Attributes.AimDifficultStrainCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
speedValue *= lengthBonus;
if (effectiveMissCount > 0)
- speedValue *= calculateMissPenalty(effectiveMissCount);
+ speedValue *= calculateMissPenalty(effectiveMissCount, Attributes.SpeedDifficultStrainCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -267,17 +267,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
}
- private double calculateMissPenalty(double missCount)
+ private double calculateMissPenalty(double missCount, double strainCount)
{
- double leniency = 4.3;
-
- if (missCount > totalHits - leniency)
- return 0;
-
- double missApprox = SpecialFunctions.ErfInv((totalHits - leniency - missCount) / totalHits);
- double fcApprox = SpecialFunctions.ErfInv((totalHits - leniency) / totalHits);
-
- return Math.Pow(missApprox / fcApprox, 3.5);
+ return 0.95 / ((missCount / (3 * Math.Sqrt(strainCount))) + 1);
}
private int totalHits => countGreat + countOk + countMeh + countMiss;
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index e47edc37cc..43e39482a7 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -57,5 +57,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
return difficulty * DifficultyMultiplier;
}
+
+ public int RelevantDifficultStrains()
+ {
+ List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList();
+
+ return strains.Count(s => s > strains[0] * 0.66);
+ }
}
}
From e9589e57a662bc47297fec2429d7bfce1256db68 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Mon, 27 Dec 2021 02:23:03 +0000
Subject: [PATCH 07/31] Fix logical error
---
osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
index ac228b0a32..87ab12248f 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
@@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
// Total number of strains in a map can vary by clockrate, and this needs to be corrected for.
aimDifficultyStrainCount = (int)(aimDifficultyStrainCount * clockRate);
- speedDifficultyStrainCount = (int)(aimDifficultyStrainCount * clockRate);
+ speedDifficultyStrainCount = (int)(speedDifficultyStrainCount * clockRate);
if (mods.Any(h => h is OsuModRelax))
speedRating = 0.0;
From 8ce6e3c573104d55956c9a3c4cd3c8beffd41b09 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Wed, 29 Dec 2021 18:49:13 +0000
Subject: [PATCH 08/31] Remove mathnet
---
osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 4 ----
osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj | 4 ----
2 files changed, 8 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index d7d294df47..f6e5481feb 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -99,8 +99,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (effectiveMissCount > 0)
aimValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), effectiveMissCount);
- aimValue *= getComboScalingFactor();
-
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
approachRateFactor = 0.3 * (Attributes.ApproachRate - 10.33);
@@ -146,8 +144,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (effectiveMissCount > 0)
speedValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
- speedValue *= getComboScalingFactor();
-
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
approachRateFactor = 0.3 * (Attributes.ApproachRate - 10.33);
diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
index 018bdb93df..98f1e69bd1 100644
--- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
+++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
@@ -15,8 +15,4 @@
-
-
-
-
\ No newline at end of file
From 4f257d6987b1144912f561d5a3360593598be834 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Wed, 29 Dec 2021 18:59:17 +0000
Subject: [PATCH 09/31] Clean up unsuccessful merge
---
.../Difficulty/OsuPerformanceCalculator.cs | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index f6e5481feb..793f9e790f 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -95,9 +95,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
aimValue *= lengthBonus;
- // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
- aimValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), effectiveMissCount);
+ aimValue *= calculateMissPenalty(effectiveMissCount, Attributes.AimDifficultStrainCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -140,9 +139,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
speedValue *= lengthBonus;
- // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
- speedValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
+ speedValue *= calculateMissPenalty(effectiveMissCount, Attributes.SpeedDifficultStrainCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@@ -259,6 +257,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty
}
private double getComboScalingFactor() => Attributes.MaxCombo <= 0 ? 1.0 : Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
+
+ private double calculateMissPenalty(double missCount, double strainCount)
+ {
+ return 0.95 / ((missCount / (3 * Math.Sqrt(strainCount))) + 1);
+ }
+
private int totalHits => countGreat + countOk + countMeh + countMiss;
private int totalSuccessfulHits => countGreat + countOk + countMeh;
}
From fd1028f3bb5c0f19ac2154974fafa528ea6e52e9 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Wed, 29 Dec 2021 23:49:07 +0000
Subject: [PATCH 10/31] Use clockrate in the difficult strain count method
---
.../Difficulty/OsuDifficultyCalculator.cs | 8 ++------
.../Difficulty/Skills/OsuStrainSkill.cs | 9 +++++++--
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
index 44ba6c6a58..27d97e9d75 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
@@ -40,12 +40,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
- int aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).RelevantDifficultStrains();
- int speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).RelevantDifficultStrains();
-
- // Total number of strains in a map can vary by clockrate, and this needs to be corrected for.
- aimDifficultyStrainCount = (int)(aimDifficultyStrainCount * clockRate);
- speedDifficultyStrainCount = (int)(speedDifficultyStrainCount * clockRate);
+ int aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountDifficultStrains(clockRate);
+ int speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountDifficultStrains(clockRate);
if (mods.Any(h => h is OsuModRelax))
speedRating = 0.0;
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 43e39482a7..fd751727a9 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -58,11 +58,16 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
return difficulty * DifficultyMultiplier;
}
- public int RelevantDifficultStrains()
+ ///
+ /// Returns the number of difficult strains.
+ /// A strain is considered difficult if it's higher than 66% of the highest strain.
+ ///
+ public int CountDifficultStrains(double clockRate)
{
List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList();
- return strains.Count(s => s > strains[0] * 0.66);
+ // Total number of strains in a map can vary by clockrate, and this needs to be corrected for.
+ return (int)(strains.Count(s => s > strains[0] * 0.66) * clockRate);
}
}
}
From d2b815b745b1cfaef241488c436b26fede000571 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Sun, 2 Jan 2022 19:20:20 +0000
Subject: [PATCH 11/31] Add miss penalty comment
---
.../Difficulty/OsuPerformanceCalculator.cs | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 793f9e790f..d8fe85d645 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -256,13 +256,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
}
+ // Miss penalty assumes that a player will miss on the relatively hard parts of a map, not the easy parts, hence the strain count.
+ private double calculateMissPenalty(double missCount, double strainCount) => 0.95 / ((missCount / (3 * Math.Sqrt(strainCount))) + 1);
+
private double getComboScalingFactor() => Attributes.MaxCombo <= 0 ? 1.0 : Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
-
- private double calculateMissPenalty(double missCount, double strainCount)
- {
- return 0.95 / ((missCount / (3 * Math.Sqrt(strainCount))) + 1);
- }
-
private int totalHits => countGreat + countOk + countMeh + countMiss;
private int totalSuccessfulHits => countGreat + countOk + countMeh;
}
From 75be4e83d6a44adc7016c150b5cbd1c74d1caf34 Mon Sep 17 00:00:00 2001
From: Luminiscental
Date: Mon, 3 Jan 2022 22:22:32 +0000
Subject: [PATCH 12/31] Remove abusable 0.66 threshold by averaging
---
.../Difficulty/Skills/OsuStrainSkill.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index fd751727a9..1513befad5 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -59,15 +59,15 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
}
///
- /// Returns the number of difficult strains.
- /// A strain is considered difficult if it's higher than 66% of the highest strain.
+ /// Returns the number of strains above a threshold averaged as the threshold varies.
+ /// The result is scaled by clock rate as it affects the total number of strains.
///
public int CountDifficultStrains(double clockRate)
{
- List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList();
-
- // Total number of strains in a map can vary by clockrate, and this needs to be corrected for.
- return (int)(strains.Count(s => s > strains[0] * 0.66) * clockRate);
+ List strains = GetCurrentStrainPeaks().ToList();
+ // This is the average value of strains.Count(s => s > p * strains.Max()) for p between 0 and 1.
+ double realtimeCount = strains.Sum() / strains.Max();
+ return (int)(clockRate * realtimeCount);
}
}
}
From 132079004ca5e6df33a2bc646a52f3036edff85e Mon Sep 17 00:00:00 2001
From: Luminiscental
Date: Tue, 4 Jan 2022 12:30:05 +0000
Subject: [PATCH 13/31] Remove unnecessary truncation
---
osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs | 4 ++--
osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 4 ++--
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
index 51842f65d5..7ab4232a19 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
@@ -25,10 +25,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
public double SliderFactor { get; set; }
[JsonProperty("aim_difficult_strain_count")]
- public int AimDifficultStrainCount { get; set; }
+ public double AimDifficultStrainCount { get; set; }
[JsonProperty("speed_difficult_strain_count")]
- public int SpeedDifficultStrainCount { get; set; }
+ public double SpeedDifficultStrainCount { get; set; }
[JsonProperty("approach_rate")]
public double ApproachRate { get; set; }
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
index 27d97e9d75..3c039c9b7e 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
@@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
- int aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountDifficultStrains(clockRate);
- int speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountDifficultStrains(clockRate);
+ double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountDifficultStrains(clockRate);
+ double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountDifficultStrains(clockRate);
if (mods.Any(h => h is OsuModRelax))
speedRating = 0.0;
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 1513befad5..46dc9c683b 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -62,12 +62,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
/// Returns the number of strains above a threshold averaged as the threshold varies.
/// The result is scaled by clock rate as it affects the total number of strains.
///
- public int CountDifficultStrains(double clockRate)
+ public double CountDifficultStrains(double clockRate)
{
List strains = GetCurrentStrainPeaks().ToList();
// This is the average value of strains.Count(s => s > p * strains.Max()) for p between 0 and 1.
double realtimeCount = strains.Sum() / strains.Max();
- return (int)(clockRate * realtimeCount);
+ return clockRate * realtimeCount;
}
}
}
From 443640a48c8bed53510947240e8337c9350d8d6d Mon Sep 17 00:00:00 2001
From: apollo <83023433+apollo-dw@users.noreply.github.com>
Date: Tue, 4 Jan 2022 16:39:30 +0000
Subject: [PATCH 14/31] Revert "Remove abusable 0.66 threshold by averaging"
---
.../Difficulty/OsuDifficultyAttributes.cs | 4 ++--
.../Difficulty/OsuDifficultyCalculator.cs | 4 ++--
.../Difficulty/Skills/OsuStrainSkill.cs | 14 +++++++-------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
index 7ab4232a19..51842f65d5 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
@@ -25,10 +25,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
public double SliderFactor { get; set; }
[JsonProperty("aim_difficult_strain_count")]
- public double AimDifficultStrainCount { get; set; }
+ public int AimDifficultStrainCount { get; set; }
[JsonProperty("speed_difficult_strain_count")]
- public double SpeedDifficultStrainCount { get; set; }
+ public int SpeedDifficultStrainCount { get; set; }
[JsonProperty("approach_rate")]
public double ApproachRate { get; set; }
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
index 3c039c9b7e..27d97e9d75 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
@@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
- double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountDifficultStrains(clockRate);
- double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountDifficultStrains(clockRate);
+ int aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountDifficultStrains(clockRate);
+ int speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountDifficultStrains(clockRate);
if (mods.Any(h => h is OsuModRelax))
speedRating = 0.0;
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 46dc9c683b..fd751727a9 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -59,15 +59,15 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
}
///
- /// Returns the number of strains above a threshold averaged as the threshold varies.
- /// The result is scaled by clock rate as it affects the total number of strains.
+ /// Returns the number of difficult strains.
+ /// A strain is considered difficult if it's higher than 66% of the highest strain.
///
- public double CountDifficultStrains(double clockRate)
+ public int CountDifficultStrains(double clockRate)
{
- List strains = GetCurrentStrainPeaks().ToList();
- // This is the average value of strains.Count(s => s > p * strains.Max()) for p between 0 and 1.
- double realtimeCount = strains.Sum() / strains.Max();
- return clockRate * realtimeCount;
+ List strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList();
+
+ // Total number of strains in a map can vary by clockrate, and this needs to be corrected for.
+ return (int)(strains.Count(s => s > strains[0] * 0.66) * clockRate);
}
}
}
From dcb969316dd5a7e2bd1b06ebd1450a0ab56ef831 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Tue, 4 Jan 2022 17:33:23 +0000
Subject: [PATCH 15/31] Weight difficult strain count against the top strain
---
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 46dc9c683b..3e0fccb6c4 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -59,14 +59,15 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
}
///
- /// Returns the number of strains above a threshold averaged as the threshold varies.
+ /// Returns the number of strains weighted against the top strain.
/// The result is scaled by clock rate as it affects the total number of strains.
///
public double CountDifficultStrains(double clockRate)
{
List strains = GetCurrentStrainPeaks().ToList();
- // This is the average value of strains.Count(s => s > p * strains.Max()) for p between 0 and 1.
- double realtimeCount = strains.Sum() / strains.Max();
+ double topStrain = strains.Max();
+
+ double realtimeCount = strains.Sum(s => Math.Pow(s / topStrain, 4));
return clockRate * realtimeCount;
}
}
From 400abc147b1f3742061125d91e80a62f5e1333f7 Mon Sep 17 00:00:00 2001
From: Dan Balasescu
Date: Thu, 6 Jan 2022 16:28:04 +0900
Subject: [PATCH 16/31] Add attribute ids to mapping functions
---
osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs | 4 ++++
osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs | 2 ++
2 files changed, 6 insertions(+)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
index 7ab4232a19..7041acc16c 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
@@ -60,6 +60,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
yield return (ATTRIB_ID_FLASHLIGHT, FlashlightDifficulty);
yield return (ATTRIB_ID_SLIDER_FACTOR, SliderFactor);
+ yield return (ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT, AimDifficultStrainCount);
+ yield return (ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT, SpeedDifficultStrainCount);
}
public override void FromDatabaseAttributes(IReadOnlyDictionary values)
@@ -74,6 +76,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
StarRating = values[ATTRIB_ID_DIFFICULTY];
FlashlightDifficulty = values.GetValueOrDefault(ATTRIB_ID_FLASHLIGHT);
SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR];
+ AimDifficultStrainCount = values[ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT];
+ SpeedDifficultStrainCount = values[ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT];
}
#region Newtonsoft.Json implicit ShouldSerialize() methods
diff --git a/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs b/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs
index 991b567f57..803a5bdac7 100644
--- a/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs
+++ b/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs
@@ -24,6 +24,8 @@ namespace osu.Game.Rulesets.Difficulty
protected const int ATTRIB_ID_SCORE_MULTIPLIER = 15;
protected const int ATTRIB_ID_FLASHLIGHT = 17;
protected const int ATTRIB_ID_SLIDER_FACTOR = 19;
+ protected const int ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT = 21;
+ protected const int ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT = 23;
///
/// The mods which were applied to the beatmap.
From 598946737f07c0f2a3ac7523666a868722906db1 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Wed, 12 Jan 2022 14:38:53 +0000
Subject: [PATCH 17/31] Reword comment and rename argument
---
.../Difficulty/OsuPerformanceCalculator.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index d8fe85d645..52658dfe38 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -256,9 +256,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
}
- // Miss penalty assumes that a player will miss on the relatively hard parts of a map, not the easy parts, hence the strain count.
- private double calculateMissPenalty(double missCount, double strainCount) => 0.95 / ((missCount / (3 * Math.Sqrt(strainCount))) + 1);
-
+ // Miss penalty assumes that a player will miss on the hardest parts of a map,
+ // so we use the amount of relatively difficult sections to adjust miss penalty
+ // to make it more punishing on maps with lower amount of hard sections.
+ private double calculateMissPenalty(double missCount, double difficultStrainCount) => 0.95 / ((missCount / (3 * Math.Sqrt(difficultStrainCount))) + 1);
private double getComboScalingFactor() => Attributes.MaxCombo <= 0 ? 1.0 : Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
private int totalHits => countGreat + countOk + countMeh + countMiss;
private int totalSuccessfulHits => countGreat + countOk + countMeh;
From da31ca17e7c12a2922ab83657df4d8d9b6826bbd Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Mon, 14 Feb 2022 01:53:03 +0000
Subject: [PATCH 18/31] Use note strains instead of sectional strains
---
osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 2 ++
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 7 ++++---
osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 6 +++++-
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
index a6301aed6d..3486db04af 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
@@ -159,6 +159,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
currentStrain *= strainDecay(current.DeltaTime);
currentStrain += strainValueOf(current) * skillMultiplier;
+ objectStrains.Add(currentStrain);
+
return currentStrain;
}
}
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 3e0fccb6c4..94e2c9d774 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -28,6 +28,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
///
protected virtual double DifficultyMultiplier => 1.06;
+ protected List objectStrains = new List();
+
protected OsuStrainSkill(Mod[] mods)
: base(mods)
{
@@ -64,10 +66,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
///
public double CountDifficultStrains(double clockRate)
{
- List strains = GetCurrentStrainPeaks().ToList();
- double topStrain = strains.Max();
+ double topStrain = objectStrains.Max();
- double realtimeCount = strains.Sum(s => Math.Pow(s / topStrain, 4));
+ double realtimeCount = objectStrains.Sum(s => Math.Pow(s / topStrain, 4));
return clockRate * realtimeCount;
}
}
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
index 06d1ef7346..108edc6f2d 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
@@ -173,7 +173,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
currentRhythm = calculateRhythmBonus(current);
- return currentStrain * currentRhythm;
+ double totalStrain = currentStrain * currentRhythm;
+
+ objectStrains.Add(totalStrain);
+
+ return totalStrain;
}
}
}
From 94a46ab640b36c3ca58f03eaf2644ab51c3abd51 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Mon, 14 Feb 2022 02:02:46 +0000
Subject: [PATCH 19/31] Rescale miss penalty for note strains
---
osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index cf2116cc5d..cf1af18d39 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -259,7 +259,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
// Miss penalty assumes that a player will miss on the hardest parts of a map,
// so we use the amount of relatively difficult sections to adjust miss penalty
// to make it more punishing on maps with lower amount of hard sections.
- private double calculateMissPenalty(double missCount, double difficultStrainCount) => 0.95 / ((missCount / (3 * Math.Sqrt(difficultStrainCount))) + 1);
+ private double calculateMissPenalty(double missCount, double difficultStrainCount) => 0.94 / ((missCount / (2 * Math.Sqrt(difficultStrainCount))) + 1);
private double getComboScalingFactor() => Attributes.MaxCombo <= 0 ? 1.0 : Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
private int totalHits => countGreat + countOk + countMeh + countMiss;
private int totalSuccessfulHits => countGreat + countOk + countMeh;
From c18df86720244a7d5bba22bc502afd4f959c9082 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Sat, 19 Feb 2022 15:33:28 +0000
Subject: [PATCH 20/31] Remove clockrate factor
---
osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 4 ++--
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 5 ++---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
index 3c039c9b7e..788b515d7f 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
@@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
- double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountDifficultStrains(clockRate);
- double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountDifficultStrains(clockRate);
+ double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountDifficultStrains();
+ double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountDifficultStrains();
if (mods.Any(h => h is OsuModRelax))
speedRating = 0.0;
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 94e2c9d774..1124c4466f 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -64,12 +64,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
/// Returns the number of strains weighted against the top strain.
/// The result is scaled by clock rate as it affects the total number of strains.
///
- public double CountDifficultStrains(double clockRate)
+ public double CountDifficultStrains()
{
double topStrain = objectStrains.Max();
- double realtimeCount = objectStrains.Sum(s => Math.Pow(s / topStrain, 4));
- return clockRate * realtimeCount;
+ return objectStrains.Sum(s => Math.Pow(s / topStrain, 4));
}
}
}
From 2f335a76dca77b0304f5ff21ed7ca2c8e1130757 Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Thu, 17 Mar 2022 22:08:56 +0000
Subject: [PATCH 21/31] Switch to using osuAttributes
---
osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 48b4f53a3e..964bd73e81 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= lengthBonus;
if (effectiveMissCount > 0)
- aimValue *= calculateMissPenalty(effectiveMissCount, Attributes.AimDifficultStrainCount);
+ aimValue *= calculateMissPenalty(effectiveMissCount, attributes.AimDifficultStrainCount);
double approachRateFactor = 0.0;
if (attributes.ApproachRate > 10.33)
@@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
speedValue *= lengthBonus;
if (effectiveMissCount > 0)
- speedValue *= calculateMissPenalty(effectiveMissCount, Attributes.SpeedDifficultStrainCount);
+ speedValue *= calculateMissPenalty(effectiveMissCount, attributes.SpeedDifficultStrainCount);
double approachRateFactor = 0.0;
if (attributes.ApproachRate > 10.33)
From 7d34542c12a8e1db707d101fc7988e32e9da74d8 Mon Sep 17 00:00:00 2001
From: TextAdventurer12
Date: Thu, 22 Feb 2024 15:14:56 +1300
Subject: [PATCH 22/31] use difficulty instead of topstrain
---
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 918e702b45..13d89cf2b8 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -37,6 +37,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
protected virtual double DifficultyMultiplier => DEFAULT_DIFFICULTY_MULTIPLIER;
protected List objectStrains = new List();
+ protected double difficulty;
protected OsuStrainSkill(Mod[] mods)
: base(mods)
@@ -45,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
public override double DifficultyValue()
{
- double difficulty = 0;
+ difficulty = 0;
double weight = 1;
// Sections with 0 strain are excluded to avoid worst-case time complexity of the following sort (e.g. /b/2351871).
@@ -78,9 +79,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
///
public double CountDifficultStrains()
{
- double topStrain = objectStrains.Max();
+ double consistentTopStrain = difficulty / 10; // What would the top strain be if all strain values were identical
- return objectStrains.Sum(s => Math.Pow(s / topStrain, 4));
+ return objectStrains.Sum(s => Math.Pow(1, s / consistentTopStrain, 5));
}
}
}
From 0db910deb90b792f41203ee9410ef6dc05231308 Mon Sep 17 00:00:00 2001
From: TextAdventurer12
Date: Thu, 22 Feb 2024 15:20:32 +1300
Subject: [PATCH 23/31] cap each note at adding 1 difficult strain count
---
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 13d89cf2b8..84bf8e3bf6 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
double consistentTopStrain = difficulty / 10; // What would the top strain be if all strain values were identical
- return objectStrains.Sum(s => Math.Pow(1, s / consistentTopStrain, 5));
+ return objectStrains.Sum(s => Math.Pow(Math.Min(1, s / consistentTopStrain), 5));
}
}
}
From 9f5f6b5d37405787a4308db875331060f54572b4 Mon Sep 17 00:00:00 2001
From: TextAdventurer12
Date: Sat, 6 Apr 2024 21:39:27 +1300
Subject: [PATCH 24/31] stop capping difficult strains per note
---
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 84bf8e3bf6..b585a30855 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -81,7 +81,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
double consistentTopStrain = difficulty / 10; // What would the top strain be if all strain values were identical
- return objectStrains.Sum(s => Math.Pow(Math.Min(1, s / consistentTopStrain), 5));
+ // Apply a power to nerf diffspikes, but only apply that power if s / adjustedDifficulty is less than 1, to prevent buffing certain spiky maps
+ return objectStrains.Sum(s => s >= adjustedDifficulty ? s / adjustedDifficulty : Math.Pow(s / adjustedDifficulty, 8));
}
}
-}
+}
\ No newline at end of file
From b32d73ec9b7be94b3f55a7007e236cffd9228ca1 Mon Sep 17 00:00:00 2001
From: TextAdventurer12
Date: Sat, 13 Apr 2024 02:43:33 +1200
Subject: [PATCH 25/31] adjust weighting function
---
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index b585a30855..c20ea732ec 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -80,9 +80,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
public double CountDifficultStrains()
{
double consistentTopStrain = difficulty / 10; // What would the top strain be if all strain values were identical
-
- // Apply a power to nerf diffspikes, but only apply that power if s / adjustedDifficulty is less than 1, to prevent buffing certain spiky maps
- return objectStrains.Sum(s => s >= adjustedDifficulty ? s / adjustedDifficulty : Math.Pow(s / adjustedDifficulty, 8));
+ // Use a weighted sum of all strains. Constants are arbitrary and give nice values
+ return objectStrains.Sum(s => 1.3 / (1 + Math.Exp(-14.15 * (Math.Pow(s / consistentTopStrain, 2) - 0.945))));
}
}
}
\ No newline at end of file
From e2a5d1904b000965f009ee746a3175396011e3fc Mon Sep 17 00:00:00 2001
From: TextAdventurer12
Date: Wed, 17 Apr 2024 01:21:06 +1200
Subject: [PATCH 26/31] adjust count difficult strains formula
---
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 c20ea732ec..beaf1d1288 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
double consistentTopStrain = difficulty / 10; // What would the top strain be if all strain values were identical
// Use a weighted sum of all strains. Constants are arbitrary and give nice values
- return objectStrains.Sum(s => 1.3 / (1 + Math.Exp(-14.15 * (Math.Pow(s / consistentTopStrain, 2) - 0.945))));
+ return objectStrains.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88))));
}
}
}
\ No newline at end of file
From c1efcc054cf1594d3d883fcf66ab67b811d4de81 Mon Sep 17 00:00:00 2001
From: danielthirtle
Date: Tue, 21 May 2024 21:03:53 +1200
Subject: [PATCH 27/31] Change miss penalty (nerf longer maps)
---
osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 47f6770ce5..36768967ff 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -261,7 +261,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
// Miss penalty assumes that a player will miss on the hardest parts of a map,
// so we use the amount of relatively difficult sections to adjust miss penalty
// to make it more punishing on maps with lower amount of hard sections.
- private double calculateMissPenalty(double missCount, double difficultStrainCount) => 0.94 / ((missCount / (2 * Math.Sqrt(difficultStrainCount))) + 1);
+ private double calculateMissPenalty(double missCount, double difficultStrainCount) => 0.96 / ((missCount / (4 * Math.Pow(Math.Log(difficultStrainCount), 0.94))) + 1);
private double getComboScalingFactor(OsuDifficultyAttributes attributes) => attributes.MaxCombo <= 0 ? 1.0 : Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(attributes.MaxCombo, 0.8), 1.0);
private int totalHits => countGreat + countOk + countMeh + countMiss;
}
From 20c54ab697eec2bb183a2f7f9ea5022a7b9be66a Mon Sep 17 00:00:00 2001
From: js1086
Date: Thu, 23 May 2024 19:08:32 +0100
Subject: [PATCH 28/31] Apply code quality changes
---
osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 3 +--
.../Difficulty/Skills/OsuStrainSkill.cs | 16 ++++++++--------
osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 10 ++++------
3 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
index ad0e3fd107..6c17c84c19 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
@@ -34,8 +34,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain += AimEvaluator.EvaluateDifficultyOf(current, withSliders) * skillMultiplier;
-
- objectStrains.Add(currentStrain);
+ ObjectStrains.Add(currentStrain);
return currentStrain;
}
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index 39175d55e0..c2e9357e3a 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -34,8 +34,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
///
protected virtual double DifficultyMultiplier => DEFAULT_DIFFICULTY_MULTIPLIER;
- protected List objectStrains = new List();
- protected double difficulty;
+ protected List ObjectStrains = new List();
+ protected double Difficulty;
protected OsuStrainSkill(Mod[] mods)
: base(mods)
@@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
public override double DifficultyValue()
{
- difficulty = 0;
+ Difficulty = 0;
double weight = 1;
// Sections with 0 strain are excluded to avoid worst-case time complexity of the following sort (e.g. /b/2351871).
@@ -64,11 +64,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
// We're sorting from highest to lowest strain.
foreach (double strain in strains.OrderDescending())
{
- difficulty += strain * weight;
+ Difficulty += strain * weight;
weight *= DecayWeight;
}
- return difficulty * DifficultyMultiplier;
+ return Difficulty * DifficultyMultiplier;
}
///
@@ -77,9 +77,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
///
public double CountDifficultStrains()
{
- double consistentTopStrain = difficulty / 10; // What would the top strain be if all strain values were identical
+ double consistentTopStrain = Difficulty / 10; // What would the top strain be if all strain values were identical
// Use a weighted sum of all strains. Constants are arbitrary and give nice values
- return objectStrains.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88))));
+ return ObjectStrains.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88))));
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
index b1cd0b21d1..bf8e09bd53 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
@@ -41,23 +41,21 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
currentRhythm = RhythmEvaluator.EvaluateDifficultyOf(current);
double totalStrain = currentStrain * currentRhythm;
-
- objectStrains.Add(totalStrain);
+ ObjectStrains.Add(totalStrain);
return totalStrain;
}
public double RelevantNoteCount()
{
- if (objectStrains.Count == 0)
+ if (ObjectStrains.Count == 0)
return 0;
- double maxStrain = objectStrains.Max();
-
+ double maxStrain = ObjectStrains.Max();
if (maxStrain == 0)
return 0;
- return objectStrains.Sum(strain => 1.0 / (1.0 + Math.Exp(-(strain / maxStrain * 12.0 - 6.0))));
+ return ObjectStrains.Sum(strain => 1.0 / (1.0 + Math.Exp(-(strain / maxStrain * 12.0 - 6.0))));
}
}
}
From 61afda1089eeee4d42f59ab6185023d699acb788 Mon Sep 17 00:00:00 2001
From: js1086
Date: Sun, 26 May 2024 11:24:06 +0100
Subject: [PATCH 29/31] Fix NaN case when difficulty is 0
---
osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
index c2e9357e3a..af97d90e53 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -77,6 +77,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
///
public double CountDifficultStrains()
{
+ if (double.IsNaN(Difficulty))
+ return 0.0;
+
double consistentTopStrain = Difficulty / 10; // What would the top strain be if all strain values were identical
// Use a weighted sum of all strains. Constants are arbitrary and give nice values
return ObjectStrains.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88))));
From c25e1bdeb586db8a2def47232632be61b4d4242e Mon Sep 17 00:00:00 2001
From: js1086
Date: Sun, 26 May 2024 14:21:47 +0100
Subject: [PATCH 30/31] Use correct operation for 0 difficulty case
---
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 af97d90e53..ec132237db 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
@@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
///
public double CountDifficultStrains()
{
- if (double.IsNaN(Difficulty))
+ if (Difficulty == 0)
return 0.0;
double consistentTopStrain = Difficulty / 10; // What would the top strain be if all strain values were identical
From a7e1d35f648c449e749fa1346d3de704b87fe4ce Mon Sep 17 00:00:00 2001
From: apollo-dw <83023433+apollo-dw@users.noreply.github.com>
Date: Wed, 11 Sep 2024 12:29:17 +0100
Subject: [PATCH 31/31] Update
osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs
Co-authored-by: James Wilson
---
osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs b/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs
index 8dfaaca7b2..a0f2a04f40 100644
--- a/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs
+++ b/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs
@@ -25,9 +25,9 @@ namespace osu.Game.Rulesets.Difficulty
protected const int ATTRIB_ID_SCORE_MULTIPLIER = 15;
protected const int ATTRIB_ID_FLASHLIGHT = 17;
protected const int ATTRIB_ID_SLIDER_FACTOR = 19;
- protected const int ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT = 21;
- protected const int ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT = 23;
protected const int ATTRIB_ID_SPEED_NOTE_COUNT = 21;
+ protected const int ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT = 23;
+ protected const int ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT = 25;
///
/// The mods which were applied to the beatmap.