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

Adjust a beatmaps offset automatically after each play #30586

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ae5f839
adding logic to adjust offset after ach play
Inconsist Nov 11, 2024
ff93d91
adding menu/settings requirements
Inconsist Nov 11, 2024
8ddf79a
xml doc adjustment
Inconsist Nov 11, 2024
795c0a6
Refactored to more meaningful names added comments to explain calcula…
Inconsist Nov 11, 2024
d1acdc9
update to name after changes.
Inconsist Nov 11, 2024
0c06b74
fixed problem with codefactor
Inconsist Nov 11, 2024
a606bef
Merge branch 'ppy:master' into Adjust_offset
Inconsist Nov 12, 2024
08d18b8
added checkbox on the in game overlay menu that appears on start/rest…
Inconsist Nov 13, 2024
0688853
Merge remote-tracking branch 'origin/Adjust_offset' into Adjust_offset
Inconsist Nov 13, 2024
76d7343
Merge branch 'ppy:master' into Adjust_offset
Inconsist Nov 13, 2024
4432e95
try to fix single thread crashing
Inconsist Nov 13, 2024
8f017c2
Merge remote-tracking branch 'origin/Adjust_offset' into Adjust_offset
Inconsist Nov 13, 2024
f11ba0a
Merge branch 'ppy:master' into Adjust_offset
Inconsist Nov 13, 2024
402aea4
conform with codestyle in similar files.
Inconsist Nov 13, 2024
715a0f3
reverting switch to if statements.
Inconsist Nov 13, 2024
76ba64a
Merge remote-tracking branch 'origin/Adjust_offset' into Adjust_offset
Inconsist Nov 13, 2024
c994448
Merge branch 'ppy:master' into Adjust_offset
Inconsist Nov 14, 2024
a9e0856
Merge branch 'ppy:master' into Adjust_offset
Inconsist Nov 15, 2024
ab6d06c
Adjust messaging to be more explicit
peppy Nov 15, 2024
9a290bb
Remove setting from player loader
peppy Nov 15, 2024
8703f59
removed leftover unsused checkbox from the loader screen
Inconsist Nov 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions osu.Game/Configuration/OsuConfigManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ protected override void InitialiseDefaults()
SetDefault(OsuSetting.MenuTips, true);

SetDefault(OsuSetting.AudioOffset, 0, -500.0, 500.0, 1);
SetDefault(OsuSetting.AutoAdjustBeatmapOffset, false);

// Input
SetDefault(OsuSetting.MenuCursorSize, 1.0f, 0.5f, 2f, 0.01f);
Expand Down Expand Up @@ -362,6 +363,7 @@ public enum OsuSetting
/// This is added to the audio track's current time. Higher values will cause gameplay to occur earlier, relative to the audio track.
/// </summary>
AudioOffset,
AutoAdjustBeatmapOffset,

VolumeInactive,
MenuMusic,
Expand Down
5 changes: 5 additions & 0 deletions osu.Game/Localisation/AudioSettingsStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ public static class AudioSettingsStrings
/// </summary>
public static LocalisableString AudioOffset => new TranslatableString(getKey(@"audio_offset"), @"Audio offset");

/// <summary>
/// "Automatically adjust beatmap offset after every play"
/// </summary>
public static LocalisableString AutoAdjustBeatmapOffset => new TranslatableString(getKey(@"auto_adjust_beatmap_offset"), @"Automatically adjust beatmap offset after every play");

/// <summary>
/// "Play a few beatmaps to receive a suggested offset!"
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ private void load(OsuConfigManager config)
{
Children = new Drawable[]
{
new SettingsCheckbox
{
LabelText = AudioSettingsStrings.AutoAdjustBeatmapOffset,
Current = config.GetBindable<bool>(OsuSetting.AutoAdjustBeatmapOffset)
},
new AudioOffsetAdjustControl
{
Current = config.GetBindable<double>(OsuSetting.AudioOffset),
Expand Down
33 changes: 33 additions & 0 deletions osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using osu.Framework.Localisation;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
Expand Down Expand Up @@ -60,6 +61,8 @@ public partial class BeatmapOffsetControl : CompositeDrawable, IKeyBindingHandle
[Resolved]
private IGameplayClock? gameplayClock { get; set; }

private double? unstableRate;
private Bindable<bool> autoAdjustBeatmapOffset = null!;
private double lastPlayAverage;
private double lastPlayBeatmapOffset;
private HitEventTimingDistributionGraph? lastPlayGraph;
Expand Down Expand Up @@ -169,6 +172,12 @@ void updateOffset()
}
}

[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
autoAdjustBeatmapOffset = config.GetBindable<bool>(OsuSetting.AutoAdjustBeatmapOffset);
}

private void scoreChanged(ValueChangedEvent<ScoreInfo?> score)
{
referenceScoreContainer.Clear();
Expand Down Expand Up @@ -214,6 +223,30 @@ private void scoreChanged(ValueChangedEvent<ScoreInfo?> score)
return;
}

unstableRate = hitEvents.CalculateUnstableRate();
const double unstablerate_threshold = 90;
const double exponential_factor = -0.0116;
// Parameters for the calculation that scales the offset with respect to UR.

if (autoAdjustBeatmapOffset.Value) //Enters this case if global setting is checked in Menu.
{
if (hitEvents.Count >= 30) //Make sure that there is a minimum baseline of hits to make evaluation.
{
if (unstableRate >= unstablerate_threshold)
{
Current.Value = lastPlayBeatmapOffset - (average * Math.Exp((double)(exponential_factor * (unstableRate - unstablerate_threshold))));
Copy link
Member

Choose a reason for hiding this comment

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

I'm sure this makes good sense, but without attempting to understand the consequences, I'm curious if there's a reason not to always use this algorithm even when the user presses the adjust button.

Copy link
Author

Choose a reason for hiding this comment

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

I don't think anything speaks against this per se. But it might just lead to situations where the player feels like the offset should have been way bigger, and is confused why it only says something like 0.8ms.
The button press is a conscious choice you make after every play, so I think displaying the true hit error average here is more genuine towards the player.
You can always choose not to apply an offset you know resulted from you playing poorly.
In my opinion when using the automation the safeguard is needed, but the player should choose themself when using the button.

Copy link
Member

Choose a reason for hiding this comment

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

Fair. Might be good to include this kind of explanation inline to give more context.

Copy link
Author

@Inconsist Inconsist Nov 14, 2024

Choose a reason for hiding this comment

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

I think I made a comment that leads any reader to the discussion where the calculation is explained in more detail. I didn't want to write such long comments since they say less than the image.
If you mean giving more context to the player, the setting name is already quite long, I couldn't think of a better way to name the setting for now, any ideas are appreciated.

// A visual explanation of what is calculated here can be found in discussion #30521
// A calculated offset which is achieved with low UR has higher impact than offset calculated with high UR.
// "average" will be scaled by a value between 1.0 and 0.0
}

if (unstableRate < unstablerate_threshold)
{
Current.Value = lastPlayBeatmapOffset - average;
}
}
}

lastPlayAverage = average;
lastPlayBeatmapOffset = Current.Value;

Expand Down