Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add the Fade-In effect to DrawableSwell #31722

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

t0nik
Copy link

@t0nik t0nik commented Jan 29, 2025

partially fixes #21769

Theory: Fade-in effect in stable
The fade-in effect affects both swells and drumroll tails. Fade-in effect happens a set amount of ms before the object collides with the judgement cirlce. It will be called visible time in this PR.

Time analysis: Swell and drumroll tail fade-in effect
Footage
Footage analysis notes

Visible time was roughly estimated to be 1800ms for swells and 1700ms for drumroll tails.
The time between 0% and 100% opacity of an affected object was estimated to be 666ms for swells and 1700ms for drumroll tails.
Footage analysis also confirmed that DT decreases the fade-in effect time by 33%, and that the time is independent of the control points BPM.

Lazer: Implementation

  • Swells: Start increasing the opacity for the duration of 666ms, when the object is 1833ms (+33ms after comparison review) away from it's starting point.

  • Drumroll tails: Not implemented. Not sure how to separate the drumroll head from the tail in the DrawableDrumRoll. Also, it would likely break the argon and triangles drumroll object, since both skins don't contain a drumroll head.

Lazer: Comparison to stable
This is how lazer compares to stable in the current PR.

lazer-stable-comp.mp4

@peppy peppy self-requested a review January 29, 2025 08:22
@bdach
Copy link
Collaborator

bdach commented Jan 29, 2025

I'm just gonna bring this up: Previously.

Not willing to get involved in discussing this further until someone else is. Applying the fade to swells only is an option, but on stable all taiko objects fade in.

@peppy
Copy link
Member

peppy commented Jan 29, 2025

@t0nik can you make the same comparison video for hitobjects as a starting point? then we can figure whether this needs to be applied to more than just spinners/swells.

@peppy peppy removed their request for review January 29, 2025 08:52
@t0nik
Copy link
Author

t0nik commented Jan 29, 2025

Lazer: HitObject comparison with stable

lazer-stable-hitcircle-comp.mp4

Low SV Fade-In isn't an issue, since HitObjects in stable have enough time to Fade-In when rendered offscreen. When increasing the SV to extremely high values, the Fade-In effect starts to appear in the playfield. In lazer, HitObjects are visible at all times.

Extreme high SV Fade-In effect is used in gimmick maps mostly, here's an example:

lazer-stable-gimmick-comp.mp4

In osu!lazer, the circles show up on the playfield for a brief moment, which may be distracting to the player.

Referring to this discussion, I stand with the 16:9 aspect ratio lock (It eliminates the widescreen aspect ratio abuse, where a player can see more objects at once) and the full HitObject opacity on high SV, unless it's extremely high for gimmick mechanic use cases.

@bdach
Copy link
Collaborator

bdach commented Jan 30, 2025

I stand with the 16:9 aspect ratio lock (It eliminates the widescreen aspect ratio abuse, where a player can see more objects at once) and the full HitObject opacity on high SV, unless it's extremely high for gimmick mechanic use cases.

I don't understand what you're trying to say here and I'd rather keep out of the aspect ratio discussions because this aspect ratio stuff has been prosecuted several times over the years and I'm still none the wiser as to how people want aspect ratio to behave on lazer, maybe other than "make like stable" which is (a) stupid (read: stupidly convoluted), (b) halfway where we are already, and (c) in full literally impossible because lazer allows configurations that stable literally cannot / does not support (see having an actual windowed mode where you can resize the window to freakishly thin / tall sizes).

I'd ask to stick with the fade-in portion of this because otherwise we're going to get even more stuck in the details than we already probably will.

In osu!lazer, the circles show up on the playfield for a brief moment, which may be distracting to the player.

  • Are you sure this is actually caused by the fade-in of the objects?
  • And if you are, then surely we want the fade-in to be applied, no?
  • And if we do want the fade-in, then it should not be applied "only to high SV gimmick maps" or whatever, but universally.

@peppy
Copy link
Member

peppy commented Jan 30, 2025

My thought here was also to keep all aspect ratio discussion out of this thread. If that starts to go in the same direction as that other PR it's not going to be easy to merge.

In osu!lazer, the circles show up on the playfield for a brief moment, which may be distracting to the player.

This would be fixed by applying the fade to them as well, rather than just swells, correct?

@t0nik
Copy link
Author

t0nik commented Jan 30, 2025

Are you sure this is actually caused by the fade-in of the objects?

Yes, 100% sure. Increasing the Slider Velocity makes the objects less visible - they don't have enough time to fully fade in before appearing on the playfield. Gimmick maps take the SV increase to extreme values and thus reduce the visibility of circles to infinitesimal values.

And if you are, then surely we want the fade-in to be applied, no?

Yes, applying fade-in is a good idea. Not rendering the HitObjects above a certain BPM*SV factor e.g. 5000 might also work.

And if we do want the fade-in, then it should not be applied "only to high SV gimmick maps" or whatever, but universally.

As far as i know, the HitObject fade-in doesn't have an use outside of gimmick mechanics. When applied universally, it shouldn't affect maps in the playable bpm range eg. <500BPM 1.0x SV. In stable, the fade-in effect starts to be barely noticeable in the playfield around 400 BPM, 1.0x SV Nomod.

This would be fixed by applying the fade to them as well, rather than just swells, correct?

Correct. Please note, that the Swells and the HitObjects require different fade-in time values. Swells need to fade-in briefly before crossing the starting point. HitObjects need to fade-in at the beginning of their's lifetime.

@bdach
Copy link
Collaborator

bdach commented Jan 31, 2025

I'd say this PR should be applying fade in to the normal objects too and not only the swells, to get this issue out of the way for good.

@t0nik
Copy link
Author

t0nik commented Feb 1, 2025

Added DrawableHit fade-in. How it looks compared with stable:

lazer-stable-fadein-hit.mp4

The effect doesn't match stable that well and the last sequence of circles is invisible in lazer. That is caused by the HitObject.StartTime - LifetimeStart 90 ms limit. In lazer, the circles become invisible around 2500BPM 1.0x SV, in stable the value is closer to 15000BPM 1.0x SV. Both scroll speeds are not possible to sightread and are mostly used in gimmick mechanics.

With the current PR, there are some visual bugs in the editor related to the object opacity on any extremely high scroll speed parts:

  • Opacity isn't updating when changing the state of "Show speed changes" button
  • When placing an object in the editor, it remains visible until testing a map or saving and opening the map in the editor again.

Other beatmaps in which DrawableHit fade-in was tested:

@pull-request-size pull-request-size bot added size/M and removed size/S labels Feb 1, 2025
@t0nik
Copy link
Author

t0nik commented Feb 8, 2025

Feel free to take over the DrawableHit fade-in feature as I'm not competent enough to develop this. I would still like DrawableSwell fade-in feature to be checked and merged, it will improve the gameplay on maps with ultra low SV spinners drastically.

@bdach bdach self-requested a review February 11, 2025 09:09
@bdach
Copy link
Collaborator

bdach commented Feb 11, 2025

So... a few things...

Even if I focus on the "swell fade-in" part of this PR, it immediately fails cross-check with stable. I made a beatmap to test this on: swell fadein test - swell fadein test.osz.zip

and this happens on it:

Untitled10.mp4

Hopefully it's self-evident what the problem is.


On the flipside, stable logic for swell fade-in is completely terrible. The relevant transform here is

                WarningIcon.Transformations.Add(
                    new Transformation(TransformationType.Fade, 0, 1, startTime - hitObjectManager.PreEmpt,
                                           startTime - (int)(hitObjectManager.PreEmpt * 0.6)));

(ref)

where

            PreEmpt = (int)Math.Min(5000, (600 / SliderVelocityAt((int)(Beatmap.ControlPoints.FirstOrDefault()?.Offset ?? 0)) / 0.6f * 1000)); // bug bug bug bug

(ref) (also enjoy the // bug bug bug bug with zero elaboration as to what the bug is)

where

        public override double SliderVelocityAt(int time)
        {
            double beatLength = Beatmap.BeatLengthAt(time);


            if (beatLength > 0)
                return
                    (SliderScoringPointDistance * Beatmap.DifficultySliderTickRate *
                     (1000F / beatLength));
            return SliderScoringPointDistance * Beatmap.DifficultySliderTickRate;
        }

(ref)

where

            SliderScoringPointDistance =
                ((100 * Beatmap.DifficultySliderMultiplier) /
                    Beatmap.DifficultySliderTickRate);

(ref)

As far as I can tell the hit fade-in logic is extremely similar to this.

Do we wanna be porting any of this? Dunno. I'd say it's a @ppy/team-client sort of question, but nobody has given me as much as an attempt of an answer in many tries across many years now.

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.

as above

@t0nik
Copy link
Author

t0nik commented Feb 11, 2025

Further tests were performed on swell fadein test - swell fadein test.osz.zip:

swell-fade-in-further-tests.mp4

The video is divided into 3 parts:

  • 00:00 - 00:15 - Difference between fade-in behavior when the First Control Point SV is set to various values.
  • 00:15 - 00:31 - Replicating the fade-in behavior of this PR, by setting the value of the First Control Point SV to 1.41x. (Which corresponds to 170BPM 1.0x, where I've performed the initial tests)
  • 00:31 - 01:03 - Setting the First Control Point SV to extreme values.

Thanks to the aforementioned code fragments and tests I've concluded that, on stable:

  1. The swell fade-in behavior is only affected by the DifficultySliderMultiplier of the beatmap (usually is 1.4) and slider velocity multiplier at the First Control Point of the beatmap.
  2. When SliderVelocityAt at the First Control Point is equal or less than 200 (BPM equal or less than 85.7 with default SliderMultiplier values):
    • The maximum fade-in duration is 2000ms.
      • Considering that PreEmpt is assigned to Math.Min(5000, ..., PreEmpt - PreEmpt * 0.6 == 5000 - 3000 == 2000
    • The maximum visible time is 5000ms (time elapsed from the moment the object begins to fade-in until the object crosses the starting point)
      • PreEmpt is the visible time.
  3. When the value of SliderVelocityAt at the First Control Point increases to sufficiently high values:
    • The minimum fade-in duration converges to 0ms.
    • The minimum visible time converges to 0ms.
      • Also seen on the footage (0:33, 10000BPM 10.0x SV @ First Control Point)

Do we wanna be porting any of this?

While this behavior is rather chaotic due to the First Control Point SV dependence, I would propose sticking to a constant value for both visible time and fade-in duration in lazer e.g. taking the mean of the limits: (2000f - 0) / 2 for fade_in_duration and (5000f - 0) / 2 for fade_in_offset. Doing so, will improve the gameplay quality on maps with ultra low SV swells, without introducing any inconsistent behaviors.

Another proposition would be to modify the swell fade-in times depending on the SV which is currently affecting the object, instead of the First Control Point's SV. Apart from improving the gameplay quality, it will enable mappers to create 'surprise' swells that show up not until they cross the starting point.

Not making any changes until it's clear what should be implemented here.

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Very slow osu!taiko spinners should fade in near the receptor
3 participants