Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pp Refactoring: Reworking StrainSkill #29290

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
7 changes: 4 additions & 3 deletions osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@

namespace osu.Game.Rulesets.Catch.Difficulty.Skills
{
public class Movement : StrainDecaySkill
public class Movement : StrainSkill
{
public override double SkillMultiplier => 900;

private const float absolute_player_positioning_error = 16f;
private const float normalized_hitobject_radius = 41.0f;
private const double direction_change_bonus = 21.0;

protected override double SkillMultiplier => 900;
protected override double StrainDecayBase => 0.2;

protected override double DecayWeight => 0.94;
protected override double SumDecay => 0.94;

protected override int SectionLength => 750;

Expand Down
3 changes: 1 addition & 2 deletions osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@

namespace osu.Game.Rulesets.Mania.Difficulty.Skills
{
public class Strain : StrainDecaySkill
public class Strain : StrainSkill
{
private const double individual_decay_base = 0.125;
private const double overall_decay_base = 0.30;
private const double release_threshold = 30;

protected override double SkillMultiplier => 1;
protected override double StrainDecayBase => 1;

private readonly double[] startTimes;
Expand Down
20 changes: 3 additions & 17 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// 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 osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Difficulty.Evaluators;
Expand All @@ -13,6 +12,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
/// </summary>
public class Aim : OsuStrainSkill
{
public override double SkillMultiplier => 23.55;

public Aim(Mod[] mods, bool withSliders)
: base(mods)
{
Expand All @@ -21,21 +22,6 @@ public Aim(Mod[] mods, bool withSliders)

private readonly bool withSliders;

private double currentStrain;

private double skillMultiplier => 23.55;
private double strainDecayBase => 0.15;

private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);

protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * strainDecay(time - current.Previous(0).StartTime);

protected override double StrainValueAt(DifficultyHitObject current)
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain += AimEvaluator.EvaluateDifficultyOf(current, withSliders) * skillMultiplier;

return currentStrain;
}
protected override double StrainValueOf(DifficultyHitObject current) => AimEvaluator.EvaluateDifficultyOf(current, withSliders);
}
}
19 changes: 2 additions & 17 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// 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.Linq;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
Expand All @@ -16,6 +15,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
/// </summary>
public class Flashlight : StrainSkill
{
public override double SkillMultiplier => 0.052;
private readonly bool hasHiddenMod;

public Flashlight(Mod[] mods)
Expand All @@ -24,22 +24,7 @@ public Flashlight(Mod[] mods)
hasHiddenMod = mods.Any(m => m is OsuModHidden);
}

private double skillMultiplier => 0.052;
private double strainDecayBase => 0.15;

private double currentStrain;

private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);

protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * strainDecay(time - current.Previous(0).StartTime);

protected override double StrainValueAt(DifficultyHitObject current)
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain += FlashlightEvaluator.EvaluateDifficultyOf(current, hasHiddenMod) * skillMultiplier;

return currentStrain;
}
protected override double StrainValueOf(DifficultyHitObject current) => FlashlightEvaluator.EvaluateDifficultyOf(current, hasHiddenMod);

public override double DifficultyValue() => GetCurrentStrainPeaks().Sum() * OsuStrainSkill.DEFAULT_DIFFICULTY_MULTIPLIER;
}
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public override double DifficultyValue()
foreach (double strain in strains.OrderDescending())
{
difficulty += strain * weight;
weight *= DecayWeight;
weight *= SumDecay;
}

return difficulty * DifficultyMultiplier;
Expand Down
16 changes: 8 additions & 8 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
/// </summary>
public class Speed : OsuStrainSkill
{
private double skillMultiplier => 1375;
private double strainDecayBase => 0.3;
public override double SkillMultiplier => 1375;

private double currentStrain;
private double currentRhythm;

protected override int ReducedSectionCount => 5;

protected override double StrainDecayBase => 0.3;
protected override double DifficultyMultiplier => 1.04;

private readonly List<double> objectStrains = new List<double>();
Expand All @@ -32,18 +32,18 @@ public Speed(Mod[] mods)
{
}

private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (CurrentStrain * currentRhythm) * StrainDecay(time - current.Previous(0).StartTime);

protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (currentStrain * currentRhythm) * strainDecay(time - current.Previous(0).StartTime);
protected override double StrainValueOf(DifficultyHitObject current) => SpeedEvaluator.EvaluateDifficultyOf(current);

protected override double StrainValueAt(DifficultyHitObject current)
{
currentStrain *= strainDecay(((OsuDifficultyHitObject)current).StrainTime);
currentStrain += SpeedEvaluator.EvaluateDifficultyOf(current) * skillMultiplier;
CurrentStrain *= StrainDecay(((OsuDifficultyHitObject)current).StrainTime);
CurrentStrain += StrainValueOf(current) * SkillMultiplier;

currentRhythm = RhythmEvaluator.EvaluateDifficultyOf(current);

double totalStrain = currentStrain * currentRhythm;
double totalStrain = CurrentStrain * currentRhythm;
Comment on lines +32 to +41
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth noting this entire thing becomes a little more confusing to read with these changes, but it's not really at fault of this PR - rhythm really should be entirely separate or atleast additive to speed so that we don't need to do this stupid solution. not a blocker, just speaking my mind


objectStrains.Add(totalStrain);

Expand Down
9 changes: 3 additions & 6 deletions osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
/// <summary>
/// Calculates the colour coefficient of taiko difficulty.
/// </summary>
public class Colour : StrainDecaySkill
public class Colour : StrainSkill
{
protected override double SkillMultiplier => 0.12;
public override double SkillMultiplier => 0.12;

// This is set to decay slower than other skills, due to the fact that only the first note of each encoding class
// having any difficulty values, and we want to allow colour difficulty to be able to build up even on
Expand All @@ -25,9 +25,6 @@ public Colour(Mod[] mods)
{
}

protected override double StrainValueOf(DifficultyHitObject current)
{
return ColourEvaluator.EvaluateDifficultyOf(current);
}
protected override double StrainValueOf(DifficultyHitObject current) => ColourEvaluator.EvaluateDifficultyOf(current);
}
}
4 changes: 2 additions & 2 deletions osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
/// <summary>
/// Calculates the rhythm coefficient of taiko difficulty.
/// </summary>
public class Rhythm : StrainDecaySkill
public class Rhythm : StrainSkill
{
protected override double SkillMultiplier => 10;
public override double SkillMultiplier => 10;
protected override double StrainDecayBase => 0;

/// <summary>
Expand Down
9 changes: 3 additions & 6 deletions osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
/// <summary>
/// Calculates the stamina coefficient of taiko difficulty.
/// </summary>
public class Stamina : StrainDecaySkill
public class Stamina : StrainSkill
{
protected override double SkillMultiplier => 1.1;
public override double SkillMultiplier => 1.1;
protected override double StrainDecayBase => 0.4;

/// <summary>
Expand All @@ -25,9 +25,6 @@ public Stamina(Mod[] mods)
{
}

protected override double StrainValueOf(DifficultyHitObject current)
{
return StaminaEvaluator.EvaluateDifficultyOf(current);
}
protected override double StrainValueOf(DifficultyHitObject current) => StaminaEvaluator.EvaluateDifficultyOf(current);
}
}
54 changes: 0 additions & 54 deletions osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs

This file was deleted.

39 changes: 34 additions & 5 deletions osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,31 @@ namespace osu.Game.Rulesets.Difficulty.Skills
public abstract class StrainSkill : Skill
{
/// <summary>
/// The weight by which each strain value decays.
/// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other.
/// </summary>
protected virtual double DecayWeight => 0.9;
public virtual double SkillMultiplier => 1;
Givikap120 marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// The weight by which each strain value decays when summing strains.
/// </summary>
protected virtual double SumDecay => 0.9;
Givikap120 marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// The length of each strain section.
/// </summary>
protected virtual int SectionLength => 400;

/// <summary>
/// Determines how quickly strain decays for the given skill.
/// For example a value of 0.15 indicates that strain decays to 15% of its original value in one second.
/// </summary>
protected virtual double StrainDecayBase => 0.15;

/// <summary>
/// The current strain level.
/// </summary>
protected double CurrentStrain;

private double currentSectionPeak; // We also keep track of the peak strain level in the current section.

private double currentSectionEnd;
Expand All @@ -36,10 +52,23 @@ protected StrainSkill(Mod[] mods)
{
}

protected double StrainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000);

/// <summary>
/// Calculates the strain value of a <see cref="DifficultyHitObject"/>. This value is affected by previously processed objects.
/// </summary>
protected abstract double StrainValueOf(DifficultyHitObject current);

/// <summary>
/// Returns the strain value at <see cref="DifficultyHitObject"/>. This value is calculated with or without respect to previous objects.
/// </summary>
protected abstract double StrainValueAt(DifficultyHitObject current);
protected virtual double StrainValueAt(DifficultyHitObject current)
{
CurrentStrain *= StrainDecay(current.DeltaTime);
CurrentStrain += StrainValueOf(current) * SkillMultiplier;

return CurrentStrain;
}

/// <summary>
/// Process a <see cref="DifficultyHitObject"/> and update current strain values accordingly.
Expand Down Expand Up @@ -86,7 +115,7 @@ private void startNewSectionFrom(double time, DifficultyHitObject current)
/// <param name="time">The time to retrieve the peak strain at.</param>
/// <param name="current">The current hit object.</param>
/// <returns>The peak strain.</returns>
protected abstract double CalculateInitialStrain(double time, DifficultyHitObject current);
protected virtual double CalculateInitialStrain(double time, DifficultyHitObject current) => CurrentStrain * StrainDecay(time - current.Previous(0).StartTime);

/// <summary>
/// Returns a live enumerable of the peak strains for each <see cref="SectionLength"/> section of the beatmap,
Expand All @@ -111,7 +140,7 @@ public override double DifficultyValue()
foreach (double strain in peaks.OrderDescending())
{
difficulty += strain * weight;
weight *= DecayWeight;
weight *= SumDecay;
}

return difficulty;
Expand Down
Loading