Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix osu! stacking not matching stable in very specific edge cases#36056

Merged
bdach merged 6 commits intoppy:masterfrom
peppy:fix-stacking-woes
Dec 23, 2025
Merged

Fix osu! stacking not matching stable in very specific edge cases#36056
bdach merged 6 commits intoppy:masterfrom
peppy:fix-stacking-woes

Conversation

@peppy
Copy link
Member

@peppy peppy commented Dec 18, 2025

Closes #36052.

Not much more to say here. Until now the PreEmpt typing discrepancy has likely gone unnoticed since it's usually only used in visual usages.

Closes ppy#36052.

Not much more to say here. Until now the `PreEmpt` typing discrepancy
has likely gone unnoticed since it's usually only used in visual usages.
@peppy
Copy link
Member Author

peppy commented Dec 18, 2025

!diffcalc
RULESET=osu

@stanriders
Copy link
Member

stanriders commented Dec 18, 2025

TimePreempt is being used in diffcalc so it might be a good idea to run a sheet just in case

1 minute late smh

@bdach
Copy link
Collaborator

bdach commented Dec 18, 2025

we were going to run it anyway as a surrogate of checking that this doesn't accidentally break stacking on some other special snowflake ranked map that was depending on the floating point [REDACTED] going the other way

Copy link
Collaborator

@bdach bdach left a comment

Choose a reason for hiding this comment

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

if we're already tracking this down I would probably apply the truncation in a few other places:

TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_RANGE);

this one shouldn't have any material effects but maybe? who knows at this point

new RulesetBeatmapAttribute.AdditionalMetric("Approach time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, OsuHitObject.PREEMPT_RANGE):#,0.##} ms"))

new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))

these ones are purely visual, probably best to not pretend fractions are involved here when they're not

@peppy
Copy link
Member Author

peppy commented Dec 18, 2025

There's also some additional similar cases in GetAdjustedDisplayDifficulty that do calculation then inverse calculation to adjust AR, thoughts?

@pull-request-size pull-request-size bot added size/L and removed size/M labels Dec 18, 2025
@bdach
Copy link
Collaborator

bdach commented Dec 18, 2025

There's also some additional similar cases in GetAdjustedDisplayDifficulty that do calculation then inverse calculation to adjust AR, thoughts?

let's not do that because it's not going to be as simple to handle (the flooring in AR makes it so that you can get multiple different answers when you attempt to take the inverse after flooring)

@bdach
Copy link
Collaborator

bdach commented Dec 18, 2025

!diffcalc
RULESET=catch

just for my peace of mind

bdach
bdach previously approved these changes Dec 18, 2025
Copy link
Collaborator

@bdach bdach left a comment

Choose a reason for hiding this comment

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

pending diffcalc check

(I posted a wrong comment here earlier then deleted it because I confused myself)

@github-actions
Copy link

@github-actions
Copy link

@bdach bdach self-requested a review December 19, 2025 07:35
@bdach
Copy link
Collaborator

bdach commented Dec 19, 2025

I've done a follow-up check on the other beatmaps that the diffcalc run turned up by running conversion mappings. It almost looks good. Unfortunately it's only almost.

master this PR
Screenshot 2025-12-19 at 09 17 14 Screenshot 2025-12-19 at 09 18 06

From the failures with this PR, /b/1341554, /b/2730824, and /b/4235513 are not regressions (still failing, but less so), so I'd be happy to just dismiss them, merge this as-is, and investigate those as follow-ups. Unfortunately /b/2593923 is an apparent regression and therefore needs further investigation.

Some are not immediately relevant to the stacking issue because they
fail both before and after it, just less so after the stacking issue
(half-)fix, and as such have been commented out for the time being.
@bdach
Copy link
Collaborator

bdach commented Dec 19, 2025

I've pushed a fix for the regressed beatmap. @peppy please check if you're ok with my changes whenever able.

In the meantime:

!diffcalc
RULESET=osu

The other broken cases I'll look at separately.

@peppy
Copy link
Member Author

peppy commented Dec 19, 2025

The fix looks appropriate, thanks.

They all pass along with the last stacking threshold fix, so I see no
reason to keep them in.
@bdach
Copy link
Collaborator

bdach commented Dec 19, 2025

Turns out remaining failures from #36056 (comment) are also relevant to stacking code (25ba3f2), so I've just pushed here to hopefully kill this once and for all. Might regret it later.

I've canceled the previous diffcalc run, so 🎶 here it goes, here it goes, here it goes again 🎶:

!diffcalc
RULESET=osu

@bdach bdach changed the title Fix osu! stacking not matching stable in very specific edge case Fix osu! stacking not matching stable in very specific edge cases Dec 19, 2025
@github-actions
Copy link

@bdach
Copy link
Collaborator

bdach commented Dec 22, 2025

I've gone through the latest sheet and double-checked conversion mappings for the new changed beatmaps, too. Won't lie that I did regret pushing that last change in due to number of maps that needed checking, but the end result looks clean, so as far as I'm concerned, this is good to go.

Details

Generated mappings: mappings.zip

osu.Game.Rulesets.Osu.Tests (168 tests) Success
  osu.Game.Rulesets.Osu.Tests (168 tests) Success
    OsuBeatmapConversionTest (168 tests) Success
      Test (168 tests) Success
        Test("1021349") Success
        Test("1105232") Success
        Test("1124896") Success
        Test("113592") Success
        Test("121073") Success
        Test("1233411") Success
        Test("1249673") Success
        Test("125201") Success
        Test("1253369") Success
        Test("1271354") Success
        Test("1341554") Success
        Test("1388269") Success
        Test("1406267") Success
        Test("1410343") Success
        Test("1473304") Success
        Test("148509") Success
        Test("1491209") Success
        Test("1543673") Success
        Test("161703") Success
        Test("1642169") Success
        Test("169450") Success
        Test("1710848") Success
        Test("1761256") Success
        Test("1775698") Success
        Test("180418") Success
        Test("1828537") Success
        Test("1847043") Success
        Test("1854237") Success
        Test("191133") Success
        Test("191503") Success
        Test("1925407") Success
        Test("2025205") Success
        Test("2118515") Success
        Test("2139556") Success
        Test("2154180") Success
        Test("225301") Success
        Test("226279") Success
        Test("2322554") Success
        Test("233148") Success
        Test("2359453") Success
        Test("2381026") Success
        Test("2393032") Success
        Test("2464763") Success
        Test("2488852") Success
        Test("2494808") Success
        Test("2534559") Success
        Test("256839") Success
        Test("256840") Success
        Test("2593923") Success
        Test("2612248") Success
        Test("2628833") Success
        Test("270137") Success
        Test("2715288") Success
        Test("2775959") Success
        Test("2814117") Success
        Test("290422") Success
        Test("2949285") Success
        Test("2966904") Success
        Test("2990276") Success
        Test("30613") Success
        Test("3150902") Success
        Test("315115") Success
        Test("3189047") Success
        Test("3231091") Success
        Test("327526") Success
        Test("3287712") Success
        Test("3287714") Success
        Test("3316842") Success
        Test("3345630") Success
        Test("3438298") Success
        Test("3442572") Success
        Test("3452950") Success
        Test("3465695") Success
        Test("3474234") Success
        Test("3559124") Success
        Test("3634641") Success
        Test("3642066") Success
        Test("3647077") Success
        Test("3656104") Success
        Test("3681813") Success
        Test("3690388") Success
        Test("371175") Success
        Test("3715317") Success
        Test("3749842") Success
        Test("3805781") Success
        Test("3880551") Success
        Test("3888276") Success
        Test("3900789") Success
        Test("4053400") Success
        Test("4060642") Success
        Test("4064874") Success
        Test("4091400") Success
        Test("4130331") Success
        Test("4131547") Success
        Test("4145242") Success
        Test("4179858") Success
        Test("4219265") Success
        Test("4225770") Success
        Test("425916") Success
        Test("4277171") Success
        Test("432913") Success
        Test("435472") Success
        Test("4366791") Success
        Test("4388888") Success
        Test("4397861") Success
        Test("4441465") Success
        Test("4448551") Success
        Test("4492463") Success
        Test("4501547") Success
        Test("4691035") Success
        Test("4750413") Success
        Test("4855573") Success
        Test("4888991") Success
        Test("4935653") Success
        Test("4951682") Success
        Test("500728") Success
        Test("5046238") Success
        Test("5151961") Success
        Test("518109") Success
        Test("52183") Success
        Test("533775") Success
        Test("5345594") Success
        Test("559809") Success
        Test("561707") Success
        Test("607813") Success
        Test("623793") Success
        Test("635375") Success
        Test("646530") Success
        Test("653086") Success
        Test("679101") Success
        Test("683086") Success
        Test("70914") Success
        Test("709258") Success
        Test("735336") Success
        Test("73699") Success
        Test("758468") Success
        Test("761722") Success
        Test("766939") Success
        Test("786166") Success
        Test("792545") Success
        Test("801165") Success
        Test("801439") Success
        Test("803402") Success
        Test("804534") Success
        Test("84142") Success
        Test("847296") Success
        Test("851518") Success
        Test("915459") Success
        Test("918087") Success
        Test("93027") Success
        Test("931597") Success
        Test("942418") Success
        Test("943989") Success
        Test("947556") Success
        Test("951392") Success
        Test("967311") Success
        Test("977161") Success
        Test("988617") Success
        Test("basic") Success
        Test("colinear-perfect-curve") Success
        Test("multi-segment-slider") Success
        Test("nan-slider") Success
        Test("old-stacking") Success
        Test("repeat-slider") Success
        Test("slider-paths-edge-case") Success
        Test("slider-ticks-edge-case") Success
        Test("slider-ticks") Success
        Test("uneven-repeat-slider") Success

From the pp angle the changes look negligible (at most ±2% swing in worst cases) and I don't particularly care about pp anyway because this is fixing stable-lazer beatmap parsing discrepancies.

@bdach bdach added the area:beatmap parsing .osu file format parsing label Dec 22, 2025
@bdach bdach merged commit 71386fe into ppy:master Dec 23, 2025
9 checks passed
@github-project-automation github-project-automation bot moved this from Pending Review to Done in osu! team task tracker Dec 23, 2025
@peppy peppy deleted the fix-stacking-woes branch December 25, 2025 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Different stacking between stable and lazer

3 participants

Comments