Skip to content

Fix OsuAutoGenerator failing to alternate when objects are exactly 50ms apart#36227

Merged
peppy merged 3 commits intoppy:masterfrom
minetoblend:fix-editor-broken-for-spartans
Jan 5, 2026
Merged

Fix OsuAutoGenerator failing to alternate when objects are exactly 50ms apart#36227
peppy merged 3 commits intoppy:masterfrom
minetoblend:fix-editor-broken-for-spartans

Conversation

@minetoblend
Copy link
Copy Markdown
Contributor

@minetoblend minetoblend commented Jan 5, 2026

Closes #36213, closes #22353
Probably also resolves several comments on #26559 (osu-ruleset only, anything mention maps with 150 or 300bpm)

Currently, if 2 objects are exactly 50ms (1/4 at 300bpm) apart the autoplay generator will generate frames that make it impossible to hit the second object without frame-stability, leading to hitsounds & hit animations not working in the editor for those objects.

There's a combination of 3 things happening that cause this problem, fixing either one of them fixes the problem.

  • The autoplay generator inserts key-up events exactly 50ms (AutoGenerator.KEY_UP_DELAY) after an object's end time into the replay.
    If the next object starts before this key-up frame, that frame is later removed when the next object's click frames are generated.
    If the objects are exactly 50ms apart the next frame and the key-up frame will have the exact same time.
  • buttonIndex will only be incremented when the difference between the current and last frame is greater than 0, effectively disabling alternating if the objects are <= 50ms apart.
  • As a fallback, when determining the button to use for a given frame, the generator examines the previous frame's pressed buttons, and make sure they don't use the same button. However, if the objects are >= 50ms apart the previous frame will be the key-up frame, which will have no active actions.

Basically, at exactly 50ms both mechanisms that ensure alternating don't work and the generated replay will put the key-down frame at the exact same time as the key-up frame and will use the exact same button as for the previous object. Without frame stability (i.e. in the editor) the key-up frame will always be skipped.

image

As far as I can tell there's 3 (relatively simple) ways to fix this:

  • Make sure the key-up frame is always before the next hitobject's start time (Diff)
  • Make sure buttons also alternate if difference to last frame is 0 (this pr)
  • Make sure previous frame actually starts before the curent frame's time when checking the previously pressed buttons (Diff)

I opted with the second fix because there's another bug in the same method that should also be fixed:

This statement has the same issue. It's purpose is to interpolate the previouss frame's position if it is too close to the current frame, except it won't get interpolated when the difference is 0. This leads to the cursor teleporting to the object at it's start time:

2026-01-05.03-08-05.mov

A better long-term solution would probably to simplify the autoplay generator so it doesn't take several hours of debugging to figure out what half of the code in it actually does but that's for another time.

Before:

2026-01-05.03-01-05.mov
2026-01-05.03-06-19.mov

After:

2026-01-05.03-00-55.mov
2026-01-05.03-07-16.mov

…is exactly zero.

Previously, there if two consecutive hitobjects were 50ms apart both mechanisms to make sure that the input buttons are alternated would fail.
This produced a replay frame which lifts the current button, followed by a frame which presses the same button again, at the same time as it was lifted.
The key-up frame would always get skipped without frame-stability, leading to hitsounds and hit animations not getting played in the editor.
@peppy
Copy link
Copy Markdown
Member

peppy commented Jan 5, 2026

A better long-term solution would probably to simplify the autoplay generator so it doesn't take several hours of debugging to figure out what half of the code in it actually does but that's for another time.

This was attempted at least once before by someone, but from recollection it read even worse 😅

@peppy peppy self-requested a review January 5, 2026 03:28
@pull-request-size pull-request-size bot added size/M and removed size/XS labels Jan 5, 2026
@peppy peppy enabled auto-merge January 5, 2026 04:19
@peppy peppy added area:editor and removed size/M labels Jan 5, 2026
@peppy peppy disabled auto-merge January 5, 2026 05:54
@peppy peppy merged commit 5839209 into ppy:master Jan 5, 2026
6 of 9 checks passed
@minetoblend minetoblend deleted the fix-editor-broken-for-spartans branch February 1, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants