-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Correctly implement stable notelock in Classic mod #24280
Conversation
@@ -20,7 +20,7 @@ public interface IHitPolicy | |||
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to check.</param> | |||
/// <param name="time">The time to check.</param> | |||
/// <returns>Whether <paramref name="hitObject"/> can be hit at the given <paramref name="time"/>.</returns> | |||
bool IsHittable(DrawableHitObject hitObject, double time); | |||
ClickAction CheckHittable(DrawableHitObject hitObject, double time); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open to renamings of both CheckHittable
and ClickAction
. ClickAction
was brought across from the stable naming.
yield break; | ||
var previousHitObject = (DrawableOsuHitObject)HitObjectContainer.AliveObjects[index - 1]; | ||
if (previousHitObject.HitObject.StackHeight > 0 && !previousHitObject.AllJudged) | ||
return ClickAction.Ignore; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this case right here is why the ClickAction
abstraction is necessary. There are times when a note should, by all other metrics, be shaken, but we don't want it to be (e.g. stacks).
I see the test failures (was accidentally only running |
stable actually allows for hitobjs to be hit in the middle of sliders, as long as it doesn't interfere with the end time of the slider.
I've fixed one test in 15af852 by adjusting expected judgments to the correct notelock: believe it or not (I didn't, and had to test against stable), stable allows hitobjects to be hit even while a slider head is the primary / next object, as long as that hitobject doesn't interfere with the end time of the slider. I guess that's another stable mismatch bug fixed by this pull that I didn't even know about. The other two failing tests are a result of custom hitwindows. Since this pull (and stable) hardcodes the notelock check at 400ms instead of using hitwindow information - which happens to also be 400ms for On one hand, the obvious solution here seems to be to respect hitwindows in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for rename suggestions - maybe HitResponse
or something instead? Maybe overthought. What you have is probably fine.
Tests would go a long way here yes. Loose sketch of how writing some may be possible (very untested, buyer beware):
Let's not try to future-proof too much and just hardcode the constant along with the rest of the legacy cruft. As far as I'm concerned we're not changing hitwindows anyway without a whole nother huge effort to somehow not break every leaderboard in existence. I don't even know why'd be changing hitwindows to be honest. |
Well, hardcoding the constant is what's causing the tests to fail, since the tests use custom hitwindows. Should I remove/adjust the tests? |
Oh. Right, I somehow had this backwards. In that case yeah adjusting the tests sounds best. |
Just as a heads up: I have put a considerable amount of time into looking at what needs to happen to get this one merged, and I feel I've gathered enough to work with for one or two possible avenues of shipping this change. I'll leave this be for the time being, but tomorrow I'll come back to this with a fresh mind and hopefully I can get this unblocked and also provide testing for the behaviours this new implementation aims to deliver. |
Thanks! To be honest, I've been putting off working on this because I know it'll take me a while to wrap my head around writing tests for it. |
I believe I've got a version of this branch that I would consider ready lined up, but I'm waiting for the reaction to #24627 and #24628 as I want to build this one on them, so I'd rather want to avoid force pushing them out if it turns out they aren't going to get approval. The WIP version can be seen here, if anyone cares: https://github.com/ppy/osu/compare/master...bdach:osu:stable-notelock-working?expand=1 - if the two above pulls get merged then I'll push those changes in here. |
@ppy/team-client should be good for review now. @tybug would appreciate your cross-check as well that I haven't broken anything with my changes, if I can get it. |
@@ -191,7 +198,9 @@ public void TestClickSecondCircleBeforeFirstCircleTimeWithFirstCircleJudged() | |||
addJudgementAssert(hitObjects[0], HitResult.Meh); | |||
addJudgementAssert(hitObjects[1], HitResult.Meh); | |||
addJudgementOffsetAssert(hitObjects[0], -190); // time_first_circle - 190 | |||
addJudgementOffsetAssert(hitObjects[0], -90); // time_second_circle - first_circle_time - 90 | |||
addJudgementOffsetAssert(hitObjects[1], -190); // time_second_circle - first_circle_time - 90 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I accidentally broke this assertion in #24628, but it was broken before I touched the test scene (note that it used to check hitObjects[0]
twice). I'm just fixing here to reduce overall ceremony.
I checked out this branch to test, but it seems to have a renderer-level crash for me when entering song select: Stacktrace
Does not occur with metal renderer. I'm on macos but am using opengl temporarily because of #23970 (which seems to be partially resolved by now; no startup crash anymore, at least). I'm really confused here, because this does not occur on latest master, but does on this branch consistently (n=4 retries each). I can't see what changes in this branch are related to the renderer, which is why I'm hesitant to even post this here...have I hit a freak probabilistic crash that only appears to occur on this pr? |
There should be no reason why this branch specifically would trigger any sort of renderer level crash. Especially not on song select of all places. That's what I'd like to think, at least. |
That's what I figured. Looked into it more and I forgot to sync my fork ;-; so it is actually crashing on master as well. I'll open another issue for that. |
I've tested the replays linked in the PR description and one other problematic one, and all behave as I would expect, so things look good purely from a visual perspective. Two comments, though - first, I don't think there's a test for the 3ms of leniency. This was one of the things that I didn't explicitly test myself with a replay, though I can't see why it wouldn't work as expected. If it's judged that case isn't worth a test then that's of course fine with me. A separate comment is that with this PR, replay 1 in the description - which is an FC - consistently breaks combo right around ~2100x (~5:18), but only when fast-forwarding to a point past it. This doesn't happen on master. I believe there's still various "fast-forward playback can be wrong" issues, so this probably isn't a blocker, but I'll mention it regardless since it's new behavior introduced here. |
Yeah there isn't. I decided not to bother with that one. Up to reviewers whether that's an issue I guess. It shouldn't be very difficult to come up with one if required.
I think we'd be looking to address that separately anyhow. The core takeaway is that it is more correct at 1x. |
e668938
to
ede9fae
Compare
As far as I can tell, stable notelock was never implemented correctly in lazer. This PR implements stable notelock effectively 1:1.
There are two obvious behavioral changes in this diff, though there may be more that are obscured by the details.
Relevant stable code:
I'm very aware that a change this far reaching deserves tests...but I'm honestly not sure how to easily test this (particularly a note being shaken vs ignored). Pointers in that regard would be appreciated.