Skip to content

Commit

Permalink
New Difficulty Factor + Length Bonus Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDark98 committed Jan 14, 2025
2 parents 694b40a + 4c8a193 commit 7988bf1
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 64 deletions.
12 changes: 6 additions & 6 deletions osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ public class OsuDifficultyCalculatorTest : DifficultyCalculatorTest
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu.Tests";

[TestCase(6.6860329680488437d, 239, "diffcalc-test")]
[TestCase(1.4485740324170036d, 54, "zero-length-sliders")]
[TestCase(6.7331304290522747d, 239, "diffcalc-test")]
[TestCase(1.4602604078137214d, 54, "zero-length-sliders")]
[TestCase(0.43052813047866129d, 4, "very-fast-slider")]
[TestCase(0.14143808967817237d, 2, "nan-slider")]
public void Test(double expectedStarRating, int expectedMaxCombo, string name)
=> base.Test(expectedStarRating, expectedMaxCombo, name);

[TestCase(9.6300773538770041d, 239, "diffcalc-test")]
[TestCase(1.7550155729445993d, 54, "zero-length-sliders")]
[TestCase(9.6779397290273756d, 239, "diffcalc-test")]
[TestCase(1.7691451263718989d, 54, "zero-length-sliders")]
[TestCase(0.55785578988249407d, 4, "very-fast-slider")]
public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name)
=> Test(expectedStarRating, expectedMaxCombo, name, new OsuModDoubleTime());

[TestCase(6.6860329680488437d, 239, "diffcalc-test")]
[TestCase(1.4485740324170036d, 54, "zero-length-sliders")]
[TestCase(6.7331304290522747d, 239, "diffcalc-test")]
[TestCase(1.4602604078137214d, 54, "zero-length-sliders")]
[TestCase(0.43052813047866129d, 4, "very-fast-slider")]
public void TestClassicMod(double expectedStarRating, int expectedMaxCombo, string name)
=> Test(expectedStarRating, expectedMaxCombo, name, new OsuModClassic());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current, bool with

// Penalize angle repetition.
wideAngleBonus *= 1 - Math.Min(wideAngleBonus, Math.Pow(calcWideAngleBonus(lastAngle), 3));
acuteAngleBonus *= 0.1 + 0.9 * (1 - Math.Min(acuteAngleBonus, Math.Pow(calcAcuteAngleBonus(lastAngle), 3)));
acuteAngleBonus *= 0.08 + 0.92 * (1 - Math.Min(acuteAngleBonus, Math.Pow(calcAcuteAngleBonus(lastAngle), 3)));

// Apply full wide angle bonus for distance more than one diameter
wideAngleBonus *= angleBonus * DifficultyCalculationUtils.Smootherstep(osuCurrObj.LazyJumpDistance, 0, diameter);
Expand Down
24 changes: 9 additions & 15 deletions osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Difficulty.Utils;
using osu.Game.Rulesets.Osu.Difficulty.Skills;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
Expand Down Expand Up @@ -41,7 +42,7 @@ public class OsuPerformanceCalculator : PerformanceCalculator
/// <summary>
/// The bonus multiplier is a basic multiplier that indicate how strong the impact of Difficulty Factor is.
/// </summary>
private const double bonus_multiplier = 0.1;
private const double bonus_multiplier = 0.15;

/// <summary>
/// Amount of missed slider tails that don't break combo. Will only be correct on non-classic scores
Expand Down Expand Up @@ -127,14 +128,7 @@ protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo s

speedDeviation = calculateSpeedDeviation(osuAttributes);

if (totalHits > 2000)
{
lengthBonusBase = 1.3 * Math.Max((Math.Log(10.0 + totalHits / 1000.0) - 1.35) * 0.45 + 0.5, 1.0);
}
else
{
lengthBonusBase = Math.Max((Math.Log(10.0 + totalHits / 1000.0) - 1.35) * 0.45 + 0.5, 1.0);
}
lengthBonusBase = Math.Log(10.0 + totalHits / 1000.0) - 1.2;

double aimValue = computeAimValue(score, osuAttributes);
double speedValue = computeSpeedValue(score, osuAttributes);
Expand Down Expand Up @@ -191,9 +185,9 @@ private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attribut

double aimValue = OsuStrainSkill.DifficultyToPerformance(aimDifficulty);

double approachRateBonus = score.Mods.Any(h => h is OsuModRelax) ? 0.0 : attributes.ApproachRate > 10.33 ? 0.3 * (attributes.ApproachRate - 10.33) : attributes.ApproachRate < 8.0 ? 0.05 * (8.0 - attributes.ApproachRate) : 0.0; //AR bonus for higher and lower AR
double approachRateBonus = score.Mods.Any(h => h is OsuModRelax) ? 0.0 : attributes.ApproachRate > 10.33 ? 0.2 * (attributes.ApproachRate - 10.33) : attributes.ApproachRate < 8.0 ? 0.02 * (8.0 - attributes.ApproachRate) : 0.0; //AR bonus for higher and lower AR

aimValue *= LengthBonusMultiplier(lengthBonusBase + approachRateBonus, attributes.AimDifficultyFactor, bonus_multiplier);
aimValue *= LengthBonusMultiplier(lengthBonusBase, attributes.SpeedDifficultyFactor, bonus_multiplier) * (1.0 + approachRateBonus);

if (effectiveMissCount > 0)
aimValue *= calculateMissPenalty(effectiveMissCount, attributes.AimDifficultStrainCount);
Expand All @@ -220,9 +214,9 @@ private double computeSpeedValue(ScoreInfo score, OsuDifficultyAttributes attrib

double speedValue = OsuStrainSkill.DifficultyToPerformance(attributes.SpeedDifficulty);

double approachRateBonus = attributes.ApproachRate > 10.33 ? 0.3 * (attributes.ApproachRate - 10.33) : 0.0;
double approachRateBonus = attributes.ApproachRate > 10.33 ? 0.2 * (attributes.ApproachRate - 10.33) : 0.0;

speedValue *= LengthBonusMultiplier(lengthBonusBase + approachRateBonus, attributes.SpeedDifficultyFactor, bonus_multiplier);
speedValue *= LengthBonusMultiplier(lengthBonusBase, attributes.SpeedDifficultyFactor, bonus_multiplier) * (1.0 + approachRateBonus);

if (effectiveMissCount > 0)
speedValue *= calculateMissPenalty(effectiveMissCount, attributes.SpeedDifficultStrainCount);
Expand Down Expand Up @@ -413,8 +407,8 @@ private double calculateSpeedHighDeviationNerf(OsuDifficultyAttributes attribute
const double scale = 50;
double adjustedSpeedValue = scale * (Math.Log((speedValue - excessSpeedDifficultyCutoff) / scale + 1) + excessSpeedDifficultyCutoff / scale);

// 200 UR and less are considered tapped correctly to ensure that normal scores will be punished as little as possible
double lerp = 1 - Math.Clamp((speedDeviation.Value - 20) / (24 - 20), 0, 1);
// 220 UR and less are considered tapped correctly to ensure that normal scores will be punished as little as possible
double lerp = 1 - DifficultyCalculationUtils.ReverseLerp(speedDeviation.Value, 22.0, 27.0);
adjustedSpeedValue = double.Lerp(adjustedSpeedValue, speedValue, lerp);

return adjustedSpeedValue / speedValue;
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public Aim(Mod[] mods, bool withSliders)

private double currentStrain;

private double skillMultiplier => 25.18;
private double skillMultiplier => 25.6;
private double strainDecayBase => 0.15;

private readonly List<double> sliderStrains = new List<double>();
Expand Down
48 changes: 8 additions & 40 deletions osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,53 +123,21 @@ private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes a
/// </summary>
private double? computeDeviationUpperBound(TaikoDifficultyAttributes attributes)
{
if (totalSuccessfulHits == 0 || attributes.GreatHitWindow <= 0)
if (countGreat == 0 || attributes.GreatHitWindow <= 0)
return null;

double h300 = attributes.GreatHitWindow;
double h100 = attributes.OkHitWindow;

const double z = 2.32634787404; // 99% critical value for the normal distribution (one-tailed).

double? deviationGreatWindow = calcDeviationGreatWindow();
double? deviationGoodWindow = calcDeviationGoodWindow();

return deviationGreatWindow is null ? deviationGoodWindow : Math.Min(deviationGreatWindow.Value, deviationGoodWindow!.Value);

// The upper bound on deviation, calculated with the ratio of 300s to objects, and the great hit window.
double? calcDeviationGreatWindow()
{
if (countGreat == 0) return null;

double n = totalHits;

// Proportion of greats hit.
double p = countGreat / n;

// We can be 99% confident that p is at least this value.
double pLowerBound = (n * p + z * z / 2) / (n + z * z) - z / (n + z * z) * Math.Sqrt(n * p * (1 - p) + z * z / 4);

// We can be 99% confident that the deviation is not higher than:
return h300 / (Math.Sqrt(2) * SpecialFunctions.ErfInv(pLowerBound));
}

// The upper bound on deviation, calculated with the ratio of 300s + 100s to objects, and the good hit window.
// This will return a lower value than the first method when the number of 100s is high, but the miss count is low.
double? calcDeviationGoodWindow()
{
if (totalSuccessfulHits == 0) return null;

double n = totalHits;
double n = totalHits;

// Proportion of greats + goods hit.
double p = Math.Max(0, totalSuccessfulHits - 0.0005 * countOk) / n;
// Proportion of greats hit.
double p = countGreat / n;

// We can be 99% confident that p is at least this value.
double pLowerBound = (n * p + z * z / 2) / (n + z * z) - z / (n + z * z) * Math.Sqrt(n * p * (1 - p) + z * z / 4);
// We can be 99% confident that p is at least this value.
double pLowerBound = (n * p + z * z / 2) / (n + z * z) - z / (n + z * z) * Math.Sqrt(n * p * (1 - p) + z * z / 4);

// We can be 99% confident that the deviation is not higher than:
return h100 / (Math.Sqrt(2) * SpecialFunctions.ErfInv(pLowerBound));
}
// We can be 99% confident that the deviation is not higher than:
return attributes.GreatHitWindow / (Math.Sqrt(2) * SpecialFunctions.ErfInv(pLowerBound));
}

private int totalHits => countGreat + countOk + countMeh + countMiss;
Expand Down
3 changes: 2 additions & 1 deletion osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Threading;
using System.Threading.Tasks;
using osu.Game.Beatmaps;
Expand Down Expand Up @@ -36,6 +37,6 @@ public PerformanceAttributes Calculate(ScoreInfo score, IWorkingBeatmap beatmap)
/// <summary>
/// Calculating the length bonus as a multiplier considering also the Difficulty Factor.
/// </summary>
protected virtual double LengthBonusMultiplier(double offsetLengthBonus, double difficultyFactor, double multiplierDifficultyFactor) => offsetLengthBonus + difficultyFactor * multiplierDifficultyFactor;
protected virtual double LengthBonusMultiplier(double lengthBonusBase, double difficultyFactor, double multiplierDifficultyFactor) => Math.Max(lengthBonusBase * (0.95 + difficultyFactor * multiplierDifficultyFactor), 1.0);
}
}

0 comments on commit 7988bf1

Please sign in to comment.