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

Spinner balancing adjustments #23732

Closed
smoogipoo opened this issue Jun 2, 2023 · 23 comments · Fixed by #24932
Closed

Spinner balancing adjustments #23732

smoogipoo opened this issue Jun 2, 2023 · 23 comments · Fixed by #24932
Assignees
Labels
area:gameplay compatibility change Changes to be considered in the future which break compatibility with osu!stable scores.

Comments

@smoogipoo
Copy link
Contributor

Type

Game behaviour

Bug description

It's come to my recent attention that osu!stable computes the number of spins required as half-spins (180deg).

The relevant lazer code is:

// spinning doesn't match 1:1 with stable, so let's fudge them easier for the time being.
const double stable_matching_fudge = 0.6;
// close to 477rpm
const double maximum_rotations_per_second = 8;
double secondsDuration = Duration / 1000;
double minimumRotationsPerSecond = stable_matching_fudge * IBeatmapDifficultyInfo.DifficultyRange(difficulty.OverallDifficulty, 3, 5, 7.5);
SpinsRequired = (int)(secondsDuration * minimumRotationsPerSecond);
MaximumBonusSpins = (int)((maximum_rotations_per_second - minimumRotationsPerSecond) * secondsDuration);

... which computes minimumRotationsPerSecond as half-spins (this is basically stable code), and then applies a fudge factor that makes them behave closer to full-spins.

I believe we should look into whether we can do away with this fudge factor, and use full-spins directly.

Calculations that match osu!stable can be found here: smoogipoo@02111e3#diff-3e6838ae87530f56fc2b07aa2c01b8ab9835cd9ce37b762e645e58cfe6f74a0eR254-R265 which demonstrates a few other quirks that may or may not be relevant to us.

Screenshots or videos

No response

Version

2023.513.0

Logs

@smoogipoo smoogipoo changed the title osu! spinners tick calculations don't match osu!stable osu! spinner tick calculations don't match osu!stable Jun 2, 2023
@smoogipoo smoogipoo changed the title osu! spinner tick calculations don't match osu!stable osu! spinner tick counts don't match osu!stable Jun 2, 2023
@smoogipoo smoogipoo added area:gameplay compatibility change Changes to be considered in the future which break compatibility with osu!stable scores. labels Jun 2, 2023
@smoogipoo smoogipoo added this to the Game balance milestone Jun 2, 2023
@PercyDan54
Copy link
Contributor

Asking here: Are you going to add a hard cap to 477SPM like stable did?

@frenzibyte
Copy link
Member

That's a whole other topic separate from this issue thread, see #21221 (comment).

@peppy peppy moved this to Needs implementation in Path to osu!(lazer) ranked play Aug 20, 2023
@peppy peppy removed this from the Game balance milestone Aug 20, 2023
@peppy peppy moved this from Needs implementation to Needs discussion in Path to osu!(lazer) ranked play Aug 20, 2023
@bdach
Copy link
Collaborator

bdach commented Aug 22, 2023

What do we need to do to progress this one? The description of this one seems pretty cut-and-dry (match stable), so not sure why it's in discussion.

@smoogipoo
Copy link
Contributor Author

smoogipoo commented Aug 22, 2023

I don't think this needs discussion. I believe there's a similar discrepancy in taiko too, fwiw

case Swell swell:
// The taiko swell generally does not match the osu-stable implementation in any way.
// We'll redo the calculations to match osu-stable here...
double minimumRotationsPerSecond = IBeatmapDifficultyInfo.DifficultyRange(playableBeatmap.Difficulty.OverallDifficulty, 3, 5, 7.5);
double secondsDuration = swell.Duration / 1000;
// The amount of half spins that are required to successfully complete the spinner (i.e. get a 300).
int halfSpinsRequiredForCompletion = (int)(secondsDuration * minimumRotationsPerSecond);
halfSpinsRequiredForCompletion = (int)Math.Max(1, halfSpinsRequiredForCompletion * 1.65f);
if (mods.Any(m => m is ModDoubleTime))
halfSpinsRequiredForCompletion = Math.Max(1, (int)(halfSpinsRequiredForCompletion * 0.75f));
if (mods.Any(m => m is ModHalfTime))
halfSpinsRequiredForCompletion = Math.Max(1, (int)(halfSpinsRequiredForCompletion * 1.5f));
for (int i = 0; i <= halfSpinsRequiredForCompletion; i++)
simulateHit(new SwellTick());

Spinners just need to be looked at again in general.

@bdach
Copy link
Collaborator

bdach commented Aug 28, 2023

So there's been a bit of a discussion on this today on osu!dev, and I'm going to attempt summarising it...

  • The starting point is that new exploits from "score farmers" caused us to reconsider the spinner mechanics again, specifically the cap to bonus that can be achieved from a spinner.
  • The stated goals wrt the above were to:
    • limit abuse of potentially unintended gaps in mechanics by making them irrelevant, which could be achieved by
      • capping the max bonus score from a spinner lower than stable so that the cap can be achieved by most players, or
      • making spinners generally easier to spin so that the stable cap can continue to be used, but players can just reach it easier
      • there is room for some extra balancing like variation of the cap depending on OD
  • This triggered a deeper reconsideration of the direction we should be taking wrt spinner mechanics:
    • Should we be porting wonky stable spinner mechanics forward to lazer? (Add two spins gap before awarding bonus score on osu! spinners #24662 was considered to be an example of such a change)
    • Should we be backporting lazer spinner mechanics to stable?
    • Or should we leave stable spinners and lazer spinner independent mechanically-wise and just mess with the score caps to ensure that scores from one can be beaten by the other?

And at this point I guess there's no real consensus where to take this forward. Likely need to go back to the drawing board and get some community involvement.

@bdach bdach changed the title osu! spinner tick counts don't match osu!stable Spinner balancing adjustments Aug 28, 2023
@frenzibyte
Copy link
Member

frenzibyte commented Aug 28, 2023

To express my point of view on this, I've been looking into this task with the thought that this was already discussed and is only pending implementation of matching stable as hinted in #23732 (comment) and #23732 (comment). But I should've backed out as soon as I realised the requirement of adding a two spins gap between a regular tick and a bonus tick, which sounds dodgy indeed to have as part of lazer's refreshed gameplay mechanics.

For the initial objective of this task as described in the OP, it should be resolved with #24661. But, lazer will always have two extra bonus ticks than stable, and whether that is relevant to our initial progress towards ranking gameplays or not, depends on the discussion that was mentioned in #23732 (comment).

I do not have any specific opinions on this matter, and I'll mark myself unassigned if this drops back to "needs discussion". It might make more sense to open a separate issue thread that focuses on this topic, as it's not directly relevant to the number of spinner ticks anymore, but either-or works equally.

EDIT: I see that the issue thread title has already been updated, I'll take back the idea of a separate issue thread then.

@Zyfarok
Copy link
Contributor

Zyfarok commented Aug 28, 2023

I like the idea of capping spinners to something which can be achieved by the huge majority of the player-base.
The maximum speed at which someone cap spin depends heavily on the "grip" (how the player is holding is mouse or pen) and a lot of other non-trainable factors (genetics ?) which make the spinner bonus highly unfair. This is one of the aspects of the game where a casual player can beat a 3 digit because it's almost impossible to increase any significantly the spinning speed with training without requiring a change of grip. (and spinning grips are usually not the best to aim circles)

What I would suggest is thus to have a "hard cap" that increases progressively and linearly as you play the spinner, such that it is impossible to reach the final hard cap earlier than (let's say) 0.5 second before the end. (or any other reasonable amount of milliseconds. Could be AR or OD based ?).
This way, the player could technically stop spinning or slow down at the beginning of the spinner, but it would force him to spin faster afterward to catch up before the end of the spinner and thus the safest and most reasonable approach would be to keep spinning reasonably till the end. This would be better than a speed cap because it allows a margin of error (slow-down, delayed start, grip issue, ...), and would be better than a fixed hard cap because it would require spinning till the end thus achieving the most important purpose of spinners: keep the player busy.

The question of how much should the spinner speed be is a hard one. As I said above, this is something hardly trainable and thus I'm not sure if making the cap OD-based makes any sense. And even if it is OD based, it should probably be bellow 300 even for OD 10, such that the huge majority of players in the top 1000 can safely spin at the max.

For conversion, it's probably best to keep it simple and simply ensure that stable scores will be at a disadvantage. This will already have to be the case anyway because of the introduction of slider-accuracy in lazer which forces us to have a mod-multiplier bellow 1.00 for the classic mod.

@frenzibyte frenzibyte moved this from In Progress to Needs discussion in Path to osu!(lazer) ranked play Aug 29, 2023
@frenzibyte frenzibyte removed their assignment Aug 29, 2023
@peppy
Copy link
Member

peppy commented Aug 30, 2023

I disagree with a variable cap (as proposed by @Zyfarok). It's just introducing new complexity. The "clear" vs "bonus" concept is already supposed to handle this.

@Zyfarok
Copy link
Contributor

Zyfarok commented Aug 30, 2023

@peppy I can see your point. But then, if a hard cap is used, you don't mind the players being able to stop spinning way before the end if they spun faster than required ? (especially on long spinners)

Alternatively, a speed cap + a fixed hard cap could be combined to allow for a small margin of error while still forcing everyone to spin for at least 90% of the spinner or until 1 second before the end or similar.

@peppy
Copy link
Member

peppy commented Aug 31, 2023

you don't mind the players being able to stop spinning way before the end if they spun faster than required?

I don't think I'm against this. I think if we made the change, we'd also have the spinner "complete" early as swells do in osu!taiko, to let the player know they've capped out.

@monochrome22
Copy link

monochrome22 commented Sep 2, 2023

If it's made easier to reach a high spinner speed, then the different spinner behavior might be uncomfortable for players who are used to the old way. Also, players wouldn't be able to compare past spinning performance. Meaning, if someone spun 220 a year ago and now they spin 250, then the system changes, they wouldn't know how much 220 is in the new system, or if they watch an older video of another player spinning, they wouldn't know if their current spin is faster or not.

One issue with lowering the cap might be that spinners simply just won't look as cool anymore, example of a fast spinner.

By the way, if the cap is lowered to something like 300, or if 477 is made easy to reach, then for converting ScoreV1, you could just assume that every score that is an SS or in the top 1000 spun at max speed, so you wouldn't need to rely on replays.

we'd also have the spinner "complete" early as swells do in osu!taiko

Doing that would decrease the experience. For example, spinners can be used during a song buildup section, if you are spinning during this time, then you can feel the song and map better, example. Also, spinners have been mapped so that they end at a specific time to follow the rhythm, allowing the spin to finish at any other time decreases the experience and undermines the mappers intentions. (I don't play taiko, so I hope I'm not misunderstanding how the spinners work there). Also, for these same reasons I disagree with Zyf's proposal of a speed cap + a fixed hard cap.

Personally I think it would be fine to not be able to catch up. Any better player should be able to consistently spin 300. Also, I see bonus as "get as much as you can before the time runs out", so if you are not doing everything you can, then you shouldn't get all the score from that bonus. Keep in mind that needing to spin at the cap only really matters if you're SSing. If you're SSing and you're not trying to hit spinners well or you mess up, then it's your own fault when you miss out on score, and if you're not SSing then it shouldn't matter if you miss out on a bit of score. Also, I agree with changing the cap to 300 (or around that), I never liked there being things that people do just to get a faster spin, like pausing and changing grip, changing mouse dpi and probably many other things. It feels like a mess. I prefer changing cap over making 477 easier, because I find it important to be able to compare past performance.

@Zyfarok
Copy link
Contributor

Zyfarok commented Sep 3, 2023

I agree with @monochrome22 except for two things:

1- I'm not sure people would care that much about comparing spinning performance with stable in lazer ? And in any-case, the RPM displayed should be as close as possible to the actual rotations per minute of the cursor (with some inertia if desired)... Otherwise the unit is meaningless ?

2- Spinning at the cap can matter in other scenarios than SSes. In particular, the amount of ScoreV2 tournament matches where points have been decided on spinners is much more important than you would think. Hopefully the reduction of score given by spinners in lazer (compared to v2) as well as the lower speed cap should reduce the probability of this happening but this might still be a thing.

My main concern with fixed speed-cap is that some maps have spinner ending (/starting) too close to other hit-objects, making it close to impossible to spin fully till the end (/from the start), without a risk of missing the next (/previous) objects. The second example @monochrome22 gave showcases this perfectly, as shige misses due to not being fully ready to flow due to the spinner.
This could be judged as bad map design, but is relatively common from my experience.

@peppy
Copy link
Member

peppy commented Sep 6, 2023

Also, players wouldn't be able to compare past spinning performance. Meaning, if someone spun 220 a year ago and now they spin 250, then the system changes, they wouldn't know how much 220 is in the new system

As already mentioned, the RPM is not really attached to scoring, and ignoring acceleration, is already on parity between games. I'd call this a non-issue.

@bdach
Copy link
Collaborator

bdach commented Sep 18, 2023

@ppy/team-client we've gotten some changes regarding spinners in - shall we consider this resolved for now, or is there still anything else we should be working on in the context of this issue? Note that cheesing is a separate issue already (#8224).

Edit: was reminded by @peppy that we should still probably look into decreasing the difficulty of bonus spins so that it's easier to achieve by all players and therefore stop people from trying weird things to get an advantage and snipe first place on leaderboards.

@peppy
Copy link
Member

peppy commented Sep 20, 2023

@smoogipoo I seem to recall you mentioning that someone provided you with a max RPM proposal for the above, did you have any documentation for that?

@smoogipoo
Copy link
Contributor Author

What do you mean by documentation, just posting the idea that was provided?

@peppy
Copy link
Member

peppy commented Sep 20, 2023

Yeah, I just remember you saying there was a proposal, along with a specific number / algorithm. It would be a starting point to keep this discussion moving forward.

@smoogipoo
Copy link
Contributor Author

  • Tie the maximum spins to overall difficulty (OD). Currently maximum required spins is capped, but maximum bonus spins is uncapped.
  • Should still remain challenging at higher ODs, for example 250rpm at OD 0 and 430rpm at OD 10 to get the full spin.

@bdach
Copy link
Collaborator

bdach commented Sep 25, 2023

The group most directly hit by such a change would be the score farmers I guess?

@WitherFlower if I recall right you tend to be the liaison for score farming stuff? Thoughts on spinner caps making it easier to reach max?

@peppy
Copy link
Member

peppy commented Sep 25, 2023

I'd be interested in not general thoughts of "if", but what the cutoffs should be. With a strict goal of making all spinners able to be completed by anyone should they put in the effort.

AKA without any kind of weird glitching, frame rate adjusting, pausing, etc.

@WitherFlower
Copy link
Contributor

I think the player group most affected by this would be leaderboard farmers, which I'm not part of so I won't speak for them.

As a player with a decent spinning speed, I don't think the speed required should ever go above 400 RPM (without acceleration). If you want to make spinners max-able by most players that put in a bit of effort, I think somewhere between 330 and 350 RPM is fine.

Not sure about the whole OD thing though, I never found it intuitive that hit windows are tied to spinning speed. I'd argue it's best to either ditch that completely, or split it into its own difficulty setting, but that might be out of scope here.

@bdach
Copy link
Collaborator

bdach commented Sep 25, 2023

I think the player group most affected by this would be leaderboard farmers, which I'm not part of so I won't speak for them

Do you know where such people can be reached maybe? I'll go ask around elsewhere if not, but I can't say I personally have very good visibility on or awareness of that part of the community...

@molneya
Copy link
Contributor

molneya commented Sep 25, 2023

I've asked a few people who like to spin/play for leaderboards and got some ideas/feedback:

The idea to make different rpm requirements for different OD is good not entirely agreed upon (14 votes in favour to 57 votes against), and the exact values will probably have to be reviewed since rpm values in stable and lazer don't quite line up (possibly by looking at different lazer replays for varying skill levels). Some example stable values that were suggested: 300 for OD0, 477 for OD10

Another idea/point that was discussed was that having an uncapped spinning rpm makes it possible to complete spinners very quickly, removing the challenge of keeping a consistent spin. If the maximum possible spin rpm matched the rpm requirement, it would add this challenge back. Of the 57 that voted against the previous idea, 18 agreed with this idea of spinner implementations.

@smoogipoo smoogipoo self-assigned this Sep 26, 2023
@peppy peppy moved this from Needs discussion to In Progress in Path to osu!(lazer) ranked play Sep 26, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in Path to osu!(lazer) ranked play Sep 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:gameplay compatibility change Changes to be considered in the future which break compatibility with osu!stable scores.
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

9 participants