Skip to content

Commit

Permalink
Merge branch 'master' into mania-scorev2-values
Browse files Browse the repository at this point in the history
  • Loading branch information
bdach committed Dec 20, 2023
2 parents b0da241 + a8c9db2 commit 8c06d38
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 94 deletions.
5 changes: 5 additions & 0 deletions osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModDoubleTime : ModDoubleTime, IManiaRateAdjustmentMod
{
public HitWindows HitWindows { get; set; } = new ManiaHitWindows();

// For now, all rate-increasing mods should be given a 1x multiplier in mania because it doesn't always
// make the map harder and is more of a personal preference.
// In the future, we can consider adjusting this by experimenting with not applying the hitwindow leniency.
public override double ScoreMultiplier => 1;
}
}
5 changes: 5 additions & 0 deletions osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModNightcore : ModNightcore<ManiaHitObject>, IManiaRateAdjustmentMod
{
public HitWindows HitWindows { get; set; } = new ManiaHitWindows();

// For now, all rate-increasing mods should be given a 1x multiplier in mania because it doesn't always
// make the map any harder and is more of a personal preference.
// In the future, we can consider adjusting this by experimenting with not applying the hitwindow leniency.
public override double ScoreMultiplier => 1;
}
}
3 changes: 3 additions & 0 deletions osu.Game.Tests/Database/BackgroundDataStoreProcessorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,11 @@ public void TestDifficultyProcessingWhilePlaying()
});
}

[TestCase(30000001)]
[TestCase(30000002)]
[TestCase(30000003)]
[TestCase(30000004)]
[TestCase(30000005)]
public void TestScoreUpgradeSuccess(int scoreVersion)
{
ScoreInfo scoreInfo = null!;
Expand Down
3 changes: 1 addition & 2 deletions osu.Game/BackgroundDataStoreProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,7 @@ private void convertLegacyTotalScoreToStandardised()

HashSet<Guid> scoreIds = realmAccess.Run(r => new HashSet<Guid>(r.All<ScoreInfo>()
.Where(s => !s.BackgroundReprocessingFailed && s.BeatmapInfo != null
&& (s.TotalScoreVersion == 30000002
|| s.TotalScoreVersion == 30000003))
&& s.TotalScoreVersion < LegacyScoreEncoder.LATEST_VERSION)
.AsEnumerable().Select(s => s.ID)));

Logger.Log($"Found {scoreIds.Count} scores which require total score conversion.");
Expand Down
16 changes: 13 additions & 3 deletions osu.Game/Database/StandardisedScoreMigrationTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static bool ShouldMigrateToNewStandardised(ScoreInfo score)
if (score.IsLegacyScore)
return false;

if (score.TotalScoreVersion > 30000004)
if (score.TotalScoreVersion > 30000002)
return false;

// Recalculate the old-style standardised score to see if this was an old lazer score.
Expand Down Expand Up @@ -293,13 +293,23 @@ public static long ConvertFromLegacyTotalScore(ScoreInfo score, LegacyBeatmapCon
// Roughly corresponds to integrating f(combo) = combo ^ COMBO_EXPONENT (omitting constants)
double maximumAchievableComboPortionInStandardisedScore = Math.Pow(maximumLegacyCombo, 1 + ScoreProcessor.COMBO_EXPONENT);

double comboPortionInScoreV1 = maximumAchievableComboPortionInScoreV1 * comboProportion / score.Accuracy;

// This is - roughly - how much score, in the combo portion, the longest combo on this particular play would gain in score V1.
double comboPortionFromLongestComboInScoreV1 = Math.Pow(score.MaxCombo, 2);
// Same for standardised score.
double comboPortionFromLongestComboInStandardisedScore = Math.Pow(score.MaxCombo, 1 + ScoreProcessor.COMBO_EXPONENT);

// We estimate the combo portion of the score in score V1 terms.
// The division by accuracy is supposed to lessen the impact of accuracy on the combo portion,
// but in some edge cases it cannot sanely undo it.
// Therefore the resultant value is clamped from both sides for sanity.
// The clamp from below to `comboPortionFromLongestComboInScoreV1` targets near-FC scores wherein
// the player had bad accuracy at the end of their longest combo, which causes the division by accuracy
// to underestimate the combo portion.
// Ideally, this would be clamped from above to `maximumAchievableComboPortionInScoreV1` too,
// but in practice this appears to fail for some scores (https://github.com/ppy/osu/pull/25876#issuecomment-1862248413).
// TODO: investigate the above more closely
double comboPortionInScoreV1 = Math.Max(maximumAchievableComboPortionInScoreV1 * comboProportion / score.Accuracy, comboPortionFromLongestComboInScoreV1);

// Calculate how many times the longest combo the user has achieved in the play can repeat
// without exceeding the combo portion in score V1 as achieved by the player.
// This is a pessimistic estimate; it intentionally does not operate on object count and uses only score instead.
Expand Down
19 changes: 11 additions & 8 deletions osu.Game/Online/Metadata/OnlineMetadataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@ private void isConnectedChanged(ValueChangedEvent<bool> connected)
{
if (!connected.NewValue)
{
isWatchingUserPresence.Value = false;
userStates.Clear();
Schedule(() =>
{
isWatchingUserPresence.Value = false;
userStates.Clear();
});
return;
}

Expand Down Expand Up @@ -187,13 +190,13 @@ public override Task UpdateStatus(UserStatus? status)

public override Task UserPresenceUpdated(int userId, UserPresence? presence)
{
lock (userStates)
Schedule(() =>
{
if (presence != null)
userStates[userId] = presence.Value;
else
userStates.Remove(userId);
}
});

return Task.CompletedTask;
}
Expand All @@ -205,7 +208,7 @@ public override async Task BeginWatchingUserPresence()

Debug.Assert(connection != null);
await connection.InvokeAsync(nameof(IMetadataServer.BeginWatchingUserPresence)).ConfigureAwait(false);
isWatchingUserPresence.Value = true;
Schedule(() => isWatchingUserPresence.Value = true);
}

public override async Task EndWatchingUserPresence()
Expand All @@ -215,14 +218,14 @@ public override async Task EndWatchingUserPresence()
if (connector?.IsConnected.Value != true)
throw new OperationCanceledException();

// must happen synchronously before any remote calls to avoid misordering.
userStates.Clear();
// must be scheduled before any remote calls to avoid mis-ordering.
Schedule(() => userStates.Clear());
Debug.Assert(connection != null);
await connection.InvokeAsync(nameof(IMetadataServer.EndWatchingUserPresence)).ConfigureAwait(false);
}
finally
{
isWatchingUserPresence.Value = false;
Schedule(() => isWatchingUserPresence.Value = false);
}
}

Expand Down
3 changes: 2 additions & 1 deletion osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ public class LegacyScoreEncoder
/// <item><description>30000003: First version after converting legacy total score to standardised.</description></item>
/// <item><description>30000004: Fixed mod multipliers during legacy score conversion. Reconvert all scores.</description></item>
/// <item><description>30000005: Introduce combo exponent in the osu! gamemode. Reconvert all scores.</description></item>
/// <item><description>30000006: Fix edge cases in conversion after combo exponent introduction that lead to NaNs. Reconvert all scores.</description></item>
/// </list>
/// </remarks>
public const int LATEST_VERSION = 30000005;
public const int LATEST_VERSION = 30000006;

/// <summary>
/// The first stable-compatible YYYYMMDD format version given to lazer usage of replays.
Expand Down
Loading

0 comments on commit 8c06d38

Please sign in to comment.