1091 Commits

Author SHA1 Message Date
e6a6352a9c sync with master fully 2025-12-16 19:39:40 +03:00
86f0159e65 adjust some CI settings 2025-12-15 20:32:33 +03:00
ae5a64ba81 fix most failing test cases 2025-12-15 20:29:31 +03:00
e3a7ae30cd prevent an exception if icon is broken (probably) 2025-12-13 22:41:23 +03:00
b6f845d99c slightly change score panels and mod icons 2025-12-13 02:41:05 +03:00
a1d6bda63e hide online status if no map is actually selected (ssv1/v2) 2025-12-12 00:06:05 +03:00
547d22a4b5 update some URLs to match instance, fix potential mp crash 2025-12-11 23:57:01 +03:00
b4c530ac04 add a very safe check for IApplicableFailExit mods 2025-12-09 23:59:35 +03:00
5af05d2479 show a message if we successfully migrate db to new place 2025-12-09 23:52:57 +03:00
43ab18ffea hide quit+replay button in most cases where replay can't be saved 2025-12-09 23:15:25 +03:00
9f59259a40 update volume meter design a bit more 2025-12-09 22:45:15 +03:00
82b3015fcc and again? 2025-12-09 21:35:24 +03:00
68f92ab57c messed things up again 2025-12-09 20:24:09 +03:00
d76d4d9a35 okay, i messed things up 2025-12-09 20:20:07 +03:00
Bartłomiej Dach
bb7417c099 Filter out more exceptions from being sent to sentry
More or less covers the first page of client sentry issues sorted by
volume, all of which is pretty much useless for anything because it's
client-specific-failure noise.
2025-12-09 20:19:16 +03:00
Dan Balasescu
066e093987 Adjust vote-to-skip to be explicit about states 2025-12-09 20:19:16 +03:00
Dan Balasescu
56e0c3e65d Fix potentially unsafe quick play event handling 2025-12-09 20:19:16 +03:00
Natelytle
89d7726903 Rank swap mod 2025-12-09 20:19:16 +03:00
Dan Balasescu
36f1bfef07 Fix incorrect quick play download progress 2025-12-09 20:19:15 +03:00
Dan Balasescu
118f07878a Allow score panel to animate 2025-12-09 20:19:15 +03:00
Dan Balasescu
e144968893 Remove quick play round results scroll animation 2025-12-09 20:19:15 +03:00
Dan Balasescu
d2ffea41c6 Consider abandon time for user placements 2025-12-09 20:19:15 +03:00
Dan Balasescu
a8be9b1381 Make quick play chat retain focus after posting 2025-12-09 20:19:15 +03:00
Dean Herbert
42b184f167 Update framework 2025-12-09 19:20:29 +09:00
Dean Herbert
27737bd4e9 Merge pull request #35938 from bdach/less-sentry
Filter out more exceptions from being sent to sentry
2025-12-09 19:10:57 +09:00
Bartłomiej Dach
8bb885a0dc Filter out more exceptions from being sent to sentry
More or less covers the first page of client sentry issues sorted by
volume, all of which is pretty much useless for anything because it's
client-specific-failure noise.
2025-12-09 09:54:46 +01:00
Bartłomiej Dach
0b06acb29d Merge pull request #35909 from smoogipoo/fix-vote-to-skip
Adjust vote-to-skip messaging flow to be explicit about states
2025-12-09 08:59:53 +01:00
Bartłomiej Dach
b129837e57 Merge pull request #35918 from smoogipoo/qp-fix-unsafe-schedules
Fix potentially unsafe quick play event handling
2025-12-09 08:32:56 +01:00
Dean Herbert
3e221c7f61 Merge pull request #35906 from Natelytle/jank-tames-raiko
Rank the taiko swap mod
2025-12-09 15:57:02 +09:00
Dean Herbert
7106a6a5e5 Merge pull request #35897 from smoogipoo/qp-fix-download-progress
Fix incorrect quick play download progress
2025-12-09 15:53:15 +09:00
Dean Herbert
eaf2721f5b Merge pull request #35912 from smoogipoo/qp-remove-results-scroll
Remove quick play results scroll animation
2025-12-09 15:52:14 +09:00
490a6fd724 fix out of range exception in changelog overlay 2025-12-08 17:34:27 +03:00
Dean Herbert
59a27dad3d Merge pull request #35923 from smoogipoo/qp-abandoned-at
Consider abandon time for user placements
2025-12-08 19:27:56 +09:00
Dan Balasescu
d6cd748d2a Consider abandon time for user placements 2025-12-07 23:26:40 +09:00
237e1828f8 add option for playing miss sound on any combo break, make...
exit & restart game options in fail condition mods mutually exclusive
2025-12-07 13:14:38 +03:00
3413f722f7 make volume meter use argon counter (it looks cool) 2025-12-06 23:52:20 +03:00
9f779dac03 forgot to disable christmas intro after testing 2025-12-06 21:57:44 +03:00
0727c53cdc bump to 2025.12.05-lazer 2025-12-06 21:52:53 +03:00
a57ff24191 bump to 2025.1203.0-tachyon, add no intro option, slightly change seasonal bg code 2025-12-06 21:51:48 +03:00
Dan Balasescu
c23d6b7fd1 Fix potentially unsafe quick play event handling 2025-12-07 02:11:26 +09:00
Dean Herbert
582ff999aa Merge pull request #35913 from smoogipoo/qp-chat-hold-focus
Make quick play chat retain focus after posting
2025-12-06 20:20:42 +09:00
Dan Balasescu
a96b024ac5 Make quick play chat retain focus after posting 2025-12-06 17:50:58 +09:00
Dan Balasescu
1c10acba76 Allow score panel to animate 2025-12-06 17:40:17 +09:00
Dan Balasescu
4ae4c700ae Remove quick play round results scroll animation 2025-12-06 17:39:54 +09:00
Dan Balasescu
2be50d917a Adjust vote-to-skip to be explicit about states 2025-12-06 13:23:16 +09:00
Natelytle
35fdc6f8b9 Rank swap mod 2025-12-05 22:51:00 -05:00
Dan Balasescu
d04029bcc7 Fix incorrect quick play download progress 2025-12-06 03:24:17 +09:00
Dean Herbert
fbac5db964 Update framework 2025-12-05 22:28:55 +09:00
Dean Herbert
5a920d15c1 Merge pull request #35875 from bdach/always-bind-virtual-modifier
Do not distinguish between left/right modifiers when assigning new key combinations
2025-12-05 22:02:50 +09:00
Dean Herbert
324d088d46 Merge pull request #35878 from frenzibyte/vote-to-skip-design-2
Update multiplayer vote-to-skip button design
2025-12-05 21:40:16 +09:00
Dean Herbert
1db4b897eb Update tests to match new behaviour 2025-12-05 21:27:11 +09:00
Bartłomiej Dach
8e2230d149 Add xmldoc to confusing field
I don't have any better ideas at this time.
2025-12-05 13:05:51 +01:00
Dean Herbert
8d33c35646 Update framework 2025-12-05 20:50:07 +09:00
Dean Herbert
c359898a75 Merge pull request #35890 from bdach/disallow-placing-objects-before-first-timing-point
Disallow placing objects before first timing point
2025-12-05 20:49:44 +09:00
Bartłomiej Dach
6343bf7d29 Privatise setter 2025-12-05 12:35:26 +01:00
Bartłomiej Dach
b1e27d842b Ensure skip counter doesn't overflow the button 2025-12-05 12:34:18 +01:00
Bartłomiej Dach
28eeb7f743 Merge pull request #35889 from smoogipoo/fix-quick-play-kick-message
Fix "kicked" users not being marked as quit
2025-12-05 10:24:30 +01:00
Bartłomiej Dach
38c3167a9d Merge pull request #35888 from smoogipoo/fix-quick-play-crash
Fix quick play crash when presenting random selection
2025-12-05 09:54:20 +01:00
Bartłomiej Dach
66ebce8c12 Fix failing tests after disallowing object placements before first timing point 2025-12-05 09:52:32 +01:00
Dan Balasescu
fed9564b40 Fix "kicked" users not being marked as quit 2025-12-05 17:26:55 +09:00
Dan Balasescu
f595a47059 Fix quick play crash when presenting random selection 2025-12-05 16:59:23 +09:00
Dan Balasescu
8a9f60df68 Add failing test 2025-12-05 16:59:23 +09:00
Salman Alshamrani
2d8b1e7152 Make button brighter on hover 2025-12-04 14:00:39 -05:00
Salman Alshamrani
fef8117b5c Add test coverage for players leaving during intro 2025-12-04 13:38:30 -05:00
Salman Alshamrani
99da986e02 Implement redesigned multiplayer vote-to-skip button 2025-12-04 13:38:30 -05:00
Salman Alshamrani
1c33291b3f Adjust skip button colour and add triangles 2025-12-04 13:38:30 -05:00
Bartłomiej Dach
c6cc92315c Add basic colour indication as to when placements are valid
Unsure about this one, but I find the preceding commit to be very
lacking in explaining to the user why the editor don't work. Shining
some things red may help aid understanding.
2025-12-04 14:37:56 +01:00
Bartłomiej Dach
12170df80a Disallow placing hit objects before first timing point
Because they can break stable. See
https://github.com/ppy/osu/issues/31591#issuecomment-3575270120 for
detailed rationale.
2025-12-04 14:15:52 +01:00
Bartłomiej Dach
3e4c038a37 Do not distinguish between left/right modifiers when assigning new key combinations
Addresses https://github.com/ppy/osu/discussions/35851.

And no I'm not making it "you have to press both modifiers for it to
become any of the two" because that's ultra weird.
2025-12-04 12:09:27 +01:00
Dean Herbert
5d76353ae4 Merge pull request #35874 from bdach/fix-skinnable-welcome
Fix welcome intro text not being looked up from user skin for supporters
2025-12-04 19:36:11 +09:00
Bartłomiej Dach
0b3ec3f1e1 Fix changing beatmap during hold-to-reveal-background delay turning off blur (#35867)
Closes https://github.com/ppy/osu/issues/35864.
2025-12-04 19:23:32 +09:00
Bartłomiej Dach
043a1c2793 Disable quick retry binding in solo spectator (#35873)
Closes https://github.com/ppy/osu/issues/35870? For some definition of
"closes", I guess?

Why would you ever do this, unless on purpose just to break stuff? Don't
answer that.

A side effect of setting this flag is that the hold-to-exit menu button
that's there on devices that support touch will slightly change
behaviour to the behaviour multiplayer play has:

	e3ea38a366/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs (L67)
	8d9245c1d4/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs (L79-L82)

but upon thinking about it for three minutes I decided I don't care and
it's probably fine because all of this was already racking up to fifteen
minutes that I shouldn't have had to spend on any of this.

Notably this shouldn't affect the actual spectated user retrying,
because all of that is handled elsewhere via

	2f90bb4d67/osu.Game/Screens/Spectate/SpectatorScreen.cs (L138-L154)
2025-12-04 19:17:44 +09:00
Bartłomiej Dach
ca8247c667 Fix welcome intro skin not being looked up from user skin for supporters
Closes https://github.com/ppy/osu/issues/35833.
2025-12-04 10:43:18 +01:00
Bartłomiej Dach
a5ae542502 Merge pull request #35872 from peppy/locus-winners-part-2
Add remaining two locus winners as bundled beatmaps
2025-12-04 09:40:37 +01:00
Dean Herbert
fe5cbc4932 Add remaining two locus winners as bundled beatmaps 2025-12-04 14:20:04 +09:00
Bartłomiej Dach
0a378e5efd Merge pull request #35835 from Hiviexd/trim-timestamp-when-pasting
Trim editor timestamp when pasting into `TimeInfoContainer`
2025-12-03 14:56:52 +01:00
Dean Herbert
1d221c1a7a Merge pull request #35852 from frenzibyte/support-ipad-resizing
Allow window resizing on iPadOS
2025-12-03 13:11:19 +09:00
bdb3418b67 fix useless DB versioning in release builds
Idk why, but in my first commit here I just commented out the lines
restricting DB schema suffixes to debug builds only, and before all that
mess there was a "TODO: fix".
I'm only doing this for sake of tools like BeatmapExporter and to not
clog up disk space when newer schema versions arrive.
This should work well with existing installations (hopefully)
2025-12-02 20:15:00 +03:00
Salman Alshamrani
82f4406c79 Allow resizing osu! on iPadOS 2025-11-30 05:14:02 -05:00
Vanni
92e9a36744 Force exit to menu on quick play disonnection (#35793) 2025-11-28 11:25:43 +09:00
Hivie
c6eba26a67 trim timestamp when pasting into TimeInfoContainer 2025-11-28 01:40:07 +01:00
Bartłomiej Dach
8f927ea7b5 Fix Beatmap.GetMostCommonBeatLength() potentially returning a beat length smaller or larger than the actual limits (#35827)
Closes https://github.com/ppy/osu/issues/35807.

The reason this closes the aforementioned issue is as follows:

Taking https://osu.ppy.sh/beatmapsets/1236180#osu/4650477 as the
example, we have:

```
minBeatLength = 342.857142857143
maxBeatLength = 419.58041958042003
mostCommonBeatLength = 342.85700000000003
```

Note that `mostCommonBeatLength < minBeatLength` here.

Taking the inverse of that to compute BPM, we get

```
minBpm = 174.99999999999991
maxBpm = 142.99999999999986
mostCommonBpm = 175.00007291669704
```

which without DT present doesn't do anything bad, but when DT is
engaged (and thus BPM is multiplied by 1.5), midpoint rounding causes
the min BPM to become 262, and the most common BPM to become 263.
2025-11-28 08:25:47 +09:00
Bartłomiej Dach
a8f058141b Fix several issues with editor timestamps for objects with fractional start times in osu!mania (#35829)
* Fix mania editor timestamp generation being culture-dependent

Mostly closes https://github.com/ppy/osu/issues/35809.

* Add failing test for notes with fractions

* Round note time when copying out timestamp & apply half-millisecond tolerance when parsing

Closes the rest of https://github.com/ppy/osu/issues/35809.

One issue here was that while the timestamp generation would allow
fractional object timestamps to be output, the parsing (via
`selection_regex`) would *reject* fractional timestamps, therefore
making lazer incompatible even with itself.

The other is that rounding is probably fine to do anyway for
interoperability with stable. I'd hope nobody actually *needs*
sub-millisecond precision but I'm ready to be proven wrong by some
aspire jokester.

* Specify invariant culture when writing out combo indices to editor timestamp in other rulesets

Pretty sure this is just a much-of-muchness because it's integers but
might as well if I'm spending time here already.
2025-11-28 08:21:13 +09:00
Bartłomiej Dach
6bb25b2abe Fix gameplay leaderboard tracked player not using team colour (#35826)
* Demonstrate colour problem in test

* Fix gameplay leaderboard tracked player not using team colour

Closes https://github.com/ppy/osu/issues/35806.
2025-11-27 21:22:06 +09:00
Bartłomiej Dach
037743e002 Add context menu shortcut to watch local replays from song select (#35823)
Addresses https://github.com/ppy/osu/discussions/35811 I guess.

Will only work for local leaderboards for now but maybe good enough for
what is essentially a 5 minute job?

Can be made to work with online leaderboards too I guess if need be.
2025-11-27 21:10:46 +09:00
Bartłomiej Dach
6244617e5e Attempt to prevent main menu osu! logo being triggered by media keys (#35825)
Maybe addresses https://github.com/ppy/osu/discussions/35813. I can't
reproduce on macOS, may be a $USER_OS idiosyncrasy.
2025-11-27 20:58:47 +09:00
Bartłomiej Dach
ddfcb4d6da Merge pull request #35821 from smoogipoo/qp-adjust-pool-selector
Display quick play pool name as sub-heading in selector
2025-11-27 12:16:02 +01:00
Bartłomiej Dach
2660f4dcb0 Merge pull request #35822 from smoogipoo/remove-unnecessary-code
Remove now-unnecessary timestamp updates
2025-11-27 12:15:38 +01:00
Dan Balasescu
5a865476ce Remove now-unnecessary timestamp updates
Since #35820, this is now handled when messages are added and removed.
2025-11-27 18:42:48 +09:00
Bartłomiej Dach
2472c91924 Merge pull request #35820 from smoogipoo/fix-chat-background-alt-2
Fix chat lines flipping colours at maximum history
2025-11-27 10:37:52 +01:00
Dan Balasescu
db50019f31 Display quick play pool name as sub-heading 2025-11-27 18:25:32 +09:00
Bartłomiej Dach
1e43509e4a Fix formatting 2025-11-27 09:37:40 +01:00
Dan Balasescu
ded8aaecfd Fix chat lines flipping colours at maximum history 2025-11-27 15:42:47 +09:00
Dan Balasescu
75df8e3639 Add failing tests 2025-11-27 15:42:40 +09:00
maarvin
0d9a50e839 Quickplay: Update top level layout to match designs (#35791)
* Adjust top level matchmaking screen layout

* Adjust colours in StageDisplay

* Fix flipped animation in StageDisplay

* Adjust colours in CurrentRoundDisplay

* Fade out stage segments as they approach the left screen border

* Remove redundant `OfType<T>()` call

* Soften banner shadow

Co-authored-by: marvin <minetoblend@gmail.com>

---------

Co-authored-by: Dan Balasescu <smoogipoo@smgi.me>
2025-11-26 22:11:40 +09:00
Bartłomiej Dach
7473c62949 Merge pull request #35803 from peppy/show-self-in-online-users
Show self in online users list
2025-11-25 13:05:35 +01:00
Bartłomiej Dach
8d30e3d852 Merge pull request #35800 from peppy/fix-audio-dim-results
Fix quick retry/exit overlay volume dimming potentially sticking at results
2025-11-25 12:57:51 +01:00
Bartłomiej Dach
97fdc89fe3 Merge pull request #35804 from Hiviexd/verify/update-taiko-drain-thresholds
Update drain thresholds in osu!taiko verify check
2025-11-25 10:59:38 +01:00
Dean Herbert
f6a6c9f885 Fix failing test 2025-11-25 18:48:03 +09:00
Hiviexd
26c50b874c update osu!taiko drain thresholds
see change in 25169ccbe6
2025-11-25 09:31:41 +01:00
Bartłomiej Dach
83706b7fb6 Merge pull request #35771 from Joehuu/fix-copy-toast-not-showing
Fix some copy link actions/buttons not showing copied toast
2025-11-25 08:50:46 +01:00
Bartłomiej Dach
9e3486d4e6 Merge pull request #35757 from peppy/settings-wank
Adjust settings buttons and general section to feel better
2025-11-25 08:46:00 +01:00
Dean Herbert
545b13c3fb Show self in online users
I don't see a reason to hide self. I kinda expect to be able to see that
I'm online.
2025-11-25 16:45:52 +09:00
Dean Herbert
2c9fc32756 Assert that player suspension is final 2025-11-25 16:39:39 +09:00
Bartłomiej Dach
0786e619f1 Leave note about lack of toast for posterity 2025-11-25 07:52:38 +01:00
Dean Herbert
c968981697 Fix quick retry/exit overlay volume dimming potentially sticking at results
Closes #35737.
2025-11-25 15:51:47 +09:00
Bartłomiej Dach
45567f19b7 Fix test not compiling 2025-11-25 07:46:29 +01:00
Dean Herbert
f0f4e7c7a5 Update resources 2025-11-25 14:50:25 +09:00
Joseph Madamba
1d353ef637 Revert showing toast on editor timestamp clipboard 2025-11-24 11:06:01 -08:00
Dean Herbert
52af905237 Hide full installation section on non-desktop platforms 2025-11-25 01:06:29 +09:00
Dean Herbert
64668eafb9 Adjust some more visual metrics to feel better 2025-11-25 01:05:31 +09:00
Dean Herbert
b0762fc8ec Reduce abstractions of rounded button 2025-11-25 00:55:42 +09:00
Dean Herbert
d59e9572d2 Add missing padding around countdown settings button 2025-11-25 00:55:22 +09:00
Bartłomiej Dach
098da946e1 Merge pull request #35763 from stanriders/real-map-difficulty-settings
Use actual mod-adjusted map difficulty settings in the `SongBar`
2025-11-24 14:48:44 +01:00
Dean Herbert
510fc506fb Merge pull request #35786 from bdach/bypass-debounce-local-lbs
Bypass 300ms debounce when requesting local leaderboards in song select
2025-11-24 22:29:33 +09:00
Dean Herbert
da09ad9c46 Merge pull request #35785 from bdach/everybody-be-hover-fighting
Fix hover fighting when a `SettingsToolboxGroup`'s child handles hover
2025-11-24 22:29:00 +09:00
Dean Herbert
aaff7d358f Merge pull request #35787 from bdach/revert-group-expansion
Revert "Expand group that current selection resides in when moving mouse to left side of song select"
2025-11-24 21:59:13 +09:00
Bartłomiej Dach
a69b2cd803 Revert "Expand group that current selection resides in when moving mouse to left side of song select"
Reverts https://github.com/ppy/osu/pull/35184 as per
https://github.com/ppy/osu/discussions/35683#discussioncomment-15034835.
2025-11-24 13:38:53 +01:00
Bartłomiej Dach
855d5dba3c Bypass 300ms debounce when requesting local leaderboards in song select
RFC. Would probably close https://github.com/ppy/osu/issues/35773.
2025-11-24 13:20:39 +01:00
Bartłomiej Dach
9c981a52f8 Fix test failures
This is dodgy as hell but `ShortName` is completely derived from
`OnlineID` anyway so there should be no valid reason to ever attempt to
serialise it anyway.
2025-11-24 12:52:57 +01:00
Bartłomiej Dach
96de47ac4f Fix hover fighting when a SettingsToolboxGroup's child handles hover
Addresses https://github.com/ppy/osu/discussions/35772.
2025-11-24 12:46:30 +01:00
Dean Herbert
43834b55f2 Merge pull request #35784 from bdach/purge-private-channels-on-user-change
Clear chat state when local user changes
2025-11-24 20:28:29 +09:00
Arpa
8fb402665e Merge pull request #35698 from ArpaDeveloper/master
Fix editor test play autoplay / quick play toggles being usable while pause or resume overlays were showing
2025-11-24 12:08:50 +01:00
Bartłomiej Dach
e4975e8d3b Remove unnecessary cast 2025-11-24 12:00:33 +01:00
Dean Herbert
dbd9f13f2d Merge pull request #35783 from bdach/form-slider-bar-double-click-to-reset
Add double-click-nub-to-reset function to form slider bars
2025-11-24 19:54:33 +09:00
Bartłomiej Dach
ec890cd459 Clear chat state when local user changes
Closes https://github.com/ppy/osu/issues/35081.
2025-11-24 11:41:52 +01:00
Bartłomiej Dach
33c8c4d639 Add failing test 2025-11-24 11:33:24 +01:00
StanR
83ce56b718 Use APIRuleset instead of a blank RulesetInfo 2025-11-24 15:11:47 +05:00
Bartłomiej Dach
9d88c761d3 Add double-click-nub-to-reset function to form slider bars
See https://github.com/ppy/osu/pull/35742#issuecomment-3561517030.
2025-11-24 10:32:42 +01:00
Joseph Madamba
49eb013967 Fix some copy link actions/buttons not showing copied toast 2025-11-22 17:13:52 -08:00
Joseph Madamba
b6ccc8cae4 Replace local osd and clipboard method with existing game method 2025-11-22 17:13:52 -08:00
Joseph Madamba
d0e09e5b5c Fix one remaining case of "copy link" not using existing localisation 2025-11-22 17:04:40 -08:00
StanR
8900c79758 Set TournamentBeatmap's IBeatmapInfo.Ruleset to a dummy ruleset.
This is being queried by the https://github.com/ppy/osu/blob/master/osu.Game.Rulesets.Mania/ManiaRuleset.cs#L442 but since we don't actually draw column count anywhere nor are we supposed to be running converts in tournaments it should be safe to populate it with nothing.
2025-11-22 03:35:10 +05:00
StanR
fd652982ce Add ruleset tests 2025-11-22 03:29:39 +05:00
StanR
a2bfb409d2 Use actual mod-adjusted map difficulty settings in the SongBar 2025-11-22 03:16:36 +05:00
936640edeb update some configs for iOS 2025-11-21 19:04:31 +03:00
1187d03333 prepare repo for github ci/cd (mostly) 2025-11-21 18:59:41 +03:00
Dean Herbert
26da75ecfb Merge pull request #35704 from minetoblend/feature/quickplay-random-panel-design-pass 2025-11-21 23:18:11 +09:00
Dean Herbert
9f8554cc13 Merge branch 'master' into feature/quickplay-random-panel-design-pass 2025-11-21 21:51:31 +09:00
Dean Herbert
713b6453c0 Merge pull request #35758 from peppy/update-framework
Update framework
2025-11-21 21:42:53 +09:00
Bartłomiej Dach
1b3ac49f2a Merge branch 'cursor-path-smooth' into update-framework 2025-11-21 12:44:19 +01:00
Dean Herbert
d8b71423b0 Update framework 2025-11-21 19:33:38 +09:00
Dean Herbert
2c40e116e1 Merge pull request #35751 from bdach/seek-differently
Debounce continuous track seeks to at most one every 200ms
2025-11-21 17:59:57 +09:00
marvin
90e7faf271 Replace PowEasingFunction with CubicBezieEasingFunction 2025-11-21 09:57:14 +01:00
Dean Herbert
fc74726d11 Ensure the skip overlay shows when someone votes to skip 2025-11-21 17:25:40 +09:00
Bartłomiej Dach
5d3997152a Merge pull request #35755 from smoogipoo/qp-fix-expired-items
Fix quick play showing expired playlist items
2025-11-21 09:25:37 +01:00
Dean Herbert
41b56971e5 Merge pull request #35350 from Loreos7/rename-delete-button
Restore original `delete` button name
2025-11-21 17:14:37 +09:00
Dean Herbert
98e7a10e1e Rename localised string 2025-11-21 17:13:44 +09:00
Dean Herbert
e99b9984d0 Merge branch 'master' into rename-delete-button 2025-11-21 17:11:24 +09:00
Dean Herbert
38504fed22 Merge pull request #35754 from minetoblend/feature/matchmaking-bg
Quickplay: Update background image to match designs
2025-11-21 17:07:38 +09:00
Dean Herbert
13dab24d41 Adjust to 200 ms debounce
This [matches
stable](52f3f75ed7/osu!/Audio/AudioEngine.cs#L1295)
and feels somewhat better.
2025-11-21 16:56:58 +09:00
Bartłomiej Dach
67530b39cf Merge pull request #35750 from bdach/created-filter
Add `created` alias for `submitted` song select filter
2025-11-21 08:46:55 +01:00
Dean Herbert
19f5e5ba7c Merge pull request #35742 from bdach/eternal-war-against-sliders
Use new sliders-with-text-input in editor toolboxes
2025-11-21 16:46:06 +09:00
Dean Herbert
56ce955e0c Move export logs to quick actions (to sit with report issue button) 2025-11-21 16:40:38 +09:00
Dean Herbert
73349ab182 Move quick actions to top 2025-11-21 16:35:10 +09:00
Dean Herbert
a6a98fc078 Only show update settings if the game can be updated 2025-11-21 16:35:09 +09:00
Dean Herbert
a8594f1c08 Move installation settings into own subsection 2025-11-21 16:35:09 +09:00
Dan Balasescu
d3860f1630 Fix quick play showing expired playlist items 2025-11-21 16:27:48 +09:00
Dan Balasescu
15ee49348d Add failing test 2025-11-21 16:27:48 +09:00
Dean Herbert
908a950cd2 Move quick action settings into own subsection 2025-11-21 16:25:04 +09:00
Dean Herbert
df79269e6f Adjust tablet settings layout to feel a touch nicer 2025-11-21 16:24:10 +09:00
Dean Herbert
34146b8bcb Update rounded button to be less rounded
Intended to match the rest of the UI which is less rounded these days.
See inline comment for reason for not matching `FormControl` corner
radius just yet.
2025-11-21 16:23:53 +09:00
Dean Herbert
08ed2844b4 Merge pull request #35673 from bdach/report-issue-button
Add "Report an issue" button to general settings
2025-11-21 15:55:17 +09:00
Dan Balasescu
871c0ebe3d Rename to GameplayItem + adjust documentation 2025-11-21 15:34:58 +09:00
marvin
6362cdb675 Replace MatchmakingRoomState.CandidateType with MatchmakingRoomState.FinalItem 2025-11-21 15:34:41 +09:00
Dean Herbert
8e78f4dac4 Adjust button colour and don't show warning 2025-11-21 15:33:14 +09:00
Dean Herbert
fa8d303922 Update framework 2025-11-21 14:54:25 +09:00
Dean Herbert
d465bee0ab Merge pull request #31057 from rikimasan/rikimasan/rank-alternate-mod
Rank the Alternate and Single Tap mods
2025-11-21 14:19:42 +09:00
Dean Herbert
721ba8aeba Merge branch 'master' into rikimasan/rank-alternate-mod 2025-11-21 14:00:18 +09:00
Dean Herbert
1dd026c0f0 Fix everything crashing 2025-11-21 13:58:21 +09:00
Dean Herbert
a873f2be65 Merge pull request #35740 from bdach/dont-nuke-all-channels-in-tourney-client
Avoid nuking logged in user's joined channels on showing match chat in tournament client
2025-11-21 10:20:47 +09:00
marvin
edf7a126c8 Use single drawable for background 2025-11-21 01:32:11 +01:00
Bartłomiej Dach
f0f33b6df4 Adjust precisions to be less weird
In a perfect world you could specify different precisions for the slider
and the text box but let's start here and see if we get complaints
first.
2025-11-20 12:36:05 +01:00
Bartłomiej Dach
6052ed790d Debounce continuous track seeks to at most one every 500ms
See https://github.com/ppy/osu/pull/35677#issuecomment-3555903209.
2025-11-20 12:23:31 +01:00
Marvin Schürz
107c481fb9 Use new background in all matchmaking test scenes 2025-11-20 12:03:42 +01:00
Marvin Schürz
aba567d258 Add background screen 2025-11-20 12:01:27 +01:00
Bartłomiej Dach
094454499c Add created alias for submitted song select filter
Symmetrical change to https://github.com/ppy/osu-web/pull/12561 (can
probably wait until that one is reviewed to be legitimate).
2025-11-20 11:51:28 +01:00
Dean Herbert
c7e1a5770d Adjust code structure slightly to simplify logic 2025-11-20 18:22:16 +09:00
Dean Herbert
a8ac82aa1f Fix test failure due to channel not being joined 2025-11-20 18:19:30 +09:00
Bartłomiej Dach
47faf774b0 Fix tests 2025-11-20 10:12:43 +01:00
Bartłomiej Dach
be77257ddb Do not overwrite website state of 'hide online presence' toggle (#35741)
Closes https://github.com/ppy/osu/issues/35735.
2025-11-20 11:10:12 +09:00
Bartłomiej Dach
397041099e Adjust element spacing in editor toolboxes 2025-11-19 13:38:34 +01:00
Bartłomiej Dach
4b59a4657f Use new sliders-with-text-input in editor toolboxes
Addresses https://github.com/ppy/osu/discussions/35732.

And yes, I renamed "perfect curve threshold" to "bias" so that the text
can fit. Sue me.
2025-11-19 13:22:20 +01:00
marvin
02090bf6c4 Resolve candidateItem in RollAndDisplayFinalBeatmap instead of PresentRolledBeatmap 2025-11-19 13:15:53 +01:00
3bd996ee43 synchronize with github (tag 2025.1119.0-tachyon) 2025-11-19 15:13:25 +03:00
37b9f91d42 make discord rich presence work 2025-11-19 14:03:57 +03:00
Bartłomiej Dach
603c77e3e9 Avoid nuking logged in user's joined channels on showing match chat in tournament client
Closes https://github.com/ppy/osu/issues/35721.

I worry that straight up removing the nuke and not adding any channel
leave calls in exchange is going to leave tourney client users
with the *inverse* problem of being joined into a gorillion channels
from multiplayer matches they broadcasted, so this attempts to strike a
reasonable balance.
2025-11-19 11:50:02 +01:00
Bartłomiej Dach
f284864f96 Merge pull request #35691 from Kawaritai/fix/window-sizing-dropdown
Add window sizes in dropdown menu options
2025-11-19 10:55:24 +01:00
1a5a5606dc don't log that we're running an unofficial build 2025-11-19 12:02:27 +03:00
Bartłomiej Dach
fa1bf7bd96 Merge branch 'master' into fix/window-sizing-dropdown 2025-11-19 09:52:31 +01:00
Bartłomiej Dach
ef4408a73e Fix song select crashing when selecting random beatmap and changing star rating filter simultaneously (#35730)
Closes https://github.com/ppy/osu/issues/35728.
2025-11-19 16:29:55 +09:00
Kawaritai
6f7f9802bd Change windowed resolutions filtering. Add comment about borders logic. 2025-11-19 09:18:07 +11:00
87ff1051e9 set up sentry (glitchtip) logging properly 2025-11-18 23:27:57 +03:00
marvin
277f4268db Remove BeatmapSelectGrid.RevealRandomItem method 2025-11-18 19:33:59 +01:00
Bartłomiej Dach
80474565fc Merge pull request #35726 from peppy/update-framework
Update framework
2025-11-18 14:19:47 +01:00
2e4b0ff197 make score cards for failed scores look better 2025-11-18 15:33:37 +03:00
499f410c94 slightly changed warnings for old windows versions 2025-11-18 14:44:34 +03:00
616c0d8ecd make key counters show proper readable key names 2025-11-18 14:24:05 +03:00
ed889138a0 break countdown now uses argon-style counter 2025-11-18 13:23:44 +03:00
Dean Herbert
89f2c7160d Update framework 2025-11-18 18:45:38 +09:00
Urantij
f0ca079fe6 Fix cursor incorrectly flashing red after a rewind in replays with Alternate mod active (#35725)
* Fix red cursor with alt mod when rewind

* Change rewind detection in input blocking
2025-11-18 09:52:37 +01:00
Bartłomiej Dach
fbd83cb048 Update framework 2025-11-18 09:50:42 +01:00
Bartłomiej Dach
843c318ec1 Merge branch 'master' into fix/window-sizing-dropdown 2025-11-18 09:50:35 +01:00
Bartłomiej Dach
19b6761697 Clarify target branch requirements in CONTRIBUTING.md
Because it appears to be a point of confusion to new contributors
(https://github.com/ppy/osu/pull/35725#issuecomment-3545734262).
2025-11-18 09:39:06 +01:00
Kawaritai
0c341c1f3e Clamp sizing 2025-11-18 14:38:34 +11:00
Kawaritai
ae5584bd88 Center window within usable bounds 2025-11-18 14:10:18 +11:00
Dean Herbert
edf08b176a Merge pull request #35718 from bdach/smoke-pooling
Add pooling support to smoke segments
2025-11-18 11:37:13 +09:00
18075bef29 display score retractions in recent activity 2025-11-17 21:28:03 +03:00
bc7780a870 updated the first players cutoff date for user profiles 2025-11-17 20:55:42 +03:00
8930b8fadb synchronize with github (tag 2025.1105.0) 2025-11-17 20:41:55 +03:00
2d457f4305 use online status of beatmap instead of mapset 2025-11-17 20:14:23 +03:00
a784734f94 fix up a couple strings 2025-11-17 20:10:54 +03:00
Bartłomiej Dach
7b952b83bf Fix test 2025-11-17 13:55:53 +01:00
Bartłomiej Dach
214122f633 Fix bad localisation reuse in pause overlay (#35717)
Closes https://github.com/ppy/osu-resources/issues/393.

Matches break overlay:

5dc44fbdf9/osu.Game/Screens/Play/Break/BreakInfo.cs (L48)
2025-11-17 20:01:27 +09:00
Bartłomiej Dach
76c0bd4750 Add pooling support to smoke segments
- Closes https://github.com/ppy/osu/issues/35703
- Supersedes / closes https://github.com/ppy/osu/pull/35711

Can test using something dumb like

diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index 11b3b5c71d..e21d8389ef 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -8,6 +8,7 @@
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Threading;
 using JetBrains.Annotations;
 using osu.Framework.Audio.Sample;
 using osu.Framework.Bindables;
@@ -540,6 +541,10 @@ protected override void ParseConfigurationStream(Stream stream)
                 case "Menu/fountain-star":
                     componentName = "star2";
                     break;
+
+                case "cursor-smoke":
+                    Thread.Sleep(500);
+                    break;
             }

             Texture? texture = null;
2025-11-17 11:58:28 +01:00
Bartłomiej Dach
4bf3d9397f Merge pull request #35714 from smoogipoo/fix-preview-track-owners
Fix various screens not registering themselves as `IPreviewTrackOwner`
2025-11-17 08:52:43 +01:00
marvin
fe56ba2921 Turn MatchmakingCandidateType into top level declaration 2025-11-17 07:46:05 +01:00
marvin
1ca4c8860b Add slight wiggle when random card reveals beatmap 2025-11-17 07:38:04 +01:00
marvin
1e05613859 Combine random card reveal & panel roll animation into the same event 2025-11-17 07:37:56 +01:00
marvin
424ef9237f Move result animation & sample implementation into selection panels 2025-11-17 07:35:11 +01:00
marvin
e541e917a4 Change order of tests 2025-11-17 07:32:27 +01:00
marvin
7796394685 Play roll animation when revealing random beatmap 2025-11-17 07:31:46 +01:00
marvin
32900f563c Roll dice on click 2025-11-17 07:30:15 +01:00
marvin
e349a597ba Use dice icon for MatchmakingSelectPanelRandom 2025-11-17 07:29:27 +01:00
maarvin
8b778e8106 Split quickplay beatmap & "random" panel into separate classes (V2) (#35701)
* Load all beatmaps in bulk for SubScreenBeatmapSelect

* Fix tests no longer working due to drawable changes

* Remove test that no longer makes sense

* Split matchmaking panel into subclasses for each panel type

* Adjust tests to match new structure

* Add `ConfigureAwait`

* Display loading spinner while beatmaps are being fetched

* Fix test failure

* Load playlist items directly in `LoadComplete`

* Convert `MatchmakingSelectPanel` card content classes into nested classes

* Wait for panels to be loaded before operating on them

* Add ConfigureAwait()

---------

Co-authored-by: Dan Balasescu <smoogipoo@smgi.me>
2025-11-17 14:11:07 +09:00
Dan Balasescu
ce5e54c9d2 Fix various screens not registering themselves as IPreviewTrackOwner 2025-11-17 13:34:02 +09:00
ecfd4764e7 fixed a blunder 2025-11-16 22:29:25 +03:00
f5ca5083d6 implement pp for legacy song select 2025-11-16 21:21:12 +03:00
1d7c77d8d6 add performance points to selectv2 beatmap info wedge 2025-11-16 20:49:27 +03:00
774e52fbd6 slight result screen score panel redesign 2025-11-16 18:52:04 +03:00
Dean Herbert
45e8df7af2 Merge pull request #35702 from nekodex/matchmaking-random-reveal-sfx
Add SFX to the matchmaking roulette random reveal
2025-11-16 21:23:57 +09:00
Dean Herbert
1c30cb8371 Update resources 2025-11-16 20:22:21 +09:00
a9d7a9d5d5 score panel is now tinted, plus some other changes 2025-11-16 02:48:41 +03:00
f7069b1009 minor fixes for some mods 2025-11-16 02:47:38 +03:00
c3ce5dc787 add argon-style longest combo counter 2025-11-15 19:24:49 +03:00
98076e2092 add skinnable online status and star rating components 2025-11-15 19:03:14 +03:00
b7d1092f90 Merge branch 'master' of https://gitea.jvnko.boats/jvnkosu/client 2025-11-15 17:02:04 +03:00
08db90c278 some minor hud changes
- argon-style cps counter
- keybinds in key counters (for now, only default)
2025-11-15 16:45:14 +03:00
Bartłomiej Dach
bd4ed49c06 Fix several issues with incorrect sample playback (#35685)
* Add failing test coverage for layered hit samples not playing in mania when beatmap is converted

Adding the `osu.Game.Rulesets.Osu` reference to the mania test project
is required so that `HitObjectSampleTest` base logic doesn't die on

f0aeeeea96/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs (L88-L91)

* Fix layered hit sounds not playing on converted beatmaps in mania

Compare
f9e58b4864/osu!/GameplayElements/HitObjects/HitObject.cs#L476-L477.

In case of converted beatmaps, the last condition there
(`BeatmapManager.Current.PlayMode != PlayModes.OsuMania`) fails,
and thus layered hitsounds are allowed to play.

* Add failing test coverage for mania beatmap conversion assigning wrong samples to spinners

* Fix mania beatmap conversion assigning wrong samples to spinners

A spinner is never `IHasRepeats`. It was a dead condition, leading to
the hitobject generating fallback `NodeSamples`, which in particular
feature a silent tail which stable doesn't do.

Noticeably, stable also appears to force the head of the generated hold
note to have no addition sounds:

f9e58b4864/osu!/GameplayElements/HitObjects/Mania/SpinnerMania.cs#L86-L89

* Add failing test coverage for file hit sample not falling back to plain samples if file missing

* Allow `FileHitSampleInfo` to fall back to standard samples if the file is not found (or not allowed to be looked up)

I'm honestly not 100% as to how closely this matches stable because I
reached the point wherein I'd rather not look at stable code anymore, so
as long as this passes tests I'm fine to wait for someone else to report
new breakage.

* Use alternative workaround for lack of osu! ruleset assembly in mania test project

* Fix encode stability test failures
2025-11-15 16:19:08 +09:00
b7e36164c3 update issue templates 2025-11-14 22:22:43 +01:00
Kawaritai
1e91dde92e Separate bindables and centering logic for windowed resolution changes. 2025-11-15 05:43:22 +11:00
Dean Herbert
a593a40429 Merge pull request #35682 from bdach/nom-nom-tasty-exceptions 2025-11-14 19:36:09 +09:00
Jamie Taylor
02b88de76e Add SFX to the matchmaking roulette random reveal 2025-11-14 19:20:56 +09:00
Kawaritai
435cd272ea Separate fullscreen/windowed dropdowns. Center window on size change. 2025-11-14 09:48:32 +11:00
0f5f13858d exit game option for fail condition mods (SD, PF, AC) 2025-11-13 21:41:09 +03:00
Bartłomiej Dach
b64abbf1f5 Alleviate song select post-filter update thread hitches by caching a model-to-carousel-item mapping (#35628) 2025-11-13 23:21:14 +09:00
Bartłomiej Dach
4265e72180 Improve loading time of collection grouping mode (#35693)
Supersedes / closes https://github.com/ppy/osu/pull/35687.

Implements idea from
https://github.com/ppy/osu/pull/35687#issuecomment-3520613982, except
without the additional record, because there's no need for it.

Co-authored-by: WitherFlower <maxime.barniaudy@gmail.com>
2025-11-13 14:10:24 +09:00
89a0c75156 all user-playable mods are now always ranked 2025-11-12 20:53:07 +03:00
Kawaritai
72507b80c7 Add window sizes in dropdown menu options 2025-11-12 06:51:55 +11:00
ab7e5c94f1 make autoupdates work, at last 2025-11-11 19:11:36 +03:00
8dc9ea4553 add startup disclaimer 2025-11-11 18:14:38 +03:00
dcf553c252 Revert "Remove disclaimer screen completely"
This reverts commit bd0e2b4dde.
2025-11-11 16:45:04 +03:00
Bartłomiej Dach
cb9d9734d6 Move realm collection writes off of update thread (#35681)
Probably closes https://github.com/ppy/osu/issues/35650.

Realm slow, episode 23894. I can't reproduce freezes as big as the video
in the issue is showing but 'realm slow' is 99% the culprit, because
affected user's database is not small.
2025-11-11 20:29:39 +09:00
Bartłomiej Dach
5763b7dbe9 Fix skin layout deserialisation eating exceptions without logging
Because I just wasted 30 minutes trying to debug why a skin provided by
a user in an issue thread was failing to deserialise, only to realise
halfway through that the deserialisation error I was seeing was *from
the fallback path and thus a complete red herring*.
2025-11-11 10:24:30 +01:00
Dean Herbert
e1baa03622 Update framework 2025-11-11 18:00:15 +09:00
Bartłomiej Dach
4f783f8c41 Fix attempting to select beatmap which was just externally edited in song select crashing (#35676)
Closes https://github.com/ppy/osu/issues/35651.

The reproduction steps provided in the issue are too complex even. In my
testing all you need to do is go into editor, replace the background via
external editing, and exit out to song select; you'll immediately see
loss of selection on the carousel, the set panel still using the old
background, and eventually a crash when you attempt to re-select any of
the difficulties of the edited set.

`HandleItemsChanged()` - an optimisation aiming to reduce the number
of redundant re-filters due to minor changes to realm models that aren't
visible to the user anyway - ignoring changes to `BeatmapInfo.ID` after
re-entering song select post-external edit meant that song select would
retain stale beatmap models that no longer existed in the realm
database, thus failing refetch attempts via `GetWorkingBeatmap()` or

	8f6f859c15/osu.Game/Screens/SelectV2/FooterButtonOptions.cs (L56-L57)
2025-11-11 14:20:42 +09:00
Bartłomiej Dach
4c72a60ee2 Delay seeking the current track when dragging now playing overlay progress bar until commit (#35677)
RFC. Written to address
https://osu.ppy.sh/community/forums/topics/2150023.

Few other things we might want to happen here:

- pause the track when starting the drag
- figure out what to do when a drag is held while the track changes in
  the background (which was impossible to happen before this)

but I want to see the reaction to this first.
2025-11-11 14:18:40 +09:00
43f3a506ea new icon + default logo color 2025-11-11 00:04:18 +03:00
ab51579c27 added quit w/ replay button to pause menu; minor visual changes for ranks 2025-11-10 22:39:10 +03:00
d8e977c05f minor changes to mod scoring, all mods are ranked now
Probably all user-playable mods are ranked by default now,
Mania key mods were reverted to 1.0x score multiplier
2025-11-10 18:52:07 +03:00
Bartłomiej Dach
c56c528824 Add button for reporting issues to general settings
Clicking the button opens the browser, on the "new topic" page inside
the help forum. Web can now correctly read the build number of the
client since https://github.com/ppy/osu-web/pull/12478 so I see
no reason not to.

Minimal effort implementation. Stemmed from discussion in
https://discord.com/channels/90072389919997952/299846395031060480/1437368033734561792.

Not really interested in putting more effort into this at this point, if
this is not considered acceptable then just close the PR and this can be
revisited more properly at a later date.
2025-11-10 11:28:15 +01:00
复予
013de9f85d Add circular progress display to back-to-top button (#35625)
* Show circular progress on ScrollBackButton of OverlayScrollContainer

* Adjust standardization of position progress
2025-11-10 18:08:00 +09:00
Bartłomiej Dach
cd6c9405fe Fix legacy skin drum roll head circle being underneath ticks (#35647)
Closes https://github.com/ppy/osu/issues/35321.
2025-11-10 15:43:59 +09:00
Loreos7
1df640898f Use proper string key 2025-11-09 17:48:19 +03:00
Andrei Zavatski
7b55b9e4f2 Change path thickness to 1px
Looks better with the new path rendering
2025-11-09 02:07:13 +03:00
Dean Herbert
822cb9e2fb Merge pull request #35643 from diquoks/localisation/wasapi
Localise `WASAPI` setting
2025-11-09 02:16:37 +09:00
c023767df9 bump to 2025.1031.0-tachyon + misc changes for debug builds 2025-11-08 16:26:06 +03:00
Bartłomiej Dach
680614fbee Fix messages from blocked users being visible in public channels (#35645)
* Add failing test coverage for blocking users not removing their messages from public channels

* Fix messages from blocked users being visible in public channels

Closes https://github.com/ppy/osu/issues/35633.

It appears that the expectation from web here is that messages from
blocked users should be excised client-side. Compare:

12dd504255/resources/js/chat/conversation-view.tsx (L104)

This implementation won't *restore* the messages after a block and
unblock, but I kind of... don't care if I'm honest with you? Making that
happen will result in a bunch of complications for no reason, so I'm
fine waiting for anyone to complain about it.
2025-11-07 23:12:12 +09:00
Dean Herbert
cb8ddc706f Merge pull request #35435 from nekodex/matchmaking-jumpy-jump
Add SFX for 'jumping' in quick play
2025-11-07 22:23:35 +09:00
Denis Titovets
04d2ce150a Localise WASAPI setting 2025-11-07 14:46:40 +03:00
Bartłomiej Dach
eaffb89b4c Merge pull request #35638 from smoogipoo/qp-beatmap-panel-mods
Display mods in quick play beatmap cards
2025-11-07 12:34:41 +01:00
Bartłomiej Dach
650a61539b Merge branch 'master' into qp-beatmap-panel-mods 2025-11-07 11:13:54 +01:00
Bartłomiej Dach
75bc934aa5 Merge pull request #35637 from smoogipoo/qp-random-selection
Add support for selecting a "random" quick play item
2025-11-07 11:13:31 +01:00
Dan Balasescu
8d80e2bd2c Adjust guard to be based on current stage 2025-11-07 18:35:46 +09:00
Dan Balasescu
34a3b1ba78 Display mods in quick play beatmap cards 2025-11-07 17:59:02 +09:00
Dan Balasescu
b354fa4472 Implement random beatmap card 2025-11-07 15:30:07 +09:00
Dan Balasescu
1fbe1bd6c9 Fix selected item callback being lost 2025-11-07 15:30:06 +09:00
Bartłomiej Dach
3c215f6574 Fix retro skin changing when creating copy for skin editor (#35630)
RFC, lowest effort solution for https://github.com/ppy/osu/issues/34979.

The `SkinImporter` conditional *is* hella ugly, but anything less ugly
will require taking a hammer to structures. Maybe passing version via
the import flow, maybe even trying to make the `EnsureMutableSkin()`
flow somehow attempt to read the `skin.ini` that's in resources. No
idea.

Properties from `skin.ini` that were defaults or that lazer can't
(won't ever?) understand snipped.
2025-11-07 12:01:11 +09:00
Dan Balasescu
8c28d26130 Document -1 as a special "random" playlist item 2025-11-07 00:23:58 +09:00
Bartłomiej Dach
933fbd274d Fix incorrect handling of user verification failure response (#35629)
`VerificationFailureResponse.RequiredSessionVerificationMethod` not
being nullable means that if it was missing in the verification
response, it would not be `null` but default to `TimedOneTimePassword`
instead, therefore showing TOTP-related error messages to users that
never enabled it rather than the user-facing message they were supposed
to.

Most easily tested on a local full-stack environment with

```diff
diff --git a/app/Libraries/SessionVerification/MailState.php b/app/Libraries/SessionVerification/MailState.php
index 305a2794ec0..3c2d15f335b 100644
--- a/app/Libraries/SessionVerification/MailState.php
+++ b/app/Libraries/SessionVerification/MailState.php
@@ -14,7 +14,7 @@ use Carbon\CarbonImmutable;

 class MailState
 {
-    private const KEY_VALID_DURATION = 600;
+    private const KEY_VALID_DURATION = 10;

     public readonly CarbonImmutable $expiresAt;
     public readonly string $key;
```

applied so that you don't have to wait 10 minutes to trigger the
failure.
2025-11-06 23:21:26 +09:00
Giovanni D.
55ae7e8bb8 Fix timing of beatmap break overlay (#35566)
Issue was bisected to [this commit](6f1664f0a6)

This change in the commit outlined is what caused the issue:
```diff
BreakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
{
  Clock = DrawableRuleset.FrameStableClock,
  ProcessCustomClock = false,
- Breaks = working.Beatmap.Breaks
+ BreakTracker = breakTracker,
},
```

`BreakTracker` always initializes breaks as `new Period(b.StartTime, b.EndTime - BreakOverlay.BREAK_FADE_DURATION);` leaving room at the end to account for the fade before resuming gameplay.

Because of this, changing the `BreakOverlay` to use a `BreakTracker` instead of the original beatmap breaks caused each break to be  `BREAK_FADE_DURATION` shorter than it was originally - which in this case is 325ms - leading to the discrepancy between the background fadeout and the overlay fadeout.

Since the current behavior is 'correct', aligning the overlay with the rest of the beatmap such as background fadeout, I changed the timing to account for the shorter duration instead of revert the overlay initialization.
2025-11-06 14:01:00 +01:00
Bartłomiej Dach
4a22ef88ce Adjust global rank colour tiers
See https://github.com/ppy/osu-web/pull/12522.
2025-11-06 13:14:25 +01:00
Bartłomiej Dach
43ca046f9b Merge branch 'master' into matchmaking-jumpy-jump 2025-11-06 13:06:16 +01:00
Bartłomiej Dach
dbefba57ce Fix pressing Enter on song select with IME active advancing to gameplay instead of confirming choice (#35619)
Closes https://github.com/ppy/osu/issues/35568.
2025-11-06 16:06:52 +09:00
Dean Herbert
20904de276 Update resources 2025-11-05 22:47:21 +09:00
Loreos7
6a6c7ad3ba Move Delete... button to CommonStrings 2025-11-05 15:56:07 +03:00
Bartłomiej Dach
fb2fe65a77 Merge pull request #35611 from stanriders/clamp-notification-avatar
Clamp notification avatar width
2025-11-05 10:42:10 +01:00
Bartłomiej Dach
4662c5d678 Merge pull request #35606 from smoogipoo/qp-history-link
Add history footer button to quick play rooms
2025-11-05 10:22:36 +01:00
Bartłomiej Dach
243cd9c073 Merge pull request #35542 from smoogipoo/mp-vote-to-skip
Implement vote-to-skip in multiplayer
2025-11-05 10:06:59 +01:00
Dan Balasescu
e8db35a5c9 Merge branch 'master' into mp-vote-to-skip 2025-11-05 16:53:44 +09:00
Dan Balasescu
d98cb9ca45 Correctly link to room history 2025-11-05 16:42:32 +09:00
StanR
a7e4aa8b12 Clamp notification avatar width 2025-11-04 21:27:07 +05:00
Bartłomiej Dach
0f54608cee Merge pull request #35575 from smoogipoo/qp-player-download-progress
Add download progress bars to quick play users
2025-11-04 14:54:03 +01:00
Bartłomiej Dach
f8331e0b28 Apply one more missed rename 2025-11-04 12:56:03 +01:00
Bartłomiej Dach
6ff2a6225d Merge branch 'master' into qp-player-download-progress 2025-11-04 12:52:01 +01:00
Bartłomiej Dach
a8020dea7c Bring back size spec in a better way 2025-11-04 12:51:53 +01:00
Dan Balasescu
88dd458394 Apply suggestions from review
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-11-04 11:37:12 +09:00
Dan Balasescu
23cb7f3b23 Add download progress bars to quick play users 2025-11-04 11:37:12 +09:00
Dan Balasescu
7da051b144 Add test 2025-11-04 11:37:07 +09:00
Dan Balasescu
78f639d760 Attempt to clean up chat size definition 2025-11-04 11:29:51 +09:00
Dan Balasescu
4ea03d0e07 Add history footer button to quick play rooms 2025-11-04 11:28:08 +09:00
Dan Balasescu
4d706b12ac Fix missing disposal 2025-11-04 11:09:02 +09:00
Dan Balasescu
c44f701abe Also update text when users leave 2025-11-04 11:09:02 +09:00
Dan Balasescu
4c81d661aa Bypass vote for auto-skip
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-11-04 11:08:57 +09:00
Dan Balasescu
f4049c7ec1 Suffix introp methods with "Intro" 2025-11-04 11:05:41 +09:00
Bartłomiej Dach
645d27bb32 Add tiered colours for global rank (#35597)
* Add new API property backing for tiered rank

* Slightly refactor `ProfileValueDisplay` for direct access to things that will need direct access

* Extract separate component for global rank display

* Add tiered colours for global rank
2025-11-04 10:47:33 +09:00
Bartłomiej Dach
73f1849365 Fix signalr connector connection failure logging eating exception stack trace (#35598)
As seen in
https://discord.com/channels/188630481301012481/1097318920991559880/1434899538123952128,
wherein precisely zero useful detail can be gleaned (and nothing is
reported to sentry either).
2025-11-04 09:46:09 +09:00
复予
89b443bccc Add GitHub link button to the wiki overlay header (#35595)
* Add Github link button to wiki overlay header

* Localize jump link string

* Mark ILinkHandler dependency as nullable

* Make the button actually look like it does on the website

* Use existing web string instead of inventing a new one

* Bind value change callback more reliably

---------

Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-11-03 13:29:46 +01:00
Bartłomiej Dach
be9170832c Merge pull request #35583 from Marvefect/maniaKeymodePP
Add PP breakdown to osu!mania profiles
2025-11-03 12:09:23 +01:00
Bartłomiej Dach
9db200ed41 Merge pull request #35585 from smoogipoo/qp-notification-join-on-click
Fix quick play notification not setting "accepted" state
2025-11-03 09:50:32 +01:00
Dan Balasescu
1ab017d4e2 Fix quick play notification not setting "accepted" state 2025-11-02 12:44:01 +09:00
Dan Balasescu
2413e98108 Fix file and class name mismatch 2025-11-02 11:58:09 +09:00
Marvefect
65fb5311ea Removed unneccesary blank space, reran dotnet format 2025-11-02 02:27:39 +03:00
Marvefect
14cdc40f0f Added Tooltip 2025-11-02 02:04:48 +03:00
Dean Herbert
9a393f912b Merge pull request #35545 from bdach/switch-active-carousel-group
Switch active carousel group if current selection no longer exists in the previous group
2025-11-01 18:42:25 +09:00
Dan Balasescu
a9ca4634fc Resolve CI inspections 2025-10-31 21:48:24 +09:00
Dan Balasescu
bdcc0ee937 Apply suggestions from review 2025-10-31 21:42:29 +09:00
Dan Balasescu
6f94b1ab6d Move property reset into GameplayStarted() 2025-10-31 21:40:40 +09:00
Dan Balasescu
b20a41c1e8 Add simple multiplayer skip overlay 2025-10-31 21:39:41 +09:00
Dan Balasescu
d0ce74063d Skip full intro length 2025-10-31 21:39:41 +09:00
Dan Balasescu
373162df02 Add support for vote-to-skip in multiplayer 2025-10-31 21:39:41 +09:00
Dean Herbert
8e0c9281d3 Merge pull request #35543 from bdach/fix-thing
Fix bad performance when moving mouse to left side of song select forcibly expands group with current selection
2025-10-31 18:35:53 +09:00
Dean Herbert
25a1a1ba37 Merge pull request #35484 from glacc/show-hud-while-editing-skin-layout
Always show HUD while editing skin layout
2025-10-31 08:48:59 +09:00
Bartłomiej Dach
73e05e3fae Switch active carousel group if current selection no longer exists in the previous group
This was primarily written to fix
https://github.com/ppy/osu/issues/35538, but also incidentally targets
some other scenarios, such as:

- When switching from artist filtering to title filtering, selection
  sometimes would stay at the group under which the selection's artist
  was filed, rather than moving to the group under which the selection's
  title is filed (in other words, the group that *the selection is
  currently under*).

- When simply assigning a beatmap to a collection such that it would
  be moved out of the current group, the selection will now follow to
  the new collection's group rather than staying at its previous
  position.

  Whether this is desired is highly likely to be extremely situational,
  but I don't want to introduce complications unless it's absolutely
  necessary.

This has a significant performance overhead because
`CheckModelEquality()` isn't free, but it doesn't seem horrible in
profiling.
2025-10-30 14:54:10 +01:00
Bartłomiej Dach
2a01e3d148 Add failing test case 2025-10-30 14:54:08 +01:00
Jamie Taylor
cf0e5edf34 Rework player jump feedback 2025-10-30 22:51:55 +09:00
Jamie Taylor
a825104688 Add test scene for player jump spamming 2025-10-30 21:34:42 +09:00
Bartłomiej Dach
ea1798d731 Fix bad performance when moving mouse to left side of song select forcibly expands group with current selection
Calling `HandleItemActivated()` rather than its intended 'parent method'
of `Activate()` meant that selection state was not correctly
invalidated:

	819da1bc38/osu.Game/Graphics/Carousel/Carousel.cs (L157)

which in turn meant that carousel item Y positions would not be
recalculated correctly after the group was expanded, which meant that
the items would become

- visible,
- stuck to the bottom of the expanded group,
- one on top of another.

Which is not something that's going to perform well.

Certified OOP moment.
2025-10-30 13:25:38 +01:00
Dan Balasescu
a435dfe93e Add interop models 2025-10-30 19:04:49 +09:00
Bartłomiej Dach
5c1171f358 Merge pull request #35537 from smoogipoo/qp-fix-view-beatmap
Fix quick play "view beatmap" showing incorrect difficulty
2025-10-30 11:04:46 +01:00
Bartłomiej Dach
3fcc626e29 Merge pull request #35511 from smoogipoo/qp-fix-empty-sequence
Fix potential sources of empty sequence errors
2025-10-30 10:49:12 +01:00
Dan Balasescu
7ff6edeb64 Fix quick play "view beatmap" showing incorrect difficulty 2025-10-30 15:27:28 +09:00
Dan Balasescu
657bc31539 Fix potential sources of empty sequence errors 2025-10-29 23:06:28 +09:00
Dan Balasescu
f9f7740acb Add failing test 2025-10-29 23:06:28 +09:00
Bartłomiej Dach
5e4dd77e64 Merge branch 'master' into show-hud-while-editing-skin-layout 2025-10-29 14:27:28 +01:00
Bartłomiej Dach
ce96c0b037 Merge extremely similar setting-enforcing flows in skin editor 2025-10-29 14:24:18 +01:00
Dean Herbert
5af9bb784b Merge pull request #35495 from Joehuu/fix-drawable-date-update
Fix `DrawableDate` not updating
2025-10-29 20:17:15 +09:00
Bartłomiej Dach
4c60df21db Fix DrawableDate not updating
Co-authored-by: Dean Herbert <pe@ppy.sh>
2025-10-29 11:51:31 +01:00
Bartłomiej Dach
3c6fb14a32 Merge pull request #35501 from peppy/more-quick-play-notification-improvements
More quick play notification improvements
2025-10-29 11:33:34 +01:00
Dan Balasescu
3afc7b045c Remove redundant default value 2025-10-29 17:27:33 +09:00
Bartłomiej Dach
2f2847f1dd Merge pull request #35498 from smoogipoo/qp-add-helpers
Add quick play helpers to add users/rounds
2025-10-29 09:13:03 +01:00
Dean Herbert
ee7c52465b Allow queue completion notification to show even during gameplay 2025-10-29 16:58:18 +09:00
Dean Herbert
beb977892e Use better iconography and colour for queue completion notification 2025-10-29 16:58:17 +09:00
Bartłomiej Dach
7203f419a2 Merge branch 'master' into qp-add-helpers 2025-10-29 08:13:51 +01:00
Dan Balasescu
722cfb72d8 Replace indexers with GetOrAdd()
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-10-29 16:07:46 +09:00
Bartłomiej Dach
5da132cc2f Merge pull request #35482 from smoogipoo/qp-fix-initial-placement-display
Ensure to never display "0th" placement
2025-10-29 07:47:35 +01:00
Dean Herbert
9fac96cf07 Merge pull request #35499 from smoogipoo/qp-fix-beatmap-nullref
Fix potential quick play crash if beatmap lookup fails
2025-10-29 15:43:31 +09:00
Jamie Taylor
fadcb9882c Merge branch 'master' into matchmaking-jumpy-jump 2025-10-29 15:34:50 +09:00
Bartłomiej Dach
0610781c6c Merge pull request #35483 from smoogipoo/qp-fix-results-no-scores-crash
Fix quick play results screen crash when no one plays
2025-10-29 07:30:59 +01:00
Dan Balasescu
e9260de56f Fix potential nullref if beatmap lookup fails 2025-10-29 15:15:36 +09:00
Dan Balasescu
2d177226fd Add failing test 2025-10-29 15:08:40 +09:00
Dan Balasescu
bd912710f1 Add quick play helpers to add users/rounds 2025-10-29 14:49:22 +09:00
Dean Herbert
4e76bd0f24 Play sound when match is available even when queueing in background (#35496) 2025-10-29 13:58:20 +09:00
Bartłomiej Dach
050c10cec2 Ensure all invocations of spectator server hub methods have their errors observed (#35488)
Fell out when attempting
https://github.com/ppy/osu-server-spectator/pull/346.

Functionally, if a true non-`HubException` is produced via an invocation
of a spectator server hub method, this doesn't really do much - the
error will still log as 'unobserved' due to the default handler, it will
still show up on sentry, etc. The only difference is that it'll get
handled via the continuation installed in `FireAndForget()` rather than
the `TaskScheduler.UnobservedTaskException` event.

The only real case where this is relevant is when the server throws
`HubException`s, which will now instead bubble up to a more
human-readable form. Which is relevant to the aforementioned PR because
that one makes any hub method potentially throw a `HubException` if the
client version is too old.

Obviously this does nothing for the existing old clients.
2025-10-29 12:18:23 +09:00
De4n
b4fd7ec10f Add a keycounter that has been actually used in Triangles skin (#35491) 2025-10-29 12:18:00 +09:00
Bartłomiej Dach
cbe7da99ad Fix screen footer overlay content being pushed to right during fade-out (#35481)
* Apply some renames & drawable names for visualiser

Optional but really helps me make heads of tails as to what anything is
here.

Like really, multiple variations of `footerContent` inside a
`ScreenFooter` class, with zero elaboration that it's really content to
do with *overlays*...

* Fix screen footer overlay content being pushed to right during fade-out

- Closes https://github.com/ppy/osu/issues/35203
- Supersedes / closes https://github.com/ppy/osu/pull/35468
2025-10-29 12:14:37 +09:00
Joseph Madamba
9a965a2546 Add failing drawable date seconds update test 2025-10-28 19:39:07 -07:00
Dan Balasescu
7b0121a430 Fix quick play results screen when no one plays 2025-10-29 11:18:25 +09:00
Dan Balasescu
627fec2e3a Add failing test case 2025-10-29 11:18:25 +09:00
Glacc
c779e142e6 Code quality fix. 2025-10-28 23:04:09 +08:00
Glacc
89fffa5a1a Code quality fix. 2025-10-28 22:54:07 +08:00
Glacc
6d597fc815 Null check for configVisibilityMode. 2025-10-28 21:51:21 +08:00
Glacc
a78b456e20 Revert value after closing editor. 2025-10-28 21:42:34 +08:00
Glacc
9237c76942 And make HUD visibility mode lease when Skin Layout Editor is visible. 2025-10-28 21:38:28 +08:00
Glacc
378c64b7f8 Only set HUD visibility mode to non-Never when skin layout editor is visible by saving and restoring HUD visibility mode setting. 2025-10-28 21:21:07 +08:00
Glacc
87b66685d6 Always show HUD while editing skin layout. 2025-10-28 19:42:47 +08:00
Dan Balasescu
c524bf5432 Make MachmakingUser.Placement nullable 2025-10-28 20:39:09 +09:00
Dan Balasescu
a40230da4b Ensure to never display "0th" placement 2025-10-28 19:35:15 +09:00
Dean Herbert
b1a421c22b Merge pull request #35470 from smoogipoo/qp-show-quit-users 2025-10-28 19:26:10 +09:00
Dean Herbert
9601708087 Fix quit text on avatar only mode, fix avatar fade 2025-10-28 18:29:05 +09:00
Dean Herbert
22f11b6fa5 Update test in line with new quit panel behaviour 2025-10-28 16:30:31 +09:00
Bartłomiej Dach
f95d0d214e Merge pull request #35474 from peppy/fix-wasapi-setting-text
Fix WASAPI settings notice text not displaying on startup
2025-10-28 08:23:03 +01:00
Dean Herbert
0205cf0fb9 Render frame buffers at a higher resolution to fix blurry for now 2025-10-28 15:43:25 +09:00
Dean Herbert
8b2b6517ca Fix regression of avatar animation 2025-10-28 15:41:40 +09:00
Dean Herbert
ce3b8bc77b Update framework 2025-10-28 15:15:35 +09:00
Dean Herbert
98829bf857 Merge pull request #35249 from dnfd1/mania-difficultychange-limits
Adjust extended OD limits for mania difficulty change mod to reflect HR and EZ values
2025-10-28 15:05:26 +09:00
Dan Balasescu
3c37ac1718 Fix clipped outline
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-10-27 23:19:28 +09:00
Dean Herbert
f8769d2e44 Fix WASAPI settings notice text not displaying on startup 2025-10-27 22:59:02 +09:00
Dean Herbert
4d66762898 Merge pull request #35471 from bdach/single-result-reselected
Fix single filtered selection not being reselected after being filtered away
2025-10-27 22:11:26 +09:00
Bartłomiej Dach
e61ae7ab8a Fix single filtered selection not being reselected after being filtered away
Closes https://github.com/ppy/osu/issues/35003.

Bit dodgy to use `CurrentSelectionItem` for this. Ideally I would use
the global `Beatmap.IsDefault`, but I kind of don't want to violate the
rule that `BeatmapCarousel` shouldn't have direct access to the global
beatmap. And this seems to work, so... maybe fine to use until it
doesn't?
2025-10-27 11:13:48 +01:00
Bartłomiej Dach
98eb29c43d Add failing test 2025-10-27 11:13:47 +01:00
Dan Balasescu
bb578d254d Mark panels as quit instead of removing 2025-10-27 19:07:09 +09:00
Dan Balasescu
b7c07ad0e5 Add support for marking panels as quit 2025-10-27 19:07:09 +09:00
Dan Balasescu
08621c4cc9 Refactor panel structure 2025-10-27 19:07:05 +09:00
Bartłomiej Dach
be9b99f975 Merge pull request #35467 from smoogipoo/qp-discord-presence
Adjust Discord rich presence for quick play
2025-10-27 09:11:20 +01:00
Dan Balasescu
765b9a20b5 Hide quick play room name in Discord rich presence 2025-10-27 12:13:15 +09:00
Dan Balasescu
473fb5720c Disable Discord invites to quick play rooms 2025-10-27 12:11:11 +09:00
Dean Herbert
5faf791ca0 Merge pull request #35445 from peppy/experimental-wasapi-user-toggle
Add settings toggle for experimental BASS initialisation mode
2025-10-25 20:44:53 +09:00
Dean Herbert
9ca47fc53a Update framework 2025-10-25 19:41:28 +09:00
Dean Herbert
79a76ce587 Update AudioDevicesSettings.cs
Co-authored-by: Dan Balasescu <smoogipoo@smgi.me>
2025-10-25 17:35:48 +09:00
Dean Herbert
72fa1553c3 Add settings toggle for experimental BASS initialisation mode 2025-10-25 13:46:49 +09:00
Andrei Zavatski
afdebcf188 Make CursorPathContainer a smooth path 2025-10-25 01:50:27 +03:00
Dean Herbert
954061b00b Merge pull request #35432 from smoogipoo/improve-qp-chat
Several improvements to quick play chat input
2025-10-25 00:50:11 +09:00
Dean Herbert
b74962af92 Merge pull request #35422 from bdach/favourites-grouping
Implement grouping by favourites
2025-10-24 23:24:48 +09:00
Dean Herbert
1af462b692 Add very simple countdown timer for quick play stages (#35433) 2025-10-24 23:07:04 +09:00
Jamie Taylor
0558f9f2d9 Add SFX for 'jumping' in quickplay 2025-10-24 22:42:28 +09:00
Dean Herbert
763739e877 Merge branch 'master' into favourites-grouping 2025-10-24 22:39:14 +09:00
Dan Balasescu
f96be84c57 Fix tests 2025-10-24 22:23:05 +09:00
Dan Balasescu
613c208362 Fix partially offscreen quick play chat context menu 2025-10-24 21:45:56 +09:00
Dan Balasescu
a3c78de710 Move context menu from channel to chat overlay 2025-10-24 21:45:56 +09:00
Dan Balasescu
e240817087 Move quick play chat entirely to screen footer 2025-10-24 21:45:56 +09:00
Dean Herbert
ddb844f81b Merge pull request #35429 from bdach/scrolling-song-select-wedge-text
Scroll song select title wedge text if it overflows
2025-10-24 21:40:03 +09:00
Dean Herbert
b6f4175939 Merge pull request #35431 from bdach/instant-scroll-carousel-post-filter
SongSelectV2: Scroll to selection instantly after a filter
2025-10-24 21:27:25 +09:00
Bartłomiej Dach
819da1bc38 SongSelectV2: Scroll to selection instantly after a filter
Closes https://github.com/ppy/osu/issues/33379.

Pretty sure this matches song select V1. The two call sites where the
old one does instant scrolls are:

	30412ba3f2/osu.Game/Screens/Select/BeatmapCarousel.cs (L672)

which happens just after a filter, and

	30412ba3f2/osu.Game/Screens/Select/BeatmapCarousel.cs (L683)

which is a bit more difficult to pin down, but generally appears to
happen on changes to the visible items, which on `SongSelectV2` triggers
a re-filter anyway.
2025-10-24 13:24:47 +02:00
Bartłomiej Dach
33e42d2809 Fix code quality 2025-10-24 12:11:38 +02:00
Bartłomiej Dach
1a49d030a0 Fix marquee container not updating scrolling state if its content changes size
This is actually possible in current usages if you e.g. toggle "use
original metadata" on/off which will change the width of the underlying
sprite texts. Or by setting window size. Pick your poison.
2025-10-24 11:08:01 +02:00
Bartłomiej Dach
03adae4417 Scroll song select title wedge text if it overflows
Instead of truncating.

Addresses https://github.com/ppy/osu/discussions/35404.

The one "tiny" problem is that the "click to search" functionality of
these texts is maybe a bit worse now, because the clickable target is
now the full width of the wedge rather than autosized to the text.
Salvaging this is *maybe* possible, but *definitely* annoying, so I'd
rather not frontload it.
2025-10-24 11:07:06 +02:00
Dean Herbert
5a38e1537b Merge pull request #35428 from bdach/star-rating-grouping-limit
Use single group for beatmaps of 15 stars and above
2025-10-24 18:00:57 +09:00
Dean Herbert
6ac8e59a11 Merge pull request #35426 from bdach/collection-grouping-order
Fix song select collection group order not matching other collection lists when certain characters are used
2025-10-24 17:53:28 +09:00
Bartłomiej Dach
a816977208 Use single group for beatmaps of above 15 stars
Addresses https://github.com/ppy/osu/discussions/35201.
2025-10-24 10:23:36 +02:00
Bartłomiej Dach
f0bfb4becc Assert expected behaviour in test 2025-10-24 10:23:36 +02:00
Dean Herbert
ec6ffb3403 Merge pull request #35420 from smoogipoo/qp-handle-beatmap-present
Disable presenting beatmaps during quick play
2025-10-24 16:59:45 +09:00
Bartłomiej Dach
6ded2e3de7 Fix song select collection group order not matching other collection lists when certain characters are used
Addresses https://github.com/ppy/osu/discussions/35391.

See inline commentary for explanation.
2025-10-24 09:51:34 +02:00
Dean Herbert
6c7eafde1a Merge pull request #35395 from bdach/culture-info-is-the-bane-of-my-existence
Allow `NumberFormattingExtensions.ToStandardFormattedString()` to accept culture
2025-10-24 16:46:37 +09:00
Bartłomiej Dach
14d0982b6c Implement grouping by favourites
- Closes https://github.com/ppy/osu/issues/34494.
- Supersedes / closes https://github.com/ppy/osu/pull/34744.
2025-10-24 08:46:34 +02:00
Bartłomiej Dach
29787360ba Change BeatmapCarouselFilterGrouping constructor params to required init properties 2025-10-24 08:42:45 +02:00
Bartłomiej Dach
6b56a0611b Refetch list of user favourites on every change to favourites
Is this lazy? Sure it is. Friends and blocks do the same thing, though,
and I'm not overthinking this any more than I already have.

Being smarter here would likely mean being more invasive with respect to
listening in on all outgoing API requests and silently updating
favourites on that basis. Which is "smart" but also complicated.
2025-10-24 08:41:52 +02:00
Bartłomiej Dach
0f1bf35bd9 Add favourite beatmap set tracking to LocalUserInfo 2025-10-24 08:40:50 +02:00
Bartłomiej Dach
b600860540 Implement request & response for fetching logged in user's favourite beatmap sets 2025-10-24 08:36:13 +02:00
Bartłomiej Dach
ae7ba034a7 Always use current culture in ToStandardFormattedString() 2025-10-24 08:26:01 +02:00
Dean Herbert
0cb521798d Merge pull request #35398 from bdach/song-select-working-beatmap-pressure
Attempt to improve performance of beatmap carousel when not grouped by sets
2025-10-24 15:22:41 +09:00
Dan Balasescu
1ee24521b8 Disable presenting beatmaps during matchmaking 2025-10-24 15:15:46 +09:00
Dean Herbert
efe7d92096 Merge branch 'master' into song-select-working-beatmap-pressure 2025-10-24 14:36:59 +09:00
Dean Herbert
4f478db056 Merge pull request #35400 from bdach/leaderboard-sometimes-incorrectly-partial
Fix solo leaderboard sometimes not showing user position while it technically could
2025-10-24 14:36:14 +09:00
Dean Herbert
646cb71b77 Merge pull request #35415 from bdach/local-user-state-refactor
Extract all pieces of local user-related state to `APIAccess` subcomponent
2025-10-24 14:32:43 +09:00
Dean Herbert
ce3e3d17fa Merge pull request #35393 from smoogipoo/fix-qp-availability
Make quick play redownload locally modified beatmaps
2025-10-24 14:28:03 +09:00
Dean Herbert
d062c99666 Merge branch 'master' into fix-qp-availability 2025-10-24 14:27:45 +09:00
Dean Herbert
803737c947 Use more legible collection initialisation 2025-10-24 14:22:10 +09:00
Dean Herbert
44a427f4e5 Merge pull request #35399 from smoogipoo/qp-view-beatmap
Fix quick play "view beatmap" not showing beatmap overlay
2025-10-24 14:21:49 +09:00
Dean Herbert
85ab0d621c Merge pull request #35397 from smoogipoo/qp-match-ended-counter
Fix round counter showing on match end
2025-10-24 14:17:09 +09:00
Dean Herbert
1591d49143 Merge pull request #35401 from bdach/custom-sample-set-model-support
Adjust gameplay sample models to support custom sample sets
2025-10-23 18:36:17 +09:00
Dean Herbert
b9de7ba196 Merge pull request #35367 from smoogipoo/qp-idle-track
Preview next song in quick play
2025-10-23 18:23:20 +09:00
Bartłomiej Dach
dfa8d4fe7c Fix blocks not being correctly cleared on logout
See, this refactor is where omissions like this that normally would pass
unnoticed stop passing unnoticed.
2025-10-23 10:54:52 +02:00
Bartłomiej Dach
5eda9a0fd7 Extract all pieces of local user-related state to APIAccess subcomponent
Something I've asked to be done for a long time. Relevant because I've
complained about this on every addition of a new piece of user-local
state: friends, blocks, and now favourite beatmaps.

It's just so messy managing all this inside `APIAccess` next to
everything else, IMO.
2025-10-23 10:53:58 +02:00
Bartłomiej Dach
ca8fc81a7e Fix solo leaderboard sometimes not showing user position while it technically could
The "partial" leaderboard logic in `SoloGameplayLeaderboardProvider`
always assumed the online fetch would request 50 scores, which is no
longer the case after https://github.com/ppy/osu/pull/33100.
2025-10-23 08:53:29 +02:00
Bartłomiej Dach
82bcbb53dd Fix taiko sample models not passing everything forward as they should 2025-10-23 08:48:39 +02:00
Dan Balasescu
9a089315b8 Don't block input on mouse down 2025-10-22 22:22:44 +09:00
Bartłomiej Dach
baea05a0a1 Adjust test to cover better 2025-10-22 14:58:13 +02:00
Bartłomiej Dach
c361e6d3c2 Adjust gameplay sample models to support custom sample sets
This is a set of model changes which is supposed to facilitate support
for custom sample sets to the beatmap editor that is on par with stable.

It is the minimal set of changes. Because of this, it can probably be
considered "ugly" or however else you want to put it - but before you
say that, I want to try and pre-empt that criticism by explaining where
the problems lie.

Problem #1: duality in sample models
---

There is currently a weird duality of what a `HitObject`'s samples will
be.

- If an object has just been placed in the editor, and not saved /
  decoded yet, it will use `HitSampleInfo`.

- If an object has already been encoded to the beatmap at least once, it
  will use `ConvertHitObjectParser.LegacyHitSampleInfo`.

As long as that state of affairs remains, `HitSampleInfo` must be able
to represent anything that `LegacyHitSampleInfo` can, if feature parity
is to be achieved.

Problem 2: The 0 & 1 sample banks
---

Custom sample banks of 2 and above are a pretty clean affair. They map to
a suffix on the sample filename, and said samples are allowed to be
looked up from the beatmap skin. `Suffix` already exists in
`HitSampleInfo`.

However, the 1 custom sample bank is evil. It uses *non-suffixed*
samples, *allows lookups from the beatmap skins*, contrary to no bank /
bank 0, which *also* uses non-suffixed samples, but *doesn't* allow them
to be looked up from the beatmap skin.

This is why `HitSampleInfo.UseBeatmapSamples` has been called to
existence - without it there is no way to represent the ability of using
or not using the beatmap skin assets.

As has been stated previously in discussions about this feature, it's
both a *mapping* and a *skinning* concern.

There are many things you could do about either of these problems, but I
am pretty sure tackling either one is going to take *many* more lines of
code than this commit does. Which is why this is the starting point of
negotiation.
2025-10-22 14:58:08 +02:00
Bartłomiej Dach
a4a2e4e639 Add test coverage of expected behaviour of sample suffix 2025-10-22 14:30:47 +02:00
Dan Balasescu
5fc8cde0f7 Fix AllowSelection blocking all input 2025-10-22 19:55:43 +09:00
Dan Balasescu
a2098b633a Fix quick play "view beatmap" not showing beatmap overlay 2025-10-22 19:29:51 +09:00
Dan Balasescu
0a3665c43d Fix round counter showing on match end 2025-10-22 19:01:02 +09:00
Bartłomiej Dach
c34b2ffc05 Fix performance overhead when computing spacing between standalone panels
The equality check that was supposed to replace the read of
`CurrentSelectionItem` showed up as a hotspot in profiling.

The selection updating code looks a little stupid after this, but all in
the name of performance...
2025-10-22 11:46:34 +02:00
Bartłomiej Dach
4ebd97b804 Slightly delay retrieval of working beatmaps in song select panels
Beatmap panels can be visible for very brief instants.
`PanelSetBackground` has a backstop to prevent expensive background
loads which is based on the position of the panel relative to centre of
screen.

However, retrieving the working beatmap that *precedes* any of that
expensive background load logic, is *also* expensive, and *always* runs
even if a panel is visible on screen for only a brief second. Therefore,
by moving some of that background load delay towards delaying retrieving
the working beatmap, we can save on doing even more work, which has
beneficial implications for performance.
2025-10-22 11:00:20 +02:00
Dean Herbert
dcb30ed5b3 Add pool names to quick play pool selector (#35394) 2025-10-22 17:54:49 +09:00
Bartłomiej Dach
a29a5ab7e6 Allow NumberFormattingExtensions.ToStandardFormattedString() to accept culture
I had previously made it invariant in
https://github.com/ppy/osu/pull/32837, and in another instance of past
me being an asshole, I can't actually find the reasoning for this at
this time.

That said, you'd be excused for thinking "why does this matter"? Well,
this will fix https://github.com/ppy/osu/issues/35381, because that
failure only occurs when the user's culture is set to one that doesn't
use a decimal point (.) but rather a decimal comma (,). This messes with
framework, which uses the *current* culture to check for decimal
separator rather than invariant:

d3226a7842/osu.Framework/Graphics/UserInterface/TextBox.cs (L106-L111)

An alternative would be to change framework instead to always accept the
invariant decimal separator.

God I hate this culture crap.
2025-10-22 10:31:12 +02:00
Dan Balasescu
62599de649 Fix intermittent footer test failures
See:
https://github.com/ppy/osu/pull/35367/checks?check_run_id=53269836615

Can be reproed via a `Thread.Sleep(1000)` in a `TestScreenOne` BDL load.
Code here is similar to `OsuGameTestScene.PushAndConfirm()`.
2025-10-22 16:40:20 +09:00
Dan Balasescu
4cac1781c5 Use interface instead 2025-10-22 16:02:46 +09:00
Dan Balasescu
fcf6d04791 Download using preferred video mode 2025-10-22 15:34:40 +09:00
Dan Balasescu
c6fcba7e1c Fix quick play not redownloading modified beatmaps 2025-10-22 15:34:29 +09:00
Dean Herbert
47b95de06d Merge pull request #35365 from bdach/bump-diffcalc-versions
Bump difficulty calculator versions
2025-10-22 15:12:56 +09:00
Dean Herbert
4e4eba2070 Merge pull request #35388 from Hoopsier/master
Accuracy to pause
2025-10-22 14:31:23 +09:00
Dean Herbert
2ec0cbe5db Allow localisation of accuracy display on pause screen 2025-10-22 13:56:38 +09:00
Hoopsy
0644543e28 Accuracy to pause and fail 2025-10-22 00:29:55 +03:00
Dan Balasescu
23933452fe Preserve last beatmap until selection is made 2025-10-21 20:00:21 +09:00
Dean Herbert
61547d6b38 Merge pull request #35377 from peppy/update-framework
Update framework
2025-10-21 18:58:42 +09:00
Dean Herbert
0b84916c3e Update framework 2025-10-21 17:24:33 +09:00
Dean Herbert
3120871298 Merge pull request #35366 from bdach/carousel-collapsing-broke
Fix beatmap set not expanding post-filter if grouping was turned off after manually collapsing active group
2025-10-20 20:22:56 +09:00
Dan Balasescu
2dbfdc3d2c Preview next song in quick play 2025-10-20 17:02:35 +09:00
Bartłomiej Dach
0af3f15c7c Merge pull request #35313 from smoogipoo/subscreen-footer
Make `ScreenFooter` support subscreens
2025-10-20 10:00:36 +02:00
Bartłomiej Dach
594b8c1a60 Fix beatmap set not expanding post-filter if grouping was turned off after manually collapsing active group
Closes https://github.com/ppy/osu/issues/35339.
2025-10-20 09:30:02 +02:00
Bartłomiej Dach
0269257287 Add failing test 2025-10-20 09:23:06 +02:00
Bartłomiej Dach
03a5aedf99 Bump difficulty calculator versions
To trigger client-side recalculations of star ratings.

Should have been done in https://github.com/ppy/osu/pull/35029.

Probably closes https://github.com/ppy/osu/issues/35357.
2025-10-20 08:46:30 +02:00
Loreos7
1ec6735a35 Restore original delete button name 2025-10-18 19:17:08 +03:00
Dean Herbert
fbaf27e3db Merge pull request #35342 from peppy/revert-framework
Revert framework bump to fix crashes for some users
2025-10-19 00:39:43 +09:00
Dean Herbert
45eb34ecde Merge pull request #35335 from peppy/fix-quick-play-user-panels
Fix quick play player panels being hard to see against bright user backgrounds
2025-10-19 00:39:37 +09:00
Dean Herbert
10beab6ad3 Revert framework bump to fix crashes for some users 2025-10-18 23:53:45 +09:00
Dean Herbert
70188d4fab Fix quick play player panels being hard to see against bright user backgrounds 2025-10-18 23:18:57 +09:00
Dean Herbert
1ce846294b Update framework 2025-10-18 19:08:07 +09:00
Dan Balasescu
4be29425a0 Use new implementation in ScreenTestScene 2025-10-17 19:01:28 +09:00
Dan Balasescu
db3cc583e6 Isolate footer behaviour to ScreenStackFooter, support subscreens 2025-10-17 19:01:28 +09:00
Bartłomiej Dach
fec7ef7624 Merge pull request #35316 from kennyaja/round_control_points
Round slider control points to integer positions (instead of truncating them)
2025-10-17 11:46:52 +02:00
Bartłomiej Dach
6e378ad5af Update relevant test with new expectations 2025-10-17 08:58:09 +02:00
Bartłomiej Dach
8f8f605748 Use MathF instead of casting 2025-10-17 08:44:58 +02:00
Bartłomiej Dach
5f9ade6610 Fix code quality 2025-10-17 08:44:30 +02:00
Bartłomiej Dach
1a569e9e2a Merge pull request #35317 from peppy/locus-bundle
Add locus 2025 winners to bundled download beatmaps list
2025-10-16 20:16:40 +02:00
Dean Herbert
98762ce09e Add locus 2025 winners to bundled download beatmaps list 2025-10-17 02:03:52 +09:00
Alban Cabannes-Michel
8f6f859c15 SSV2 : Replace "Mark as Played" with "Remove from Played" if map is already played (#35287)
* SSV2 : Replace Mark as Played with Remove from Played if already played

* Remove checks of BeatmapInfo.LastPlayed for DateTimeOffset.MinValue

* Make FooterButtonOptions use a RealmLive<BeatmapInfo> and act on review comments

* FIXUP: Detach BeatmapInfo before passing it to FooterButtonOptions.Popover

---------

Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-10-16 14:59:16 +02:00
kennyaja
cf1834b080 Also round slider control points to integer positions if it has less than 2 segments 2025-10-16 19:25:43 +07:00
Bartłomiej Dach
a2bae15db1 Fix Hold Off mod changing scroll speed in rare scenarios (#35265)
Reported (in a rather confusing manner) in
https://discord.com/channels/188630481301012481/1097318920991559880/1426084740783538268.

The relevant bit here is the following logic:

	32c60bfb36/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs (L111-L118)

which mania enables.
2025-10-16 21:09:52 +09:00
Dean Herbert
159349a64b Merge pull request #35312 from smoogipoo/fix-mp-exit
Fix screen event misusages in multplayer/matchmaking
2025-10-16 18:19:01 +09:00
Dan Balasescu
81a529200d Add footer tests involving subscreens 2025-10-16 17:38:51 +09:00
Dan Balasescu
6fa4a7152f Refactor resuming / exiting events 2025-10-16 17:05:52 +09:00
Dan Balasescu
508c37c27b Fix missing entering / suspending events 2025-10-16 17:05:52 +09:00
Dan Balasescu
95f86a5c0e Fix matchmaking calling OnExiting() twice
Once prior to the confirmation dialog being displayed, then a second
time after the exit is confirmed.
2025-10-16 17:05:46 +09:00
Dan Balasescu
cd62f66d79 Fix multiplayer calling OnExiting() twice
Once via explicit call to `OnExiting()`, and the second time via
`.Exit()`.
2025-10-16 17:02:20 +09:00
kennyaja
3fbe777f33 Round instead of truncating slider control points to integer positions 2025-10-16 14:44:44 +07:00
Dean Herbert
b8ceb91a78 Merge pull request #35236 from tadatomix/song-select/coloured-group-ranked-status
Colour Ranked Status panel to the related status
2025-10-15 16:56:45 +09:00
Dean Herbert
9f61284371 Merge pull request #35300 from bdach/show-leaderboard-in-solo-spectator
Show leaderboard in solo spectator
2025-10-14 22:55:55 +09:00
Dean Herbert
3f18a1312e Merge pull request #35263 from bdach/user-tag-not-equals-filter
Fix not-equals user, artist, and title tag filters not working
2025-10-14 22:29:09 +09:00
Bartłomiej Dach
17758d5934 Merge pull request #34845 from diquoks/localisation/binding-settings
Localise "back" button in `BindingSettings`
2025-10-14 13:00:26 +02:00
Bartłomiej Dach
eaebe99a5c Merge pull request #35273 from diquoks/localisation/play
Localise `Break` & `PlayerSettings` on `Play` screen
2025-10-14 12:57:45 +02:00
Bartłomiej Dach
1edbb1d586 Show leaderboard in solo spectator
Closes https://github.com/ppy/osu/issues/35293.

The removed comment here says that "there's no guarantee" that
`LeaderboardManager` has the correct scores:

	a060ddb543/osu.Game/Screens/Play/SpectatorPlayer.cs (L22-L25)

but at least now, that's not correct because this is ensured via

	a060ddb543/osu.Game/Screens/Play/PlayerLoader.cs (L280-L286)

through which the solo spectator player is pushed:

	a060ddb543/osu.Game/Screens/Play/SoloSpectatorScreen.cs (L239)

The empty leaderboard provider is still valid however in the case of
multiplayer spectator, because there we don't really ever want to be
showing any leaderboards on the individual player instances.
2025-10-14 11:50:55 +02:00
Dean Herbert
a060ddb543 Merge pull request #35262 from bdach/song-select-move-realm-fetches-off-thread
Move realm refetches of beatmap in song select wedges off of update thread
2025-10-13 22:57:54 +09:00
Dean Herbert
f488974d39 Improve design of quick play endgame results (#35267) 2025-10-13 22:07:21 +09:00
Bartłomiej Dach
8e01fb70c3 Fix artist/title keyword filters not working properly with not-equals operator
Closes https://github.com/ppy/osu/issues/35264.
2025-10-13 11:39:59 +02:00
Bartłomiej Dach
a3f635588c Fix exclusion filters filtering out empty strings 2025-10-13 11:39:38 +02:00
Bartłomiej Dach
f8d3285ab4 Add failing test coverage for artist text filters also not working correct 2025-10-13 11:22:29 +02:00
Bartłomiej Dach
a73c325235 Fix code quality 2025-10-13 10:19:19 +02:00
Bartłomiej Dach
97739c39e7 Attempt to ensure RealmAccess waits for the async read before disposing itself 2025-10-13 09:27:21 +02:00
Denis Titovets
b58f03bc36 Move PlayerSettingsStrings & revert "Creator" back to "Mapper" 2025-10-13 10:13:41 +03:00
Denis Titovets
d870547a18 Localise Back button on settings' sidebar 2025-10-13 10:02:13 +03:00
James Wilson
28c846b4d9 Reading bonus hotfix for Traceable mod (#35266)
* Pass slider factor to visibility bonus correctly for TC

* Decrease reading bonuses for TC
2025-10-13 13:34:57 +09:00
Dean Herbert
8e36533f65 Quick play forward design work (#35253)
* Remove unnecessary information from matchmaking beatmap panel

* Move avatar overlay inside card for better layout

* Allow higher jumping when jumping in succession

* Exclude player panel avatars from masking

* Adjust player panel animations a bit further

* Add avatar-only display mode

* Fix round warmup test not working

* Remove dead test scenes

* Fix edge case where users are added to not-yet-loaded card

* Decouple `PlayerPanel` from `UserPanel`

* Fix remaining test failure (and rename test to match new naming)
2025-10-13 13:28:09 +09:00
Denis Titovets
e183e6bb88 Make edits based on reviews 2025-10-11 11:03:53 +03:00
Denis Titovets
5dc44fbdf9 Add some localisation to Play screen 2025-10-11 11:03:40 +03:00
Bartłomiej Dach
60544bf595 Merge branch 'master' into song-select/coloured-group-ranked-status 2025-10-10 12:37:10 +02:00
Bartłomiej Dach
8f0b8153eb Adjust test
- Don't hardcode numerical enum bounds
- Exclude `Approved` as it doesn't show in real contexts
2025-10-10 12:34:51 +02:00
Bartłomiej Dach
3070a0068a Change graveyard colour yet again
Editorial decision. The "brighter" colour was still too dark to be able
to even see any semblance of shade, or the triangles in the background.
2025-10-10 12:34:28 +02:00
Bartłomiej Dach
c5e17f5f0f Actually throw error instead of weirdly using white 2025-10-10 12:31:56 +02:00
Bartłomiej Dach
8439e6ec6c Remove strange comments 2025-10-10 12:30:57 +02:00
Bartłomiej Dach
9ebc5b0a35 Merge pull request #35255 from dnfd1/rotate
Fix default origin in skin editor when rotating multiple objects
2025-10-10 12:19:53 +02:00
Bartłomiej Dach
0b00191d71 Check for cancellation EVEN MORE aggressively 2025-10-10 12:06:57 +02:00
Bartłomiej Dach
0389da4559 Attempt to abort realm accesses on disposal 2025-10-10 10:30:31 +02:00
Bartłomiej Dach
40c447a792 Fix not-equals user tag filters not working
Omission / oversight from https://github.com/ppy/osu/pull/34568.

Addresses https://github.com/ppy/osu/discussions/35260.
2025-10-10 09:56:39 +02:00
Bartłomiej Dach
4132a7cd53 Add failing test coverage for not-equals user tag filter 2025-10-10 09:55:59 +02:00
Bartłomiej Dach
ca4c033b76 Remove redundant refresh calls 2025-10-10 09:20:23 +02:00
Bartłomiej Dach
85bbe13aa9 Move realm refetches of beatmap in song select wedges off of update thread
From local testing on release build (such that online beatmaps are
accessible) with a large database it seems that maybe this'll help with
recurrent complaints of 'stutters'.

Co-authored-by: Dean Herbert <pe@ppy.sh>
2025-10-10 08:51:12 +02:00
Dean Herbert
1f2928bf2f Merge pull request #35252 from bdach/song-select-present-sometimes-fails
Fix wrong beatmap shown when presenting a beatmap from results screen
2025-10-10 14:54:50 +09:00
Dean Herbert
94c7489c1c Add some logging when FindWithRefresh triggers a slow realm refresh 2025-10-10 13:36:28 +09:00
tadatomix
3d6a3e3eda Remove unused OsuColor variable 2025-10-10 02:34:09 +03:00
tadatomix
a0f295d6fe Make Graveyard panel colour even brighter 2025-10-10 02:32:07 +03:00
dnfd1
3bb6685e75 Merge branch 'ppy:master' into rotate 2025-10-09 08:52:21 -07:00
dnfd1
e3459eccf2 convert origin of rotation to screen space for selections multiple objects in skin editor 2025-10-09 08:36:01 -07:00
dnfd1
0d68e5eeeb add inline comment to explain larger limits 2025-10-09 05:21:08 -07:00
dnfd1
faad1753a4 Round OD limits to -15 and 15 2025-10-09 05:13:17 -07:00
dnfd1
fed04eb63b Merge branch 'ppy:master' into mania-difficultychange-limits 2025-10-09 05:10:50 -07:00
Dean Herbert
52f82c7e56 Merge pull request #35240 from bdach/song-select-preserve-selection-on-update-attempt-3
Fix song select V2 not preserving selection after an update operation
2025-10-09 17:30:28 +09:00
Bartłomiej Dach
3fc3a53521 Fix weird xmldoc issue
Rider was fine with it...
2025-10-09 10:17:55 +02:00
Dean Herbert
2136d95087 Merge pull request #35251 from smoogipoo/fix-broken-tests
Fix test failures during individual runs
2025-10-09 17:09:01 +09:00
Dean Herbert
c58d13b802 Merge pull request #35250 from smoogipoo/fix-test-leaks
Fix test scene leaks through RealmRulesetStore/RealmAccess
2025-10-09 17:08:07 +09:00
Bartłomiej Dach
b477790d3e Fix wrong beatmap shown when presenting a beatmap from results screen
- Closes https://github.com/ppy/osu/issues/35023.
- Supersedes / closes https://github.com/ppy/osu/pull/35107.
2025-10-09 09:52:22 +02:00
Bartłomiej Dach
e33de9b658 Add test demonstrating failure scenario 2025-10-09 09:46:32 +02:00
Dan Balasescu
6eaf91d31a Fix test failures during individual runs 2025-10-09 16:34:55 +09:00
Bartłomiej Dach
6da6edd1d1 Fix shift-clicking not working on extra size beatmap cards
Was broken due to double assignment to `Action`.
2025-10-09 08:59:26 +02:00
Dan Balasescu
6af5158bb4 Fix undisposed Realm subscription 2025-10-09 15:56:34 +09:00
Dan Balasescu
79c367d208 Fix test scene leaks through RealmRulesetStore/RealmAccess 2025-10-09 15:28:15 +09:00
dnfd1
348713d83d Allow OD to be overrided 2025-10-08 21:27:49 -07:00
dnfd1
cab0b3451f Override OD setting to set extended limits for mania EZ and HR 2025-10-08 21:26:45 -07:00
Dean Herbert
91019dcdf7 Merge pull request #35241 from bdach/song-select-crash-on-missing-group
Fix carousel sometimes crashing when attempting to select next random set
2025-10-09 06:20:22 +09:00
De4n
0cc2e4eaa0 Change the pool of available Ranked Statuses
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-10-08 20:09:06 +03:00
Dean Herbert
422392233b Update framework 2025-10-08 23:18:35 +09:00
Bartłomiej Dach
7b1e3cd537 Fix carousel sometimes crashing when attempting to select next random set
I'm not exactly sure on the reproduction scenario here, but I have had
switching ruleset with converts disabled crash on me a few times
today. It appears to happen sometimes when after the switch the expanded
group no longer exists in the set mapping, because a filter just ran and
removed that group from set of possible groups because there'd be no
beatmaps under it.

I tried to manufacture a quick test but it's not a quick one to test
because filtering intereference is required to reproduce, I think.
I will try again on request but I mostly just want to get this fix out
ASAP before I finish up for the day.
2025-10-08 15:13:00 +02:00
Bartłomiej Dach
30412ba3f2 Fix song select V2 not preserving selection after an update operation
Because the detached store exists and has a chance to actually
semi-reliably intercept a beatmap update operation, I decided to try
this. It still uses a bit of a heuristic in that it checks for
transactions that delete and insert one beatmap each, but probably the
best effort thus far?

Notably old song select that was already doing the same thing locally to
itself got a bit broken by this, but with some tweaking that *looks* to
be more or less harmless I managed to get it unbroken. I'm not too
concerned about old song select, mind, mostly just want to keep it
*vaguely* working if I can help it.
2025-10-08 14:42:26 +02:00
Dean Herbert
4622d39f41 Merge pull request #35233 from diquoks/quick-fix/sfx-mute-on-restart
Mute SFX when holding restart beatmap bind
2025-10-08 21:39:07 +09:00
Dean Herbert
0d5c041cac Merge pull request #35234 from diquoks/quick-fix/spinner-rpm-layering
Fix `spinner-rpm` being layered above `spinner-spin` / `spinner-clear`
2025-10-08 21:21:21 +09:00
Dean Herbert
ffe8b9f4c3 Merge pull request #35239 from bdach/song-select-weirdness
Fix current beatmap set being incorrectly expanded after collapsing group with current selection
2025-10-08 21:19:08 +09:00
Bartłomiej Dach
9ba9966078 Fix current beatmap set being incorrectly expanded after collapsing group with current selection
Noticed in passing. See preceding commit for failure scenario.

Regressed in https://github.com/ppy/osu/pull/35163.
2025-10-08 13:42:43 +02:00
Bartłomiej Dach
f1ec04114f Add failing test 2025-10-08 13:42:31 +02:00
Bartłomiej Dach
4337046680 Add test assets covering correct layering of spinner SPM metre 2025-10-08 12:39:48 +02:00
Bartłomiej Dach
1a522a19f1 Disallow zero-length sliders from specifying a non-zero number of repeats (#35220) 2025-10-08 16:01:04 +09:00
tadatomix
e4c5fc1906 Make Graveyard panel brighter 2025-10-07 23:29:34 +03:00
Denis Titovets
568ddc2d2d Fix spinner-rpm layering 2025-10-07 19:01:50 +03:00
Denis Titovets
0ebc90462d Mute SFX when holding restart beatmap bind 2025-10-07 18:42:42 +03:00
Dean Herbert
a08f7327b1 Merge pull request #35029 from ppy/pp-dev
Q3 SR & PP release
2025-10-07 19:07:58 +09:00
Dean Herbert
533c61e719 Merge pull request #35216 from diquoks/quick-fix/mods-deselection-diff
Fix mods deselection difference
2025-10-07 18:38:40 +09:00
Dean Herbert
64fba9470d Invert conditional to read a bit better 2025-10-07 18:07:58 +09:00
Dean Herbert
743a94bd22 Re-remove duplicate error functions 2025-10-07 16:30:40 +09:00
Dean Herbert
bda5737135 Merge branch 'master' into pp-dev 2025-10-07 16:11:54 +09:00
tadatomix
03bbbebbbc Fix chevron being too bright in most cases 2025-10-07 01:21:31 +03:00
tadatomix
97c95de94a Add a test for the new group 2025-10-07 01:21:01 +03:00
tadatomix
3dcbcb5f64 Make initial work to create a ranked status style 2025-10-07 01:06:46 +03:00
Dean Herbert
19718c706a Merge pull request #35221 from bdach/adjust-tag-threshold
Adjust display tag threshold to match web
2025-10-06 20:57:26 +09:00
Bartłomiej Dach
4b3d2b0c57 Merge pull request #35222 from peppy/fix-left-hover-not-always
Fix hovering left area in song select not always activating reset action
2025-10-06 12:17:56 +02:00
Dean Herbert
df58dc0ca2 Fix hovering left area in song select not always activating reset action 2025-10-06 18:23:33 +09:00
Dean Herbert
d08b5a72b7 Add failing test scene covering song select left hover action not always activating 2025-10-06 18:21:10 +09:00
Bartłomiej Dach
b286f05c78 Adjust display tag threshold to match web
Follow-up to https://github.com/ppy/osu-web/pull/12381 - tags will glow
green starting from 5 votes rather than 10 to match the new threshold
web-side.
2025-10-06 11:09:54 +02:00
Dean Herbert
b3ed7717a8 Merge pull request #35185 from nekodex/matchmaking-more-sfx
Yet more matchmaking SFX work
2025-10-06 18:04:22 +09:00
Dean Herbert
bc7e02c30b Delay round increment sound to match animation better 2025-10-06 18:03:53 +09:00
Dean Herbert
557df19bf4 Merge pull request #35184 from bdach/song-select-reselect-group-for-selection-when-moving-left
Expand group that current selection resides in when moving mouse to left side of song select
2025-10-06 17:47:20 +09:00
Dean Herbert
8a450563fd Merge branch 'master' into song-select-reselect-group-for-selection-when-moving-left 2025-10-06 16:57:57 +09:00
Dean Herbert
f9a226d68e Merge pull request #35189 from bdach/catcher-fail-state-on-tiny-droplet-miss
Fix missing tiny droplets not changing catcher animation state to fail
2025-10-06 16:42:10 +09:00
Dean Herbert
dd846dcc52 Merge pull request #35176 from bdach/local-modified-beatmap-regressions
Fix a few issues regarding incorrect treatment of locally-modified beatmaps
2025-10-06 16:22:09 +09:00
Dean Herbert
71ae1d34cd Merge pull request #35178 from bdach/song-select-loses-selection-if-convert
Fix selection being changed on re-entering song select when a converted beatmap is selected
2025-10-06 15:53:42 +09:00
Bartłomiej Dach
dd8dfc04b3 Merge pull request #35199 from peppy/editor-timing-panel-current-row-visibility
Adjust colouring to make current row in timing visualisation more obvious
2025-10-06 08:39:05 +02:00
Dean Herbert
2f6bd6605f Update resources 2025-10-06 14:49:42 +09:00
Dean Herbert
e76d1ae619 Merge pull request #35188 from bdach/song-select-do-not-flash-wrong-leaderboard
Fix wrong leaderboard flashing briefly when quickly changing beatmaps
2025-10-06 14:43:33 +09:00
Dean Herbert
c0a7c97185 Merge pull request #35179 from bdach/song-select-scroll-closest-expanded-thing-into-view
Attempt to scroll carousel to nearest expanded panel when the current selection is filtered out
2025-10-06 14:42:54 +09:00
Denis Titovets
dbd48bc3a1 Fix mods deselection difference 2025-10-06 01:58:49 +03:00
Dean Herbert
a2770a8674 Adjust colouring to make current row in timing visualisation more obvious 2025-10-04 16:13:48 +09:00
Bartłomiej Dach
67041254db Fix missing tiny droplets not changing catcher animation state to fail
Addresses https://github.com/ppy/osu/discussions/35182.

The source as it is would have you believe that this is correct and
intentional but I'm not so sure about that. For one thing, I
cross-checked stable, and sure, missing tiny droplets does change the
state to fail over there. For another, the guard in master at

	5e642cbce7/osu.Game.Rulesets.Catch/UI/Catcher.cs (L250)

is very suspicious, given that it is dead in cause of tiny droplets
because of a preceding guard:

	5e642cbce7/osu.Game.Rulesets.Catch/UI/Catcher.cs (L227-L228)

Looking into blame, the tiny droplet guard originates at
e7f1f0f38b, wherein it looks to have been
aimed at handling *hyperdash* state specifically. Later, the logic has
been moved around and around like five times; at
7069cef9ce, the catcher animation logic
was added *below* the hyperdash-aimed guard without the comment being
updated in any way; 5a5c956ced moved the
logic from `CatcherArea` to `Catcher`, while simultaneously changing
the inline comment to no longer mention hyperdashing; and finally,
1d669cf65e added specific testing of tiny
droplets not changing catcher animation state, which I wager to be
back-engineered from the implementation as-it-was rather than
supported by any actual ground truth.

For additional reference:

- catcher animation logic in stable is at 67795dba3c/osu!/GameModes/Play/Rulesets/Fruits/RulesetFruits.cs#L411-L463
- hyperdash application logic in stable is at 67795dba3c/osu!/GameModes/Play/Rulesets/Fruits/RulesetFruits.cs#L165-L171
2025-10-03 14:52:33 +02:00
Bartłomiej Dach
68d5f53cc7 Adjust test to exercise actual desired behaviour 2025-10-03 14:39:48 +02:00
Bartłomiej Dach
a30c7f51d0 Fix wrong leaderboard flashing briefly when quickly changing beatmaps
Closes https://github.com/ppy/osu/issues/33743.
2025-10-03 12:35:58 +02:00
Jamie Taylor
4e90a2aee2 Code style fixes 2025-10-03 18:04:55 +09:00
Jamie Taylor
e24df0b9d0 Change 'quick play' button to use the 'daily' sample for now 2025-10-03 17:17:23 +09:00
Jamie Taylor
27ff2a7d49 Add SFX for round transitions 2025-10-03 17:16:45 +09:00
Jamie Taylor
3cb85f743a Rework StageDisplay SFX 2025-10-03 17:16:21 +09:00
Jamie Taylor
43878f6d33 Add SFX for enqueueing and also a looping 'waiting' SFX when in certain matchmaking states 2025-10-03 17:10:52 +09:00
Jamie Taylor
60dc2c8876 Add ducking effect on match found 2025-10-03 17:05:00 +09:00
Bartłomiej Dach
87128453d6 Expand group that current selection resides in when moving mouse to left side of song select
Closes https://github.com/ppy/osu/issues/33557.
2025-10-03 09:27:05 +02:00
Bartłomiej Dach
ae4e015352 Add failing test scene 2025-10-03 09:24:37 +02:00
Bartłomiej Dach
007de10e2b Attempt to scroll carousel to nearest expanded panel when the current selection is filtered out
Addresses https://github.com/ppy/osu/issues/33443, maybe.

I considered adding tests but they'd likely be janky and take a long
time to write, so decided against until there's a demand for it.
2025-10-02 14:28:39 +02:00
Bartłomiej Dach
3d5dc60cfe Fix selection being changed on re-entering song select when a converted beatmap is selected
Closes https://github.com/ppy/osu/issues/34062.

The root cause of the issue is that `OnEntering()` calls
`onArrivingAtScreen()`, which calls `ensureGlobalBeatmapValid()`, which
would call `checkBeatmapValidForSelection()` with a `FilterCriteria`
instance retrieved from the `FilterControl`.

The problem with that is at the time that this call chain is happening,
`FilterControl` is not yet loaded, which means in particular that it has
not bound itself to the config bindable, as that happens on
`LoadComplete()`:

	bff07010d1/osu.Game/Screens/SelectV2/FilterControl.cs (L198)

To resolve this, retrieve the bindable in `SongSelect` itself, which
ensures it is valid for reading at the time the above call chain
happens.
2025-10-02 13:27:43 +02:00
Bartłomiej Dach
e7076b9582 Add failing test case 2025-10-02 13:24:24 +02:00
Bartłomiej Dach
2a85f7b7c8 Do not attempt to retrieve score submission tokens for locally-modified beatmaps
Because it is 99% sure that doing so will fail and spam the user with
"this beatmap doesn't match the online version" notifications, and
because the map status is "locally modified", they should be pretty
aware of that already. This fixes the primary mode of the failure that
https://github.com/ppy/osu/pull/35173 was attempting to hack around.

This will have regressed somewhere around the time that BSS went live,
because at that point the editor stopped resetting online IDs for
beatmaps that got locally modified, making the `beatmapId <= 0` guards
no longer prevent attempts of submission.
2025-10-02 09:16:17 +02:00
Bartłomiej Dach
44a1a5ffc7 Add failing test coverage for no score submission attempt on known locally modified beatmap 2025-10-02 09:16:17 +02:00
Bartłomiej Dach
365cdfd40e Do not overwrite "locally modified" beatmap set status when performing online lookups in song select
A relatively recent regression. It's maybe not a huge one, in that it
probably doesn't matter all that much, but it is somewhat important to
keep the "locally modified" status of the set for as long as possible.

One reason for that is that keeping the "locally modified" status will
pull up a dialog when the user attempts to update the beatmap, warning
them that they will lose their local changes - this dialog will not show
if the online lookup flow is allowed to overwrite the map status with
something else.
2025-10-02 09:16:15 +02:00
Bartłomiej Dach
aad321a0b8 Fix clicking the osu! logo when in the multiplayer submenu opening solo play instead (#35175) 2025-10-02 16:03:46 +09:00
Dean Herbert
37a11b5592 Merge pull request #35154 from smoogipoo/matchmaking-events
Add structure and support for jumping in quick play rooms
2025-10-02 13:57:00 +09:00
Dean Herbert
565a2866ea Merge pull request #35169 from bdach/song-select-enter-on-filtered-out-carousel-should-start-map
Fix pressing Enter not starting current global beatmap if carousel is fully filtered out
2025-10-01 23:44:01 +09:00
Dean Herbert
c9a6a4887c Merge pull request #35167 from bdach/carousel-panels-consistent-update-button
Use consistent ordering of update button on carousel beatmap panels
2025-10-01 21:59:03 +09:00
Bartłomiej Dach
9b78187d29 Fix pressing Enter not starting current global beatmap if carousel is fully filtered out
Closes https://github.com/ppy/osu/issues/34693.
2025-10-01 14:31:48 +02:00
Bartłomiej Dach
0230a27de6 Add failing test case 2025-10-01 14:17:16 +02:00
Bartłomiej Dach
ccf3151172 Use consistent ordering of update button on carousel beatmap panels
Closes https://github.com/ppy/osu/issues/34810.

The reason why I touched it in this direction and not the other is only
because the standalone panel positioning of the button was touched last
in 92ed964627, thus I changed the set
panel to match that.
2025-10-01 13:49:54 +02:00
Bartłomiej Dach
b980183e98 Merge pull request #35126 from Joehuu/song-select-silver-terminology
Use silver S/SS terminology when grouping by rank/grade in song select
2025-10-01 13:30:50 +02:00
Jinkku
b7d36cffd4 Refactor spritesheet-based icons to be single-file based (#34976)
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
Co-authored-by: Dean Herbert <pe@ppy.sh>
2025-10-01 13:30:06 +02:00
Dean Herbert
345ae29770 Merge pull request #35163 from bdach/carousel-stop-re-expanding-group
Do not forcibly re-expand carousel groups on refilters if the user manually collapsed them
2025-10-01 16:33:59 +09:00
Bartłomiej Dach
6bf589af88 Use slightly safer method of converting to string 2025-10-01 08:50:39 +02:00
Bartłomiej Dach
03455ba683 Merge branch 'master' into song-select-silver-terminology 2025-10-01 08:32:07 +02:00
Dean Herbert
1f7aa2fe5e Merge pull request #35158 from bdach/fix-carousel-teleports-on-delete
Fix song select carousel sometimes teleporting on beatmap set deletion
2025-10-01 15:16:26 +09:00
Dean Herbert
e26e44cd45 Merge pull request #35159 from bdach/carousel-target-vertical-center
Add half-height-of-selected-panel adjustment to carousel scroll target
2025-10-01 15:00:14 +09:00
Dean Herbert
5ab40e4b73 Merge pull request #35160 from bdach/carousel-not-switching-beatmap-on-ruleset-change
Fix song select not changing global beatmap correctly when switching rulesets
2025-10-01 13:47:08 +09:00
Joseph Madamba
ee638492bf Remove now unused description attributes from ScoreRank 2025-09-30 10:55:47 -07:00
Joseph Madamba
7d81ff8115 Fix jank GetRankLetter() method 2025-09-30 10:52:55 -07:00
Joseph Madamba
114e7f5c61 Rename GetRankName to GetRankLetter 2025-09-30 10:50:34 -07:00
Dean Herbert
e2b9288716 Merge pull request #35161 from bdach/song-select-refetch-online-on-reenter
Forcibly refetch online beatmap content on re-entering song select
2025-09-30 23:20:38 +09:00
Dean Herbert
919c47b918 Merge pull request #35111 from smoogipoo/quick-play-keybinds
Add keybinds to matchmaking queue screen
2025-09-30 23:19:33 +09:00
Bartłomiej Dach
bc4d5d07d7 Do not forcibly re-expand carousel groups on refilters if the user manually collapsed them
RFC. Closes https://github.com/ppy/osu/issues/35091.
2025-09-30 15:24:48 +02:00
Bartłomiej Dach
4b2f3efcbd Add tests covering desired UX 2025-09-30 15:24:35 +02:00
Bartłomiej Dach
33ddb84633 Forcibly refetch online beatmap content on re-entering song select
Closes https://github.com/ppy/osu/issues/34546.
2025-09-30 13:58:10 +02:00
Bartłomiej Dach
f66c8d10e0 Fix song select not changing global beatmap correctly when switching rulesets
Closes https://github.com/ppy/osu/issues/35113.

Regressed in dfed564bda - setting
`Carousel.CurrentSelection` was not all that
`requestRecommendedSelection()` was doing there...

A potential point of discussion is whether this global beatmap switch
should be debounced or instant. I'm not sure I have a particularly
well-formed opinion on that. One argument in favour of not debouncing is
that if you look closely at the left side of the screen while the
debounce is in progress, you can still sort of see the broken behaviour
happen - it just doesn't stay there forever.

Thankfully `ensureGlobalBeatmapValid()` being called in every scenario
on screen suspension prevented this bug from being any worse than it is
right now.
2025-09-30 13:34:26 +02:00
Bartłomiej Dach
38278eaaac Merge pull request #35157 from peppy/update-framework
Update framework
2025-09-30 13:25:39 +02:00
Bartłomiej Dach
ac2df49c35 Demonstrate failure in test 2025-09-30 13:19:03 +02:00
Bartłomiej Dach
2edd49d2c0 Add half-height-of-selected-panel adjustment to carousel scroll target
Intended to address https://github.com/ppy/osu/issues/35147, maybe?

The old carousel would target the vertical center of the active panel
when scrolling:

	b9e1b6969e/osu.Game/Screens/Select/BeatmapCarousel.cs (L948)

This was not in place in the new carousel, weirdly, which was targeting
the top-left corner of the selected panel.
2025-09-30 12:57:24 +02:00
Dean Herbert
a078d4bdb4 Merge pull request #35149 from smoogipoo/qp-fix-nullref
Fix nullref when users leave quick-play rooms
2025-09-30 19:23:05 +09:00
Dean Herbert
6e39e714e1 Refactor to simplify sample handling 2025-09-30 19:22:16 +09:00
Dean Herbert
d512adb971 Merge branch 'master' into quick-play-keybinds 2025-09-30 19:07:29 +09:00
Bartłomiej Dach
a3e09a1c31 Fix song select carousel sometimes teleporting on beatmap set deletion
Closes https://github.com/ppy/osu/issues/35010.

The issue here does not reproduce consistently, and is more or less
random in presentation. That said, using a large enough realm database
more or less ensures that the issue will present itself (in testing on a
large realm db, the failure rate is around ~50%).

This actually regressed in https://github.com/ppy/osu/pull/34842. The
core failure in this case is here:

	fd412618db/osu.Game/Screens/SelectV2/BeatmapCarousel.cs (L161)

The `CheckModelEquality()` call above is comparing two `BeatmapInfo`s,
but a84c364e44 changed the
`BeatmapInfo`-comparing path of `CheckModelEquality()` to use
`GroupedBeatmap` instead. Due to this, `CheckModelEquality()` falls back
to reference equality comparison for `BeatmapInfo`s. When that reference
comparison fails, the carousel stops detecting that the current
selection was deleted from under it correctly, and therefore the
proximity-based selection logic never runs.

Due to the human-obvious mechanism of failure and relatively easy
manual reproduction I've decided not to try and add tests for this,
as they are likely to take a long time to write due to the mechanism
of failure being incorrect use of reference equality specifically. That
said, I can try on request.
2025-09-30 11:41:47 +02:00
Dan Balasescu
e636a09e0f Add ability to jump in quick play 2025-09-30 18:38:30 +09:00
Dan Balasescu
3ebb72a20a Add avatar action request/event models 2025-09-30 18:32:04 +09:00
Dean Herbert
256483165f Update framework 2025-09-30 18:10:34 +09:00
Dean Herbert
1a084f28ff Merge pull request #35056 from OliBomby/anchor-snap
Allow snapping slider control points to nearby objects in the editor
2025-09-30 18:01:02 +09:00
Dean Herbert
a0ff7728b9 Merge pull request #35057 from OliBomby/snap-to-anchor
Allow snapping to nearby visible slider control points in the editor
2025-09-30 18:00:31 +09:00
Dean Herbert
9860bba2f3 Merge branch 'master' into qp-fix-nullref 2025-09-30 17:46:53 +09:00
Dean Herbert
bb9b4a2827 Merge pull request #35151 from bdach/maybe-fix-bss-clicking
Ensure submission progress sample is stopped when transitioning into a final state
2025-09-30 17:29:21 +09:00
Bartłomiej Dach
057406c910 Simplify logic further 2025-09-30 08:32:53 +02:00
Bartłomiej Dach
062174d874 Merge pull request #35049 from AeroKoder/fix-scaling-sliders
Fix certain sliders incorrectly registering as a horizontal/vertical only slider.
2025-09-30 15:17:05 +09:00
Dan Balasescu
d31df5bbc7 Make quick play chat not hold focus 2025-09-30 12:35:33 +09:00
AeroKoder
41698d5848 Updated moveSelectionInBounds in OsuSelectionScaleHandler to match the one in OsuSelectionHandler 2025-09-29 09:27:01 -07:00
Dean Herbert
838b8d3013 Merge pull request #35145 from tadatomix/song-select/coloured-group-ranks
Colour Rank Achieved panels to the related rank
2025-09-29 23:40:28 +09:00
Bartłomiej Dach
2c39e1e9db Ensure submission progress sample is stopped when transitioning into a final state
Probably closes https://github.com/ppy/osu/issues/35138. I'm not sure. I
only got the issue to reproduce once, on dev, using a very large
archive that was uploading really slowly, and then never again.

The working theory is that basically handling of `progressSampleChannel`
is quite dodgy and it could possibly, in circumstances unknown, be
allowed to play forevermore after transitioning to failed / canceled
state. Success state does not get this treatment because it has special
logic to set progress to 1.
2025-09-29 15:30:45 +02:00
OliBomby
18549ea7dc Remove all linq calls from getScreenSpaceControlPointNodes 2025-09-29 15:07:03 +02:00
OliBomby
d76dce76ec dont snap inherited bspline type control points to nearby objects 2025-09-29 14:44:12 +02:00
OliBomby
40cbe58220 Revert inline method for code abstraction 2025-09-29 14:23:19 +02:00
Bartłomiej Dach
68523a637a Merge pull request #35128 from peppy/matchmaking-design-work
Switch to using more standardised beatmap cards in quick play
2025-09-29 20:15:10 +09:00
Dean Herbert
3f5b71fdc3 Always explicitly assign the action for beatmap cards 2025-09-29 17:31:45 +09:00
Dan Balasescu
573d639238 Fix nullref when users leave quick-play rooms 2025-09-29 16:56:48 +09:00
Dan Balasescu
82beeec730 Add failing test 2025-09-29 16:55:54 +09:00
Bartłomiej Dach
5336bcd71d Merge pull request #34934 from Valerus9/fixtestdouble
Fix TestDouble failing on systems where the decimal separator isn't a dot
2025-09-29 16:46:32 +09:00
Bartłomiej Dach
47b6b70cae Avoid duplicating rank name colour constants 2025-09-29 09:44:05 +02:00
Bartłomiej Dach
fd412618db Adjust initial pool size for group rank displays
11 is excessive. There can ever be at most 9 of these panels, ever,
because there are at most 9 possible letter grades at this time (F, D,
C, B, A, S, S+, SS, SS+).
2025-09-29 09:42:36 +02:00
Bartłomiej Dach
9dc79e6f0d Avoid passing the same thing three times 2025-09-29 09:42:33 +02:00
Bartłomiej Dach
ba3d7392bf Merge pull request #35120 from LumpBloom7/fix-toolbox-tooltip
Fix composition tool tooltip not changing text when enabled
2025-09-29 16:04:15 +09:00
Bartłomiej Dach
bed9fb0ba6 Merge pull request #35044 from Joehuu/old-badge-alignment
Match profile badge centre alignment with web
2025-09-29 15:57:47 +09:00
Bartłomiej Dach
9257e62bac Merge branch 'master' into fixtestdouble 2025-09-29 08:43:49 +02:00
Bartłomiej Dach
70f683e7fa Use slightly nicer way of invarianting rate adjust setting value 2025-09-29 08:39:01 +02:00
Bartłomiej Dach
d1cf248b9a Remove redundant double string invariance 2025-09-29 08:33:18 +02:00
Bartłomiej Dach
295adf9f28 Add actual test coverage for relevant failure 2025-09-29 08:32:09 +02:00
tadatomix
6ac4f482ee Add a new test for Rank Achieved panels 2025-09-28 23:10:32 +03:00
tadatomix
33791318fe Call a new panel style, when Rank Achieved grouping is picked 2025-09-28 22:56:32 +03:00
tadatomix
cf20bbbf80 Add a new Rank Achieved panel to BeatmapCarousel.cs 2025-09-28 22:55:22 +03:00
tadatomix
55ef221390 Add a separate panel for RankAchieved group 2025-09-28 22:49:45 +03:00
Dean Herbert
0f8d8780d3 Adjust stage display animation to linger for longer 2025-09-26 18:26:11 +09:00
Dean Herbert
b743506207 Keep panel backgrounds loaded 2025-09-26 18:26:11 +09:00
Dean Herbert
0a17a3c4ed Use BeatmapCard for matchmaking beatmap display 2025-09-26 18:09:05 +09:00
Dean Herbert
da80b61f38 Allow visibly disabling the "go to beatmap" button
Easiest way to make this work without rewriting the layout logic.

I think it makes sense to have the button still exist there but not be
usable on certain screens.
2025-09-26 18:08:47 +09:00
Dean Herbert
badeb24d56 Change beatmap in selection panels to always be non-null 2025-09-26 16:53:22 +09:00
Dean Herbert
76c3043913 Improve selection animation border isolation
I'm not final on the design, just wanted to split it out into an actual
border element rather than an "underlay".
2025-09-26 16:48:56 +09:00
Derrick Timmermans
c66cc5ebb1 Handle disabled text in composition tool button 2025-09-26 09:28:04 +02:00
Dean Herbert
9dc5605d95 Scale active stage larger 2025-09-26 16:15:37 +09:00
Dean Herbert
3af4edf051 Remove pointless TestSceneMatchmakingScreenStack
Should always be using `TestSceneMatchmakingScreen` right?
2025-09-26 15:48:29 +09:00
Dean Herbert
e9063dcf57 Simplify flash layer 2025-09-26 15:48:29 +09:00
Dean Herbert
d690477776 Add context menu to show beatmap details 2025-09-26 14:52:23 +09:00
Dean Herbert
7879e091c0 Simplify avatar handling in beatmap selection panels 2025-09-26 14:39:20 +09:00
Dean Herbert
702511c918 More matchmaking renames and spacing adjusts 2025-09-26 14:22:55 +09:00
Dean Herbert
e1ba1b45b0 Adjust matchmaking naming, namespaces, xmldoc (#35123)
* Adjust matchmaking naming, namespaces, xmldoc

* Change partial filenames to use `.` instead of `_` separator
2025-09-26 12:17:28 +09:00
Joseph Madamba
8ea9e2e4bb Change non-localisable sh/xh to correct terminology 2025-09-25 15:45:12 -07:00
Joseph Madamba
ef88a3530a Use silver S/SS terminology when grouping by rank/grade in song select 2025-09-25 14:18:41 -07:00
Derrick Timmermans
df795da070 Fix composition tool tooltip not changing text when enabled 2025-09-25 10:44:05 +02:00
Dean Herbert
12e29f0bcc Attempt to fix flaky TestGameplaySettingsDoesNotExpandWhenSkinOverlayPresent
See https://github.com/ppy/osu/pull/35118/checks?check_run_id=51202910556.
2025-09-25 15:56:48 +09:00
Dean Herbert
ff54908687 Matchmaking stage display / screen layout design improvements (#35118) 2025-09-25 15:16:22 +09:00
Dan Balasescu
3c37fb11be Add sounds 2025-09-24 19:47:13 +09:00
Dan Balasescu
3176006510 Add select keybind to queue screen buttons 2025-09-24 19:46:54 +09:00
Dan Balasescu
183ccbf792 Add left/right keybinds to pool selector 2025-09-24 19:46:54 +09:00
Dean Herbert
f1ffc1dc33 Merge pull request #35109 from smoogipoo/matchmaking-fix-chat
Fix matchmaking chat not working
2025-09-24 18:59:24 +09:00
Dan Balasescu
b3cfded8f2 Fix matchmaking chat not working 2025-09-24 18:58:01 +09:00
Dean Herbert
67291c1a42 Fix match-found not playing due to incorrect case in path 2025-09-24 18:55:02 +09:00
Dean Herbert
93afc83c4b Merge pull request #35105 from smoogipoo/improve-mm-testing
Various improvements to matchmaking testability
2025-09-24 16:26:43 +09:00
Andrei Zavatski
57e5fe7265 Improve FailRetryDisplay performance (#35101) 2025-09-24 15:53:16 +09:00
Dean Herbert
e082d24bab Merge pull request #35106 from smoogipoo/matchmaking-fix-player-list
Fix players positioning on next matchmaking round
2025-09-24 15:38:17 +09:00
Dan Balasescu
13cb5deca3 Fix players positioning on next matchmaking round 2025-09-24 14:44:27 +09:00
Dan Balasescu
3556d6c8c8 Reduce number of picks shown 2025-09-24 14:28:04 +09:00
Dan Balasescu
83dafb4ef9 Fix incorrect default room types 2025-09-24 14:28:04 +09:00
Dan Balasescu
9df3bd9a98 Add stage-changing helper, use in test scenes 2025-09-24 14:28:01 +09:00
Dan Balasescu
597a06ac38 Set initial matchmaking room state 2025-09-24 13:42:55 +09:00
Dean Herbert
a129345a82 Merge pull request #35098 from smoogipoo/fix-intermittent-test
Attempt to fix intermittent tests
2025-09-24 03:00:31 +09:00
Dean Herbert
8660578d2c Merge pull request #35053 from smoogipoo/matchmaking-player-list-modes
Add display styles to matchmaking player list
2025-09-24 02:59:57 +09:00
Dean Herbert
bf63b6f9f0 Simplify lookup method to appease inspection
See https://github.com/ppy/osu/pull/35100/files.
2025-09-23 22:55:43 +09:00
Dean Herbert
85ea278e1d Merge pull request #35100 from smoogipoo/matchmaking-match-start-sample
Play gameplay start sample in matchmaking
2025-09-23 22:54:31 +09:00
Dan Balasescu
37e661b27e Fix intermittent collection dropdown tests 2025-09-23 18:23:41 +09:00
Dan Balasescu
ff6c6083b4 Mark spinner rewind test as flaky 2025-09-23 18:18:07 +09:00
Dan Balasescu
aba0d2c1d3 Play gameplay start sample in matchmaking 2025-09-23 17:52:33 +09:00
Dan Balasescu
3789010dd5 Attempt to fix intermittent test 2025-09-23 15:09:45 +09:00
Dan Balasescu
82ac42cae3 Replace nested ternaries with ifs 2025-09-23 13:45:10 +09:00
Dean Herbert
87061959ea Fix failing screen test 2025-09-23 12:49:34 +09:00
Dean Herbert
1840363713 Add one more temoprary workaround for rider failings 2025-09-21 13:09:27 +09:00
qinvvv
b91ff8a5c5 Fix osu!mania legacy skin WidthForNoteHeightScale not being used (#35050)
* Add osu!mania legacy skin widthForNoteHeightScale

* Ensure WidthForNoteHeightScale correctly defaults to MinimumColumnWidth
2025-09-19 10:53:25 +09:00
Olivier Schipper
9fddce92e9 Reword inline comments 2025-09-19 01:22:35 +02:00
Olivier Schipper
7c5278ea45 Fix incorrect skip count 2025-09-19 01:09:42 +02:00
Olivier Schipper
0e523d3eb7 Allow snapping to visible slider control points 2025-09-19 00:30:31 +02:00
Olivier Schipper
55a4c75e76 Allow slider control points to snap to nearby objects
and a bit of code cleanup to reduce code duplication with the slider head anchor snapping
2025-09-18 21:26:49 +02:00
Dean Herbert
c07dd72f6d Merge pull request #35037 from bdach/totp
Add client-side support for TOTP authentication
2025-09-18 23:50:07 +09:00
Dean Herbert
c320c9df1c Merge branch 'master' into totp 2025-09-18 22:53:20 +09:00
Dan Balasescu
c08d88eb7f Adjust namespaces 2025-09-18 16:28:25 +09:00
Dan Balasescu
5eaf376a60 Decrease scale of panels 2025-09-18 16:28:25 +09:00
Dan Balasescu
b26a1b6330 Add display style to PlayerPanelList 2025-09-18 16:28:25 +09:00
AeroKoder
6dc3432735 Fix certain slider shapes incorrectly registering as a horizontal/vertical only slider. 2025-09-17 15:34:18 -07:00
Joseph Madamba
e0c86b3048 Match profile badge centre alignment with web 2025-09-16 20:37:44 -07:00
Givy120
7852df639a Use DeltaTime in RhythmEvaluator to increase stability (#32790)
* Update RhythmEvaluator.cs

* Rename `StrainTime` into `AdjustedDeltaTime`

---------

Co-authored-by: StanR <hi@stanr.info>
2025-09-16 13:31:14 +00:00
Bartłomiej Dach
37f58e5c80 Add client-side support for TOTP authentication
Closes https://github.com/ppy/osu/issues/34972.
2025-09-16 10:36:34 +09:00
Dean Herbert
0dbee70ca9 Merge pull request #35022 from smoogipoo/matchmaking-fix-errors
Fix errors in gameplay stage of matchmaking
2025-09-15 22:25:58 +09:00
James Wilson
2749184c38 Remove databasing of MechanicalDifficulty and ReadingDifficulty attributes (#35028)
* Remove databasing of `MechanicalDifficulty` and `ReadingDifficulty` attributes

* Update attribute IDs
2025-09-15 13:46:00 +03:00
James Wilson
0a3844d3ef Update tests (#35026) 2025-09-15 12:46:27 +03:00
Eloise
c7f50f35b7 osu!taiko final balancing before deploy (#34962)
* Change maximum UR estimation + buff rhythm

* Penalty for classic ezhd

* Buff mono bonus to counterbalance logic fix

* New miss penalty + slightly nerf length bonus

* Adjust rhythm values

* Adjust penalty and buff high SR acc

* Exclude HDFL from hidden reading penalties

* Make comment a lil nicer

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-09-15 09:43:26 +01:00
Dan Balasescu
9577472c9e Fix errors in gameplay stage of matchmaking 2025-09-15 12:49:42 +09:00
Dean Herbert
55fe927af0 Merge pull request #34985 from nekodex/matchmaking-sfx
More matchmaking SFX work
2025-09-14 14:38:10 +09:00
Dean Herbert
4ccfebe842 Update resources 2025-09-14 14:15:16 +09:00
Dean Herbert
b7d6e76d19 Merge pull request #35000 from bdach/lazer-judgement-counter-misalign 2025-09-13 22:29:58 +09:00
Valerus9
e34b0659da Fix testtooltip failure 2025-09-13 06:44:29 +02:00
Bartłomiej Dach
e73e9275ba Fix argon judgement counter looking misaligned with wireframe off
Closes https://github.com/ppy/osu/issues/34959.

`ArgonCounterTextComponent` is pretty terrible and prevents being able
to fix the issue easily. The core issue is that this is the first
instance of the component's usage where the label text can be longer
than the counter in the X dimension, so the total width of any counter
is equal to max(label width, counter width), and the label will be
aligned to the left of that width, while the counter will be aligned to
the right of that width.

The fix sort of relies on the fact that I don't expect *any* consumer of
`ArgonCounterTextComponent` that meaningfully uses the wireframe digits
to want the non-wireframe digits to be aligned to the *left* rather than
the right. It's not what I'd expect any segmented display to work.
(There are usages that specify `TopLeft` anchor, but they usually
display the same number of wireframe and non-wireframe digits, so for
them it doesn't really matter if the digits are left-aligned to the
wireframes or not.)
2025-09-13 11:11:45 +09:00
Bartłomiej Dach
a9c021ce04 Demonstrate failure in test 2025-09-13 10:50:33 +09:00
d47e26f1ae now reproducible! 2025-09-12 23:44:01 +03:00
b0e5ae1109 some minor very UI changes 2025-09-12 22:39:07 +03:00
47b859ab17 l10n: replace "osu!" with "game" where suitable 2025-09-12 21:59:58 +03:00
5e523eb0b1 bump to 2025.912.0 2025-09-12 18:10:03 +03:00
Jamie Taylor
9a2513230c Add SFX for stage progression feedback 2025-09-12 18:27:16 +09:00
Jamie Taylor
ccc5ca5d80 Rework matchmaking cloud SFX 2025-09-12 18:25:08 +09:00
Jamie Taylor
9b9e7a8f75 Refactor selection roulette SFX logic 2025-09-12 18:23:02 +09:00
Dean Herbert
d912f8c3b9 Lazer release 2025-09
For tagging purposes.
2025-09-12 16:30:29 +09:00
Dean Herbert
5b781655c1 Merge pull request #34815 from smoogipoo/matchmaking
Add matchmaking
2025-09-11 18:17:10 +09:00
Dean Herbert
644b797734 Add temporary workaround for rider bug (attempt 2) 2025-09-11 16:21:55 +09:00
Dean Herbert
e5fbf62ff5 Revert "Add temporary workaround for rider bug"
This reverts commit bcff6be5f6.
2025-09-11 16:21:40 +09:00
Dean Herbert
bcff6be5f6 Add temporary workaround for rider bug 2025-09-11 16:21:03 +09:00
Dean Herbert
0c68a91b4c Fix main menu key tests 2025-09-11 16:09:17 +09:00
Dean Herbert
69a0ac6c76 For tachyon release 2025-09-11 16:00:41 +09:00
Dean Herbert
619a6e7321 Merge branch 'master' into matchmaking 2025-09-11 15:11:01 +09:00
Dean Herbert
83c6e57984 Update resources 2025-09-11 15:00:21 +09:00
Dean Herbert
1ea17129cc Adjust debounce again to handle key down state 2025-09-11 13:25:24 +09:00
Bartłomiej Dach
1f4f6ce4fe Merge pull request #34966 from peppy/fix-carousel-thing
Fix beatmap carousel not holding selection after refilter in some cases
2025-09-10 10:31:22 +02:00
Dean Herbert
231b366e5e Merge pull request #34958 from smoogipoo/fix-skin-editor-initial-state
Fix mangled initial undo state on fresh skins
2025-09-10 17:30:30 +09:00
Dan Balasescu
762fee91ed Merge branch 'master' into fix-skin-editor-initial-state 2025-09-10 17:04:51 +09:00
Bartłomiej Dach
4d76c467f8 Merge pull request #34910 from CloneWith/update/drawable-date
Make DrawableDate formatting localizable
2025-09-10 09:54:50 +02:00
Dean Herbert
699892c6a2 Fix beatmap carousel not holding selection after refilter in some cases
Closes https://github.com/ppy/osu/issues/34923.
2025-09-10 16:37:49 +09:00
Dean Herbert
fa6b830a13 Add test coverage showing selection not being held post-filter when difficulties are being split out 2025-09-10 16:37:16 +09:00
Dean Herbert
278b232318 Fix realm not being cached in beatmap carousel tests 2025-09-10 16:37:12 +09:00
Bartłomiej Dach
6660406ee9 Change ToString() override to match pre-existing conventions 2025-09-10 15:34:18 +09:00
Bartłomiej Dach
482b7b6d3f Change class name
I suggested it myself but on revisiting it's a bit of a mouthful.
2025-09-10 15:33:46 +09:00
CloneWith
c8c87089e5 Use LocalisableString interpolation to make strings update properly 2025-09-10 07:49:14 +08:00
CloneWith
b3abd09517 Add HumanisedLocalisableDate for l10n 2025-09-10 07:48:09 +08:00
Dean Herbert
014b55602d Fix one more failing test 2025-09-10 02:41:27 +09:00
Dean Herbert
0cd3894fa6 Fix multiple failing song select tests 2025-09-10 01:31:15 +09:00
Dan Balasescu
a6e42fb0cb Fix mangled initial undo state on fresh skins 2025-09-09 20:26:41 +09:00
Dean Herbert
2bd734918a Adjust song select debounce to be high than repeat_initial_delay
I'm doing this silently to see if any users complain without being told
about the change. Without this, when holding left arrow for short
bursts, precisely *one* beatmap change happens before actual key repeat
kicks in, which feels really weird (updates the leaderboard / background
unexpectedly).

This is the simplest way to resolve the issue, so if users aren't
offended by it I think we should commit to it.

Personally it's still fast enough to not annoy me at all.
2025-09-09 19:11:50 +09:00
Dan Balasescu
a436372b05 Allow exit during matchmaking intro (#137) 2025-09-09 18:09:43 +09:00
Dean Herbert
6362fed097 Update framework 2025-09-09 18:02:02 +09:00
Dean Herbert
16594f2986 Update resources 2025-09-09 18:01:06 +09:00
Dean Herbert
68e7af0c02 Merge pull request #34956 from peppy/bpm-filtering-less-precise
Adjust BPM filtering at song select to be less precise
2025-09-09 17:33:49 +09:00
Dean Herbert
caad065433 Merge pull request #34920 from cl8n/retro-skin
Add "retro" default skin
2025-09-09 15:48:12 +09:00
Dean Herbert
11696a7a3c Merge pull request #34932 from Joehuu/fix-argon-judgement-colored-numbers
Fix `ArgonJudgementCounterDisplay` not showing colored numbers when "Show label" is off
2025-09-09 15:20:49 +09:00
Dean Herbert
f94d5004ea Adjust BPM filtering at song select to be less precise
Closes https://github.com/ppy/osu/issues/34942.
2025-09-09 15:02:57 +09:00
Dean Herbert
335bc6cdf6 Guard against ArgonJudgementCounterDisplay crashing due to fuckery
I can't see how this can happen in a normal flow, so just doing it as a
safety measure. Pointed out in https://github.com/ppy/osu/issues/34940
but likely due to a third party fuck being loaded.
2025-09-09 14:56:21 +09:00
Dean Herbert
eb24e02c38 Merge pull request #34952 from peppy/rank-display-rate-limit-change
Change debounce method in rank display to allow more immediate updates
2025-09-08 17:23:56 +09:00
Dean Herbert
06c1b81c1b Change debounce method in rank display to allow more immediate updates 2025-09-08 15:12:49 +09:00
Dan Balasescu
449038d070 Split main menu buttons into multiplayer section (#136)
Co-authored-by: Dean Herbert <pe@ppy.sh>
2025-09-08 13:54:06 +09:00
Dean Herbert
35885a17b4 Merge pull request #34948 from Joehuu/fix-sheared-dropdown-click-sound-area
Fix sheared dropdown click sound area
2025-09-08 13:40:15 +09:00
Joseph Madamba
c2bc67d083 Fix sheared dropdown click sound area 2025-09-07 11:00:26 -07:00
Dean Herbert
645518f5bd Fix external edit filename sanitising unintentionally dropping folder separators (#34945)
* Add failing test coverage showing external edits not working with folders

* Fix external edit filename sanitising unintentionally dropping folder separators

Closes https://github.com/ppy/osu/issues/34929.
2025-09-07 21:47:20 +09:00
Dan Balasescu
ffab8342f2 Merge branch 'master' into pp-dev 2025-09-07 19:22:08 +09:00
Dan Balasescu
31188127ef Transmit availability with ready state
Regressed with https://github.com/ppy/osu-server-spectator/pull/311.

As it turns out, the method not just resets ready states but also the
beatmap availabilities. So we have to send it again here.

I have a feeling this is also broken in standard multiplayer in some way
or another.
2025-09-07 16:17:28 +09:00
Dan Balasescu
48bad31255 Pessimistically set the beatmap in all stages (#135) 2025-09-07 16:17:28 +09:00
Dan Balasescu
1a49c81bab Fix matchmaking being permanently sound-ducked (#134) 2025-09-07 16:17:28 +09:00
Dan Balasescu
27db49bad3 Fix results screen crash from missing users (#133) 2025-09-07 16:17:28 +09:00
Jamie Taylor
e6dbb1020c Add some audio feedback to the matchmaking flow (#132) 2025-09-07 16:17:28 +09:00
Dan Balasescu
e0c11504a2 Query for available pools for selection (#131) 2025-09-07 16:17:27 +09:00
Dan Balasescu
35e1fa6660 Fix test failure 2025-09-07 16:17:27 +09:00
Dan Balasescu
330b61f4c0 Add ruleset selector (#130) 2025-09-07 16:17:27 +09:00
Dan Balasescu
3985596602 Join matchmaking rooms with password 2025-09-07 16:17:27 +09:00
Dan Balasescu
3786efaa5e Separate IMatchmakingClient and IMultiplayerClient
Co-authored-by: Dean Herbert <pe@ppy.sh>
2025-09-07 16:17:27 +09:00
Dan Balasescu
0225c1a867 Fix event handler leak 2025-09-07 16:17:27 +09:00
Dan Balasescu
111b98ef8e Add matchmaking 2025-09-07 16:17:27 +09:00
Valerus9
22bfab95b0 Fix testdouble failure. 2025-09-06 06:43:13 +02:00
Joseph Madamba
18b5c652a3 Fix ArgonJudgementCounterDisplay not showing colored numbers when "Show label" is off 2025-09-05 12:25:40 -07:00
clayton
3c1c537b1b Replace old-skin with retro skin in tests 2025-09-05 21:21:52 +09:00
clayton
6af48975b0 Add "retro" default skin 2025-09-05 21:21:52 +09:00
Dean Herbert
058835440d Update resources 2025-09-05 21:20:12 +09:00
Dean Herbert
ea79422b60 Update resources 2025-09-05 19:16:47 +09:00
Dean Herbert
543d21a0ce Merge pull request #34905 from NiyazBiyaz/update-rank-display
Fix `rank-up` and `rank-down` sounds playing too often in some scenarios
2025-09-05 16:53:55 +09:00
Dean Herbert
ab7985f31e Improve initial state handling 2025-09-05 16:19:55 +09:00
Dean Herbert
52c10a42be Change DefaultRankDisplay to start with no value 2025-09-05 16:10:27 +09:00
Dean Herbert
912c0a39cf Change debounce to be delayed since last actual change to avoid state flickering 2025-09-05 16:10:12 +09:00
Dean Herbert
45ef97c92c Simplify implementation 2025-09-05 16:01:22 +09:00
NiyazBiyaz
54d4b16a01 Fix rank-up and rank-down sounds playing too often in some scenarios 2025-09-05 15:41:04 +09:00
Dean Herbert
54a0c7af23 Merge pull request #34917 from smoogipoo/matchmaking-pool-model
Replace MatchmakingSettings with MatchmakingPool
2025-09-05 15:26:49 +09:00
Dean Herbert
891b717b3d Merge pull request #34914 from bdach/error-on-exiting-editor
Fix errors on exiting from editor if there are no more beatmaps remaining for the ruleset active in song select
2025-09-05 15:24:07 +09:00
Dean Herbert
11e1c2d73f Merge pull request #34903 from peppy/song-select-better-debounce
Fix song select debounce not handling long (stutter) frames well
2025-09-05 15:02:53 +09:00
Dan Balasescu
4475bcafa9 Add GetMatchmakingPools server method 2025-09-05 14:40:58 +09:00
Dan Balasescu
32576ff249 Replace MatchmakingSettings with MatchmakingPool 2025-09-05 14:40:48 +09:00
Bartłomiej Dach
134f854d7b Fix broken reselection logic
d4b357dfa0 contains a sneaky regression.
The previous code read:

    if (CurrentSelection != null && CheckModelEquality(beatmap, CurrentSelection))
	RequestSelection(matchingNewBeatmap);

and the new one reads:

    if (CurrentSelection is GroupedBeatmap currentBeatmapUnderGrouping)
    {
	var candidateSelection = currentBeatmapUnderGrouping with { Beatmap = beatmap };
	if (CheckModelEquality(candidateSelection, CurrentSelection))
	    RequestSelection(candidateSelection);
    }

The point is that we want to reselect `matchingNewBeatmap` here, not the
old selection. The `CheckModelEquality()` check's purpose is to check
whether *the current selection needs updating*.

I'm not sure why tests just wonderfully passed despite this, but my
suspicion is that it was because of accidental copying of realm guids
that obscured this problem.
2025-09-04 13:11:31 +02:00
Bartłomiej Dach
bae288859b Fix test failing because of new realm check 2025-09-04 12:44:36 +02:00
Bartłomiej Dach
6e5bf57fe7 Ensure that matching beatmap still exists when performing replace operation in the carousel 2025-09-04 12:44:18 +02:00
Dean Herbert
0027b9846d Merge pull request #34912 from peppy/matchmaking-model-types
Add matchmaking model types required for server-side deploy
2025-09-04 19:32:07 +09:00
Dean Herbert
1627f67ada Add variant to MatchmakingSettings 2025-09-04 18:43:46 +09:00
CloneWith
ae0f9619b9 Change wrong overwrite type in ScheduleScreen 2025-09-04 17:30:10 +08:00
Dan Balasescu
815bf9c37b Add matchmaking model types required for server-side deploy 2025-09-04 18:26:56 +09:00
Dean Herbert
b0c7b6c700 Fix multiple concerns with new debounce logic
Tried many approaches but this seems simplest to guarantee no test (or
other) regressions..
2025-09-04 18:13:16 +09:00
Dean Herbert
3fcc8d45cb Merge pull request #34911 from bdach/fix-no-report-in-playlists
Fix not being able to report users from playlists chat
2025-09-04 17:08:08 +09:00
Dean Herbert
f1d06f796a Merge pull request #34904 from bdach/local-rank-includes-unproven-scores
Treat guest user scores & scores of unknown users as the local user's
2025-09-04 17:06:51 +09:00
Bartłomiej Dach
be365dfdc5 Fix not being able to report users from playlists chat
Reported internally.
2025-09-04 09:45:32 +02:00
CloneWith
1c608e779d Make DrawableDate formatting localizable 2025-09-04 14:44:40 +08:00
Dean Herbert
b2501ae58f Change debounce consideration to use dynamic FPS moving average rather than fixed 60 fps
This should better account for scenarios where user FPS is below 60 fps.
Previously the debounce would unexpectedly be longer than usual for low
FPS scenarios.
2025-09-04 02:19:28 +09:00
Dean Herbert
23d10ccdeb Merge pull request #32297 from LukynkaCZE/argon-judgement-counter
Add argon style judgement counter
2025-09-03 21:33:07 +09:00
Bartłomiej Dach
98c3437174 Always show the same number of placeholder digits in argon judgement counter when it is vertical 2025-09-03 13:42:17 +02:00
Bartłomiej Dach
a56f81a731 Fix abysmal code quality 2025-09-03 13:23:12 +02:00
Bartłomiej Dach
dac534e22a Merge branch 'master' into argon-judgement-counter 2025-09-03 13:01:57 +02:00
Bartłomiej Dach
1ba403753c Merge branch 'master' into song-select-better-debounce 2025-09-03 12:42:21 +02:00
Bartłomiej Dach
f1a020d2c6 Treat guest user scores & scores of unknown users as the local user's 2025-09-03 12:05:03 +02:00
Bartłomiej Dach
15d73ce07e Add test coverage 2025-09-03 12:05:03 +02:00
Bartłomiej Dach
0bbad3e1cd Extract helper method for retrieving all user local scores 2025-09-03 12:05:02 +02:00
Dean Herbert
4ec620c4a9 Fix song select debounce happening too early during fast iteration if there's a stutter 2025-09-03 18:55:47 +09:00
Dean Herbert
6ce76786ed Better document various debounce constants and split out processing debounce for clarity 2025-09-03 18:55:46 +09:00
Dean Herbert
b97cb65444 Adjust song select debounce upwards slightly
I still think it can probably go higher. Just going to do this in small
increments until people complain / notice.
2025-09-03 18:55:46 +09:00
Dean Herbert
3e8775051e Implement local song select debounce rather than using Scheduler.AddDelayed
This is to allow more custom handling of the debounce timing.
2025-09-03 18:55:46 +09:00
Dean Herbert
0ab3b593e7 Merge pull request #34900 from bdach/invalid-filenames-in-imported-skins
Fix external edit operations failing due to invalid filenames
2025-09-03 18:50:17 +09:00
Dean Herbert
71d0afd4c2 Attempt to fix flaky test TestFilteringRunsAfterReturningFromGameplay
The double escape key press was dodgy from the get-go.
2025-09-03 18:49:21 +09:00
Dean Herbert
19d194476f Merge pull request #34842 from bdach/carousel-multiple-copies-of-beatmap-clean
Allow beatmaps to show up multiple times in the carousel if grouping criteria requires it
2025-09-03 18:47:25 +09:00
Bartłomiej Dach
546113451b Merge pull request #34902 from peppy/update-framework
Update framework
2025-09-03 11:46:24 +02:00
Bartłomiej Dach
4a7ee6fafc Hide object-typed CurrentSelection and expose strongly-typed alternatives instead 2025-09-03 10:24:25 +02:00
Dean Herbert
eb1263aa32 Update framework 2025-09-03 17:23:41 +09:00
Dean Herbert
a840e55977 Check exported filenames for added safety 2025-09-03 17:14:45 +09:00
Bartłomiej Dach
315eea8d9a Simplify beatmap access in carousel panels 2025-09-03 09:52:37 +02:00
Bartłomiej Dach
aa847c5833 Merge pull request #34867 from kptach/mania-multi-key
Add secondary keys for osu!mania
2025-09-03 09:38:33 +02:00
Bartłomiej Dach
5c66998c57 Replace local copy of GetValidFilename() with direct usage
Noticed in passing.
2025-09-03 09:32:43 +02:00
Bartłomiej Dach
51e7593446 Fix external edit operations failing due to invalid filenames 2025-09-03 09:26:06 +02:00
Bartłomiej Dach
6399f7e3db Add failing test case 2025-09-03 09:26:06 +02:00
Dean Herbert
1e50e36a64 Merge pull request #34892 from bdach/shift-click-beatmap-card
Download online beatmap / present local beatmap on shift-clicking beatmap cards
2025-09-03 16:19:48 +09:00
Dean Herbert
48e4844fbb Merge pull request #34891 from bdach/multi-spectator-player-fail
Adjust fail handling in multiplayer spectator player to permit showing F rank
2025-09-03 15:40:20 +09:00
Dean Herbert
566562240e Merge branch 'master' into carousel-multiple-copies-of-beatmap-clean 2025-09-03 15:35:03 +09:00
Dean Herbert
19361666a1 Add menu tip exposing new behaviour 2025-09-03 15:27:29 +09:00
Bartłomiej Dach
dc5794dceb Do not pass a whole bunch of InputKey.None down three levels for no reason 2025-09-03 07:51:52 +02:00
Dean Herbert
f414dd70f5 Merge pull request #34880 from minetoblend/fix/editor-player-crash
Fix crash when trying to test map in the editor
2025-09-03 02:31:42 +09:00
Dean Herbert
69bcef8339 Merge pull request #34893 from bdach/ignore-osu-files-in-subdirs
Ignore `.osu` files not placed at top level of beatmap archive on import
2025-09-03 02:29:20 +09:00
Dean Herbert
c29217240e Merge pull request #34819 from smoogipoo/fix-room-event-loss
Fix potential loss of room events during join
2025-09-03 02:20:43 +09:00
Krystian Ptach-Żurakowski
4a193e96e0 Change deafult keys to none 2025-09-02 17:53:31 +02:00
Bartłomiej Dach
79f7f0ecad Ignore .osu files not placed at top level of beatmap archive on import
Closes https://github.com/ppy/osu/issues/34677.
2025-09-02 14:50:31 +02:00
Bartłomiej Dach
95c7252467 Add failing test case 2025-09-02 14:43:41 +02:00
Dean Herbert
a1105ba16f Make OsuGame dependency optional for sanity 2025-09-02 21:40:52 +09:00
Dean Herbert
bee6c32b83 Change bass workaround fix to use game clock intead of another-audio-clock
paper trail:
https://github.com/ppy/osu/pull/34890#issuecomment-3244549790
2025-09-02 21:39:12 +09:00
Bartłomiej Dach
6c82f543e6 Download online beatmap / present local beatmap on shift-clicking beatmap cards
Closes https://github.com/ppy/osu/issues/34883.
2025-09-02 13:11:18 +02:00
Bartłomiej Dach
4ed72efeae Use better guard (and reword subsequent comment)
Co-authored-by: Dean Herbert <pe@ppy.sh>
2025-09-02 12:42:07 +02:00
Bartłomiej Dach
5c6bbfcc6a Adjust fail handling in multiplayer spectator player to match multiplayer player
Closes https://github.com/ppy/osu/issues/34884.
2025-09-02 12:38:34 +02:00
Bartłomiej Dach
9354547e15 Move solo spectator-specific fail logic to SoloSpectatorPlayer 2025-09-02 12:25:42 +02:00
Bartłomiej Dach
a799720232 Add failing test 2025-09-02 12:23:38 +02:00
James Wilson
a78c78ecdd Update difficulty calculation tests for osu ruleset (#34828) 2025-09-02 13:19:34 +03:00
Bartłomiej Dach
89aea73495 Merge pull request #34890 from peppy/less-frozen-gameplay
Fix gameplay freezing on stutter frames / long load times
2025-09-02 11:24:24 +02:00
StanR
84309f57c5 Reduce rhythm difficulty if current object is doubletappable (#34877)
* Reduce rhythm difficulty if current object is doubletappable

* Buff rhythm multiplier
2025-09-02 10:22:12 +01:00
Dan Balasescu
1519084f72 Eagerly clear the request queue on join 2025-09-02 17:57:15 +09:00
Dean Herbert
677beb4251 Fix gameplay freezing on stutter frames / long load times
Closes https://github.com/ppy/osu/issues/34732.

May hotfix for this one.
2025-09-02 17:37:33 +09:00
Dean Herbert
a8ef57ad0a Revert "Adjust bass invalid data threshold"
This reverts commit ddce11fbc8.
2025-09-02 17:36:08 +09:00
Bartłomiej Dach
903d91b697 Use SingleOrDefault() instead of LastOrDefault()
`LastOrDefault()` is arbitrary, and I hope this doesn't matter for
anything, because if it does, then that's utterly *horrifying*.
2025-09-02 08:08:23 +02:00
Bartłomiej Dach
b0dcd06b38 Add one more comment 2025-09-02 08:08:22 +02:00
Dean Herbert
9422fe52d1 Merge pull request #34887 from smoogipoo/fix-editor-leak 2025-09-02 11:31:14 +09:00
Krystian Ptach-Żurakowski
f9e89afe03 Add increase visibility setting for taiko hidden (#34879)
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-09-02 10:10:58 +09:00
Dan Balasescu
cac136d3c6 Fix editor memory leak 2025-09-02 09:21:31 +09:00
Dean Herbert
63ab11ac16 Merge pull request #34885 from peppy/multiplayer-ui-sizing
Fix multiplayer lobby being unusable on mobile
2025-09-02 00:15:18 +09:00
Bartłomiej Dach
a008a66fb2 Fix test 2025-09-01 13:50:42 +02:00
Bartłomiej Dach
eb392c47e9 Merge pull request #34873 from NiyazBiyaz/fix-scale-and-rotation-popover-crash
Fix rotation & scale popovers crashing on dismissal via keyboard when simultaneously dragging sliders
2025-09-01 13:41:04 +02:00
Marvin Schürz
ffb6ae2066 Move null check after loop over nested hitobjects 2025-09-01 13:13:28 +02:00
Marvin Schürz
385529ec78 Fix mismatch in cutoff time check between preventMissOnPreviousHitObjects and markPreviousObjectsHit 2025-09-01 13:05:22 +02:00
Dean Herbert
cf471066bf Add basic spacing between participants in list 2025-09-01 19:52:29 +09:00
Dean Herbert
659480fa3f Adjust sizing of room panels and other elements to make things fit better on mobile layouts 2025-09-01 19:52:29 +09:00
Dean Herbert
209ba76b21 Reduce size of online play screen's header 2025-09-01 19:40:39 +09:00
Dean Herbert
5079a53cca Add more panel types to TestSceneRoomPanel 2025-09-01 19:37:35 +09:00
Marvin Schürz
060854f23a Revert moving markPreviousObjectsHit into LoadAsyncComplete
Running that there caused a test failure due to modifying drawables' transforms outside the update thread
2025-09-01 12:10:12 +02:00
Bartłomiej Dach
e2d661736e Fix typos 2025-09-01 12:01:36 +02:00
Bartłomiej Dach
82a135af19 Merge pull request #34882 from peppy/fix-excess-requests-song-select
Fix excess requests leading to queueing / delays of updating metadata at song select
2025-09-01 11:49:32 +02:00
Marvin Schürz
689cc27e68 Prevent npr in tests due to drawable ruleset not being available 2025-09-01 11:12:19 +02:00
Marvin Schürz
da7e256302 Move markPreviousObjectsHit into LoadAsyncComplete 2025-09-01 11:11:26 +02:00
Marvin Schürz
9827f9f189 Recursively update hit results for nested drawables 2025-09-01 11:10:30 +02:00
Dean Herbert
9d0043d03b Cancel underlying web request on local cancellation of lookup request 2025-09-01 18:00:52 +09:00
Dean Herbert
0021434a62 Fix cancellation token not actually being used 2025-09-01 18:00:52 +09:00
NiyazBiyaz
677c008b4d Fix movement via slider while popover closes 2025-09-01 13:57:14 +05:00
NiyazBiyaz
12430ce464 Move guard to scale/rotationInfo 2025-09-01 13:55:29 +05:00
Dean Herbert
5de7cc3efb Merge pull request #34764 from bdach/pinned-rooms
Add support for pinning multiplayer rooms
2025-09-01 16:52:05 +09:00
Dean Herbert
4e976cff6a Merge branch 'master' into pinned-rooms 2025-09-01 16:01:50 +09:00
65f275106e update license information in various places (and readme) 2025-08-31 22:47:36 +03:00
Krystian Ptach-Żurakowski
c7f1210281 Better secondary keybinds for 10K 2025-08-31 21:19:26 +02:00
6e374762fd synchronize with github 2025-08-31 21:26:21 +03:00
80646a166c add settings toggle to not delete imported archives 2025-08-31 19:39:13 +03:00
NiyazBiyaz
b02093505d Add OperationInProgress checking 2025-08-31 17:17:17 +05:00
8f0510d903 made beatmap anonymization code a bit less awful 2025-08-31 15:06:24 +03:00
James Wilson
6a35b7237b Prevent Taiko difficulty crash if a map only contains 0-strains (#34829)
* Prevent Taiko difficulty crash if a map only contains 0-strains

* Add second check for safety

This is accessing a different array of strains. I'd rather be safe than sorry.

* Add guard in PP too

* Make `MarginOfError` a const
2025-08-31 12:04:56 +00:00
James Wilson
90ac249f5e Move SpunOut penalty back to PP (#34838)
This isn't a super common mod compared to every other one on the list, it's probably not worth the storage (and memory in case of stable) implications. We can look at revisiting this once we have actual spinner difficulty considerations
2025-08-31 12:32:28 +05:00
02e7000ee4 update editor beatmap anonymization code to update not just first diff 2025-08-30 22:56:01 +03:00
Krystian Ptach-Żurakowski
08ad27459e Code quality 2025-08-30 20:36:29 +02:00
Krystian Ptach-Żurakowski
2fb481e2ee Add Secondary Keys for Mania 2025-08-30 20:35:51 +02:00
marvin
d6b4c2958d Fix crash when marking previous objects as hit 2025-08-30 19:36:17 +02:00
Dean Herbert
c26e669fc5 Merge pull request #34837 from smoogipoo/more-testable-footers
Add footer to `ScreenTestScene`
2025-08-30 21:52:30 +09:00
081355864e add beatmap editor option to remove online data of a map 2025-08-29 20:19:39 +03:00
6435a835d1 fix background category selection (this time for real) 2025-08-29 18:48:13 +03:00
Dean Herbert
e621eed0ba Merge pull request #34841 from peppy/interpolate-more
Adjust interpolation workaround to catch-up slightly smoother
2025-08-29 22:04:20 +09:00
Bartłomiej Dach
4ffc262073 Fix rewind not working over grouping mode changes 2025-08-29 14:42:32 +02:00
Dean Herbert
41b8033ebd Adjust interpolation workaround to catch-up slightly smoother 2025-08-29 21:24:23 +09:00
Dean Herbert
1d9de88aaa Merge pull request #34836 from bdach/online-lookups-on-reenter
Fix song select not performing online lookup on re-enter
2025-08-29 21:21:34 +09:00
Bartłomiej Dach
a27fef2437 Add failing test for rewind not working over grouping mode changes 2025-08-29 14:06:53 +02:00
Bartłomiej Dach
2b52c1de0b Fix presenting individual beatmaps from main menu breaking
In this case `CurrentSelection` is being set on the song select screen's
`OnEntering()`, at which point grouping is not yet known.
2025-08-29 13:45:27 +02:00
Bartłomiej Dach
89492cbd81 Do not attempt to refresh group in current selection if grouping is not relevant 2025-08-29 13:25:08 +02:00
Bartłomiej Dach
1bb24c923d Fix stale group refresh logic inadvertently losing selection entirely sometimes 2025-08-29 13:25:08 +02:00
Bartłomiej Dach
dfed564bda Allow BeatmapCarousel.CurrentSelection to accept raw BeatmapInfos (and redirect to appropriate grouped beatmap)
This is probably where things get a little controversial.

There are some song select flows wherein song select just wants to
ensure sanity by authoritatively setting the global beatmap. The goal is
to change the beatmap immediately and instantly. Therefore it should
kind of be the carousel's job to figure out its grouping complications.

To that end, `CurrentSelection` is made virtual, and overridden in
`BeatmapCarousel` to perform a sort of reconciliation logic. If an
external component sets `CurrentSelection` to a `BeatmapInfo`, one of
the two following things happen:

- Nothing, if the current `GroupedBeatmap` is already a copy of the
  beatmap that needs to be selected, or

- The carousel looks at its items, finds any first copy which matches
  the beatmap that the external consumer wanted selected, and changes
  selection to that instead.
2025-08-29 13:25:08 +02:00
Bartłomiej Dach
3cf0a9b9c0 Fix standalone beatmap panels not having the correct height 2025-08-29 13:25:08 +02:00
Bartłomiej Dach
107e103825 Fix changing group mode causing CurrentSelection to retain a stale GroupDefinition 2025-08-29 13:25:08 +02:00
Bartłomiej Dach
3f637db391 Fix obvious test failures from using GroupedBeatmap in BeatmapCarousel.CurrentSelection 2025-08-29 13:25:08 +02:00
Bartłomiej Dach
d4b357dfa0 Fix carousel selection not working
Basically, `BeatmapCarousel.CurrentSelection`, which is
magic-object-typed, can no longer use `BeatmapInfo` directly, it now
must also use `GroupedBeatmap`.

This spills out all the way into song select because of beatmap
selection flows that require hookup from song select.
2025-08-29 13:25:01 +02:00
Bartłomiej Dach
e98579d3af Apply most trivial adjustments to tests after beatmap model replacement 2025-08-29 13:22:37 +02:00
Bartłomiej Dach
a84c364e44 Introduce new model for "beatmaps under grouping" & allow beatmaps to appear in multiple groups
This bypasses the immediate first issue of not being able to display
multiple instances of a beatmap on the carousel because of model
equality being baked into the structure. It inevitably poses a bunch of
*other* problems, but it's a start.
2025-08-29 13:12:12 +02:00
Bartłomiej Dach
2ed79d354c Add baseline test exercising desired duplicated display 2025-08-29 13:12:12 +02:00
Bartłomiej Dach
d304a31757 Make grouping by collections and rank achieved testable without involving realm 2025-08-29 13:12:12 +02:00
Dean Herbert
3ca5e20e70 Merge branch 'master' into online-lookups-on-reenter 2025-08-29 19:03:41 +09:00
Dean Herbert
404044e8d7 Merge pull request #34822 from bdach/carousel-multi-grouping-clean 2025-08-29 19:02:58 +09:00
Dan Balasescu
d5575b4037 Merge pull request #34830 from minetoblend/fix/hitobject-lifetime-delay
Fix hitobject drawables becoming visible 1 frame too late
2025-08-29 18:38:24 +09:00
Dan Balasescu
04ba5aa575 Move footer to ScreenTestScene 2025-08-29 17:49:48 +09:00
Bartłomiej Dach
51ed19cb99 Merge branch 'master' into carousel-multi-grouping-clean 2025-08-29 10:41:46 +02:00
Dean Herbert
0a408a3ac4 Fix tournament test failure due to control change 2025-08-29 17:12:24 +09:00
Dean Herbert
22ba956f25 Merge pull request #34833 from peppy/fix-mod-cosmetics
Fix some mods showing tooltips when settings are default
2025-08-29 17:09:01 +09:00
Bartłomiej Dach
526ee32268 Apply suggested rename 2025-08-29 09:58:56 +02:00
Bartłomiej Dach
df6d6edaca Fix song select not performing online lookup on re-enter
Closes https://github.com/ppy/osu/issues/34825.

Root cause is

	24ec43b3b6/osu.Game/Screens/SelectV2/SongSelect.cs (L345-L356)

not specifying `(..., true)`, therefore the fetch doesn't happen on
enter if song select doesn't change the global beatmap as a side effect
of the enter, which is the case on re-entering.
2025-08-29 09:31:20 +02:00
Bartłomiej Dach
24ec43b3b6 Merge pull request #34834 from peppy/tournament-warmup-better
Use switches for warmup/chat toggles in tournament interface
2025-08-29 09:09:20 +02:00
Dean Herbert
9e77a5b050 Fix obviously incorrect conditional
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2025-08-29 16:01:49 +09:00
Dean Herbert
12832e9fef Use switches for warmup/chat toggles in tournament interface
As proposed in https://github.com/ppy/osu/discussions/32515.
2025-08-29 14:35:42 +09:00
Dean Herbert
e83f3d5e77 Fix some mods showing tooltips when settings are default 2025-08-29 14:08:18 +09:00
Dean Herbert
f2f5cf19a2 Return early to avoid creating mod description strings unnecessarily 2025-08-29 14:08:06 +09:00
marvin
bb9f9e4d35 Fix operations in PooledDrawableWithLifetimeContainer.CheckChildrenLife being in wrong order
Previously CompositeDrawable.CheckChildrenLife() would be run before lifetimeManager.Update() which lead to the new drawables being inserted into the container but not being made alive immediately, leading to the drawable not becoming visibile until the next update loop.
2025-08-28 23:36:29 +02:00
Jay Lawton
087f0565e6 Implement deltatimenormaliser into rhythm grouping logic (#33403)
* additions

* review fixes

* Formatting

* comments + review

* fix

* fix renaming and namespace

* balancing + round

---------

Co-authored-by: tsunyoku <tsunyoku@gmail.com>
Co-authored-by: StanR <hi@stanr.info>
2025-08-28 13:19:13 +00:00
Bartłomiej Dach
6e1316241a Merge pull request #34774 from genskyff/feat/long-note-ratio
Add long note percentage filter for mania mode
2025-08-28 14:32:52 +02:00
Bartłomiej Dach
3eaa5314ac Merge pull request #34808 from peppy/fix-difficulty-churn
Fix beatmap carousel triggering full filters more often than it needs to
2025-08-28 14:26:25 +02:00
Bartłomiej Dach
6ba72fa481 Adjust tests to new beatmap set model usage in carousel 2025-08-28 13:09:11 +02:00
Bartłomiej Dach
8dd131f17e Support beatmap sets being split apart by the active group mode in beatmap carousel 2025-08-28 13:09:08 +02:00
Dean Herbert
7e109add96 Ensure filtering also runs after local gameplay LastPlayed changes 2025-08-28 19:10:20 +09:00
Dean Herbert
f953d58922 Merge pull request #34740 from bdach/maximised-player-audio
Always use audio from maximised player if there is one in multiplayer spectator
2025-08-28 18:27:56 +09:00
Bartłomiej Dach
47164c61b4 Add failing test coverage of splitting beatmap sets apart 2025-08-28 11:00:23 +02:00
Bartłomiej Dach
311c75aa53 Adjust test after allowing grouping modes to split beatmap sets apart 2025-08-28 11:00:23 +02:00
Dean Herbert
0b40f1d0db Merge pull request #34818 from smoogipoo/completion-handler-override
Preserve pre-post notification completion target
2025-08-28 14:10:59 +09:00
Dan Balasescu
9ae6e509b7 Configure await calls 2025-08-28 13:47:55 +09:00
Dan Balasescu
b95573f97d Fix potential loss of room events during join 2025-08-28 13:20:02 +09:00
Dan Balasescu
e831d1b6fa Preserve pre-post notification completion target 2025-08-28 13:07:05 +09:00
Dean Herbert
ed15e1fb88 Merge branch 'master' into fix-difficulty-churn 2025-08-28 02:38:10 +09:00
Dean Herbert
33b99a51b1 Merge pull request #34812 from bdach/failed-at-judgement
Fix `HealthProcessor` potentially incorrectly reverting failed state
2025-08-28 02:37:44 +09:00
Dean Herbert
8a6c857719 Fix hidden beatmap state not being reflected immediately 2025-08-28 02:33:18 +09:00
Dean Herbert
5abd93eda7 Merge pull request #34809 from peppy/fix-star-rating-weird-mod-double-handling
Fix beatmap panels locally handling mod and ruleset changes unnecessarily
2025-08-28 01:27:31 +09:00
Bartłomiej Dach
4030383276 Allow grouping modes that apply max aggregate to split beatmap sets apart 2025-08-27 14:45:20 +02:00
Dean Herbert
f9c1b24df4 Apply in more places 2025-08-27 19:59:44 +09:00
Bartłomiej Dach
197c318180 Fix HealthProcessor potentially incorrectly reverting failed state
This stems from me looking into `TestSceneFailAnimation` failures
(https://github.com/ppy/osu/runs/48663953318). As it turns out, I should
not have been mad by CI, and rather should have been mad at myself for
failing to read.

`FailedAtJudgement` in fact does not mean "this judgement, and only this
judgement, triggered failure". If any further judgements occur
post-fail, they will also have `FailedAtJudgement` set to true. It is
essentially a *dump* of the state of `HealthProcessor.Failed` prior to
applying the judgement.

	ec21685c25/osu.Game/Rulesets/Scoring/HealthProcessor.cs (L49-L57)

Because of this, reverting several judgements which occur post-fail
could lead to failed state reverting earlier than intended, and thus
potentially trigger a second fail, thus tripping the `Player` assertion.
2025-08-27 12:27:11 +02:00
Dean Herbert
fda40d7fd5 Fix beatmap panels locally handling mod changes unnecessarily
The `BeatmapDifficultyCache` handles mod changes, so handling locally is
unnecessary. By handling locally, it creates a visual issue when
adjusting mods often. Test using Ctrl +/- at song select and observing
that without this change, the star rating will flicker back to the
default due to the local re-fetch.
2025-08-27 18:31:50 +09:00
Dean Herbert
be6fb9aa77 Fix beatmap carousel re-filtering when it doesn't need to
Local rules ensure we only handle callbacks when we need to.
2025-08-27 18:21:19 +09:00
Dean Herbert
0e57ee9ba6 Avoid triggering changes when add operations are empty
Only seems to happen in tests. I think.
2025-08-27 18:13:13 +09:00
Dean Herbert
043235fed2 Add test coverage ensuring filtering does not occur on unnecessary updates 2025-08-27 18:13:12 +09:00
Dean Herbert
ec21685c25 Merge pull request #34803 from peppy/update-framework-please-no-clock-breakage
Update framework
2025-08-27 13:23:09 +09:00
628181a883 also update colour on load 2025-08-27 01:11:57 +03:00
835329efd3 synchronize with github 2025-08-27 00:59:45 +03:00
5399943118 update logo colour only when changing setting value 2025-08-27 00:58:26 +03:00
d07f82f6f4 refactor custom seasonal background code
some of it may be trauma-inducing, but I don't know how to make it
better
2025-08-27 00:43:26 +03:00
Dean Herbert
244bad07c7 Update framework 2025-08-26 21:43:09 +09:00
Binwalker
149f18c3f5 test(ManiaFilterCriteriaTest): simplify test case 2025-08-26 21:36:20 +09:00
Binwalker
6a82b7331f refactor(ManiaFilterCriteria): exclude converted beatmaps from long note filter 2025-08-26 21:36:20 +09:00
Binwalker
65253708d8 test(ManiaFilterCriteriaTest): fix some test case for ln filter 2025-08-26 21:36:20 +09:00
Binwalker
556c2469bf fix(ManiaFilterCriteria): converted beatmaps are not included 2025-08-26 21:36:20 +09:00
Binwalker
f7b0e114a9 test(ManiaFilterCriteriaTest): add some testcase 2025-08-26 21:36:20 +09:00
Binwalker
68677200f3 feat(ManiaFilterCriteria): add long note ratio filter for mania 2025-08-26 21:36:19 +09:00
Dean Herbert
2bea59e65f Merge pull request #34802 from bdach/hack-around-carousel-panel-refresh
Work around excessive refreshes of carousel beatmap set panel backgrounds
2025-08-26 21:13:28 +09:00
Bartłomiej Dach
c0fd5637de Work around excessive refreshes of carousel beatmap set panel backgrounds
Closes https://github.com/ppy/osu/issues/34511 I guess.
2025-08-26 13:27:54 +02:00
Bartłomiej Dach
5e7a99c97f Merge pull request #34801 from peppy/replay-player-null
Fix crash on exiting `ReplayPlayer` is beatmap was not loaded successfully
2025-08-26 12:11:27 +02:00
Bartłomiej Dach
8f628d16ae Merge pull request #34800 from peppy/fix-daily-challenge-leaderboard-skip
Fix daily challenge / playlist leaderboard sometimes showing incorrect default state
2025-08-26 12:07:41 +02:00
Dean Herbert
2ccb65aa65 Add test coverage and fix one more fail case 2025-08-26 18:41:14 +09:00
Dean Herbert
4d851f2527 Fix crash on exiting ReplayPlayer is beatmap was not loaded successfully
Closes https://github.com/ppy/osu/issues/34763.
2025-08-26 18:31:42 +09:00
Dean Herbert
4bafbfb9e4 Apply NRT to ReplayPlayer for good measure 2025-08-26 18:30:12 +09:00
Dean Herbert
3f179e3903 Sort scores immediately for good measure 2025-08-26 17:51:14 +09:00
Dean Herbert
196b28115e Fix playlist leaderboard provider potentially inserting local user in wrong order
Due to `Perform` being used from a BDL method in conjunction with
`Success` (which is scheduled to the *update* thread), there was a
chance that the order of execution would be not quite as intended.

To rectify, let's not use `Success` and just continue with synchronous
flow.
2025-08-26 17:51:02 +09:00
Dean Herbert
7660a9ba8e Merge pull request #34794 from bdach/fix-aim-meter
Fix aim error meter applying incorrect scaling constant in normalised mode
2025-08-26 15:16:15 +09:00
Bartłomiej Dach
e908b80359 Fix aim error meter applying incorrect scaling constant in relative mode
Closes https://github.com/ppy/osu/issues/34769

Visible (and easiest to check) in test scene.
2025-08-25 14:20:05 +02:00
Bartłomiej Dach
a2bf8e3988 Fix copy-paste fail in log message 2025-08-25 13:43:03 +02:00
5b186bb740 potentially make logo look less weird (untested)
uh, yeah, I accidentally flipped the colors around in the UpdateColour() method (which I should've probably make private or protected), and it's the reason why the logo overall looked dimmer than it should've

anyhow, this should *probably* look a bit better, don't have any means to test it yet though
2025-08-25 12:46:27 +02:00
Bartłomiej Dach
6e8246b539 Merge pull request #34761 from frenzibyte/fix-flashlight
Fix flashlight not always matching gameplay scaling
2025-08-25 12:03:58 +02:00
6cb99c13c2 added cookie color customization (which shouldn't have been done) 2025-08-24 19:46:36 +03:00
Salman Alshamrani
3cca458c21 Fix xmldoc error and reword 2025-08-24 18:55:45 +03:00
Salman Alshamrani
bc59270f3e Fix flashlight not handling internal playfield sizing changes
Note that this does not handle sizing/scaling changes applied directly
to `Playfield`, but it handles any changes within the layers inside
`PlayfieldAdjustmentContainer`.
2025-08-24 17:51:05 +03:00
96008e06ab added settings toggle for song select v1 2025-08-24 05:42:59 +03:00
590b0a8028 welcome back select v1 2025-08-24 04:55:25 +03:00
70f7f09a83 synchronize with github (ppy/osu) 2025-08-23 18:11:07 +03:00
Dean Herbert
16343fd7d6 Merge pull request #34766 from bdach/remove-double-lookup
Pull up online beatmap set lookup to song select level to avoid two components doing the same fetch independently
2025-08-23 20:50:17 +09:00
Dean Herbert
acafc06bcc Merge pull request #34757 from bdach/new-mod-icons
Update mod icons
2025-08-23 19:55:10 +09:00
Salman Alshamrani
c0c3690908 Remove no longer valid test 2025-08-23 09:28:14 +03:00
Bartłomiej Dach
5292d4a04e Fix song select favourite button potentially showing stale data from (un)favourite request callback 2025-08-22 14:25:25 +02:00
Bartłomiej Dach
d3ae20dd88 Pull up online beatmap set lookup to song select level to avoid two components doing the same fetch independently 2025-08-22 14:25:21 +02:00
Dean Herbert
c852e5854c Merge pull request #34723 from bdach/status-updates-are-great-arent-they
Refresh realm before performing song select refetches following an online metadata lookup
2025-08-22 20:25:36 +09:00
Bartłomiej Dach
03e7e2b0d8 Update tests 2025-08-22 12:44:08 +02:00
Bartłomiej Dach
20b316d32d Add indicator for pinned rooms in upper right of room panel 2025-08-22 10:17:15 +02:00
Dan Balasescu
0756c45d70 No longer download iOS simulator
https://github.com/actions/runner-images/issues/12862#issuecomment-3209787203
2025-08-22 13:29:46 +09:00
Salman Alshamrani
73624e4e25 Add visual test setup for taiko flashlight 2025-08-21 19:03:43 +03:00
Salman Alshamrani
f374af7ce7 Fix taiko flashlight applying aspect ratio twice 2025-08-21 19:03:43 +03:00
Salman Alshamrani
7530ad1a7b Adjust default flashlight size on osu! & osu!catch
Because the flashlight is made to be scaled by playfield, there are
constant scale factors applied somewhere in the
`PlayfieldAdjustmentContainer` which needs to be reflected in the
flashlight size to keep the size the same.

The factor is specifically 1.6x, computed in {Osu,Catch}PlayfieldAdjustmentContainer.ScalingContainer`.

More generally, I've deduced these factors by logging the difference
between the `flashlightSize` before and after b78abe2f.
2025-08-21 19:03:43 +03:00
Salman Alshamrani
a049f5065d Fix flashlight not correctly scaled to match playfield 2025-08-21 19:03:43 +03:00
Bartłomiej Dach
4627c8a859 Update resources 2025-08-21 14:44:43 +02:00
Bartłomiej Dach
a6f823e5bc Show pinned rooms on top of listing 2025-08-21 14:18:13 +02:00
Dean Herbert
30f7da8f71 Merge pull request #34759 from bdach/BACKGROUND-STUCK-PLEASE-I-BEG-YOU
Fix song select background being stuck in revealed state
2025-08-21 21:01:59 +09:00
Dean Herbert
4b8ff481fd Merge pull request #34752 from bdach/avoid-endless-futile-backpopulation
Fix submission & rank date backpopulation failing every launch for some users
2025-08-21 20:37:03 +09:00
Bartłomiej Dach
a7f1795f98 Fix song select background being stuck in revealed state
Closes https://github.com/ppy/osu/issues/34731.

The failure scenario here is as follows:

- User holds down left mouse button for >200ms to reveal the background.
- User presses down another mouse button and releases it in <200ms.
- User releases left mouse button. Song select does not return.

The timing here is key because what is happening here is that the second
mouse button press is overwriting the `revealingBackground` scheduled
delegate. Releasing that same mouse button within 200ms leads to that
scheduled delegate being cancelled and cleared, and thus the release of
left mouse wrongly decides there is nothing left to do.

One thing I'm not entirely sure about is the release behaviour even with
this change; as things stand, the first release of any mouse button will
bring song select back, even if it was not the button that was initially
held down to reveal the background. That's probably easily fixed if
deemed required, but I'm most interested in fixing the bad breakage.
2025-08-21 11:31:37 +02:00
Bartłomiej Dach
c053cfbf9b Adjust icon sizings in mod display to match new assets 2025-08-21 09:00:48 +02:00
Bartłomiej Dach
e47a60f303 Add test steps to mod icon test scene for exercising all rulesets 2025-08-21 09:00:46 +02:00
Bartłomiej Dach
92016a7d9b Add and use new mod icon assets 2025-08-21 09:00:44 +02:00
Dean Herbert
41885c0fc0 Merge pull request #34643 from frenzibyte/leaderboard-resize
Fix leaderboard not resizing correctly
2025-08-21 13:33:24 +09:00
Dean Herbert
e75a6b4010 Log bass issues for more than one frame 2025-08-21 13:27:14 +09:00
Dean Herbert
ddce11fbc8 Adjust bass invalid data threshold 2025-08-21 13:27:13 +09:00
Bartłomiej Dach
c894969d17 Fix submission & rank date failing every launch for some users
Addresses https://github.com/ppy/osu/discussions/34705, I suppose.

The cagey tone of that statement is because this change merely papers
over the issue. The issue in question for the user that reported this is
that they have a bunch of very old beatmaps, whose md5 hashes do not
match the online hashes, that need updating. The submission/rank date
population was running every single time for these, and failing every
time, because there is really not much useful that the lookup *can* do.

Because mappers have made `OnlineID` essentially useless for determining
the provenance of a beatmap due to reusing them to "fix" beatmap
submission failures, online IDs have been explicitly disallowed from use
in any sort of beatmap lookup flow. The only things that are allowed to
be used are: md5 of the beatmap, and filename as a fallback for very old
beatmaps / beatmap packs.

If the user has local beatmaps with md5 not matching online, chances are
that any metadata lookups are likely to fail or return bogus data. At
that point my personal feeling is that backpopulation flows should leave
such beatmaps well alone and the user should just go update the beatmap
themselves.

I am aware that updating 124 individual beatmap sets would - in the
current state of things - would probably be a ridiculously onerous thing
to do, and that people have been asking multiple times for a facility to
update all local beatmaps at once, but that discussion is out of scope
at this stage.
2025-08-20 09:21:35 +02:00
Bartłomiej Dach
ad6c0c272d Fix leaderboard score text never showing if leaderboard starts collapsed
Only seems to reproduce in gameplay for whatever reason. Can't justify
spending time to chase down why really because the previous code looked
obviously wrong on closer inspection anyway (`rightLayer` has transforms
applied to it on collapse/expand).
2025-08-19 13:32:01 +02:00
Bartłomiej Dach
083365f332 Always use audio from maximised player if there is one in multiplayer spectator 2025-08-19 12:03:35 +02:00
Bartłomiej Dach
62b4999184 Add failing test case 2025-08-19 12:03:12 +02:00
Salman Alshamrani
bb5933ef80 Add test for scores with long score/combo numbers 2025-08-18 13:46:51 +03:00
Salman Alshamrani
62548244bc Hide right-side numbers when not enough space is available 2025-08-18 13:46:08 +03:00
Bartłomiej Dach
a393b3c6b1 Refresh realm before performing song select refetches following an online metadata lookup
Probably closes https://github.com/ppy/osu/issues/34716

Can't see any other cause, can reproduce the issue on master using
manual db modifications via realm studio and it is not a consistent
reproduction, so seems like an open-and-shut lack of refresh.
2025-08-18 09:48:32 +02:00
Salman Alshamrani
a3443f76be Limit leaderboard size to sane minimum values 2025-08-13 12:52:08 +03:00
Salman Alshamrani
d998847271 Fix leaderboard not resizing correctly 2025-08-13 12:51:51 +03:00
Salman Alshamrani
62803af1de Add ability to resize leaderboard in tests 2025-08-13 12:51:09 +03:00
Givikap120
dce4132209 Nerf Low AR HD bonus for slideraim (#34215)
* Refactor slider factor calculation

* Nerf low AR HD bonus for slideraim

* finish merge

* Fixes

* Fix comment

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-08-09 19:40:37 +00:00
James Wilson
fa1fea02dc Fix edge case that estimates sliderbreaks in impossible scenarios (#34544)
* Test theory crafting

* Place in more appropriate place

* fix a bit better

* Move things around

* Reduce diff

---------

Co-authored-by: StanR <hi@stanr.info>
2025-08-07 19:13:00 +01:00
StanR
802e559472 Add DF flashlight rating reduction (#34081)
* Add DF flashlight rating reduction

* Use reverse lerp
2025-08-06 17:10:00 +01:00
Eloise
dbb16fc834 osu!taiko reduce multiplier for hidden on lazer (#34089)
* Reduce multiplier for hidden on lazer

* Refactor

* Quality

* The space
2025-07-30 21:48:45 +02:00
Eloise
eaaca60b1d osu!taiko new acc pp formula + rhythm difficulty penalty (#34188)
* New acc curve

* Penalise rhythm difficulty based on unstable rate

* Rename mono acc stuff for more clarity

* Fix nullable

* Rename stuff

* Get actual estimation for SS unstable rate

* Double space my bad

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-07-29 18:03:13 +00:00
Eloise
803e30f50f osu!taiko consistency factor changes using object strains (#34327)
* Calculate consistency factor from object strains

* Use `totalDifficultHits` in performance calc

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-07-28 13:58:54 +00:00
Jay Lawton
e54779ceee Fix colour penalties being bypassed via repeated ratio variance (#33641)
* fix a lil bit of colour

* review comments

* fix empty initialiser
2025-07-27 14:31:46 +00:00
StanR
83765abe34 Make visibility-based bonuses be additive to ratingMultiplier instead of multiplicative (#34367)
* Make visibility-based bonuses be additive to `ratingMultiplier` instead of multiplicative

* Slightly buff low AR HD, slightly nerf low AR TC
2025-07-25 19:51:30 +00:00
James Wilson
28d36dd3bd Move rating calculations to OsuRatingCalculator (#33265)
* Move rating calculations to `OsuRatingCalculator`

* Use `CalculateDifficultyRating`
2025-07-25 18:47:21 +03:00
James Wilson
945db7b431 Fix backwards logic on visibility bonus (#34369)
Co-authored-by: StanR <hi@stanr.info>
2025-07-25 06:50:23 +00:00
Givikap120
56b072cfd9 remove high CS bonus from slider bonus (#34214)
Co-authored-by: StanR <hi@stanr.info>
2025-07-24 15:41:36 +00:00
Jay Lawton
ddf9d6b8c8 ensure monolengthbonus applies to new strain contribution only (#33635)
* stamina fix

* review changes

* fix naming

---------

Co-authored-by: StanR <hi@stanr.info>
2025-07-22 09:37:51 +00:00
Givikap120
a75e0c3850 Refactor AR and OD calculations in osu! pp calculation (#34065)
* Add AR and OD calculation functions

* use created functions in perfcalc
2025-07-08 18:37:41 +03:00
Dan Balasescu
f2dcf2024a Merge branch 'master' into pp-dev 2025-07-08 20:58:22 +09:00
Dean Herbert
7ec6c8bf57 Merge branch 'master' into pp-dev 2025-07-07 17:56:44 +09:00
Natelytle
cf4d6bea72 Implement difficulty evaluators in the osu! mania ruleset (#33411)
* stuff

* Implement evaluators

* Typo

* Fixes

* clarifying comment

* Fix CalculateInitialStrain

* Remove debug line

* Small code quality fix

* Address comments, slight code quality fixes

* Change comment for clarity

---------

Co-authored-by: StanR <hi@stanr.info>
2025-06-27 23:46:52 +01:00
Natelytle
d5ef8c8524 Replace error functions in DifficultyCalculationUtils with good-enough approximations (#33717)
* Reimplement error functions

* Fix bug with adjustment for negative values

* Formatting

---------

Co-authored-by: tsunyoku <tsunyoku@gmail.com>
2025-06-18 13:14:01 +00:00
Givikap120
b783bb70e9 Optimize rhythm evaluation by replacing curve (#33423)
* Update RhythmEvaluator.cs

* add smoothstep bell curve

* Update osu.Game.Rulesets.Osu/Difficulty/Evaluators/RhythmEvaluator.cs

Co-authored-by: StanR <castl@inbox.ru>

* Update osu.Game.Rulesets.Osu/Difficulty/Evaluators/RhythmEvaluator.cs

Co-authored-by: StanR <castl@inbox.ru>

* Rename variables

---------

Co-authored-by: StanR <castl@inbox.ru>
Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-06-13 13:02:31 +05:00
James Wilson
19e9bffc11 Q2 osu! PP rebalance (#33640)
* Rebalance aim and speed

* Rebalance star rating

* Attempt further speed balancing

* More balancing

* More balancing

* Buff aim a bit

* More speed balancing

* Global rebalance

* Speed balancing

* Global rebalancing

* More speed balancing

* Buff aim

* MORE BALANCING

* Revert "Rebalance star rating"

This reverts commit f48c7445e12174c65b74edfef863cb3ae3cc29ff.
2025-06-11 19:46:46 +03:00
StanR
87023b22ea Remove wide/wiggle angle bonus rhythm requirements (#31409)
* Remove aim angle bonuses angle restrictions

* Remove unrelated change

* Only apply acute bonus for similar rhythms

* Cleanup

* Fix incorrect multiplication order

* Remove unrelated wide bonus change

* Remove redundant check

* Award less wide/wiggle bonus for sliders

* Balancing

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-06-10 11:20:55 +00:00
Eloise
7066f3def7 osu!taiko changes to length bonus using consistency factor (#33582)
* Implement new formulas for length bonus

* Add comment(s)

* Fix up HDFL thing
2025-06-10 11:31:11 +01:00
StanR
699fbb1a85 Decouple velocity change bonus from wide angle bonus (#33541)
* Decouple velocity change bonus from wide angle bonus

* Replace sin with smoothstep

* Set multiplier back to 0.75

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-06-09 11:02:49 +00:00
Eloise
5df41c08f4 osu!taiko new miss penalty using consistency factor (#33409)
* New formulas for effective miss count and penalty

* More elaborate comments

* More comment stuff
2025-06-08 22:47:26 +00:00
Natelytle
c4b07413b1 Refactor and re-comment osu! standard deviation calculations (#33218)
* Refactor

* Fix typo

* Prevent double.PositiveInfinity from occuring

* Fix leftover code branch

* Fix some idiot putting Math.Max instead of Math.Min

* Address NaN values

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-06-08 22:41:13 +00:00
Eloise
6ae8a68389 osu!taiko simplify pp summing and make performance attributes accurate (#33500)
* Change pp summing and adjust multipliers

* Add back convert consideration for hidden

* And the other one whoops

---------

Co-authored-by: StanR <hi@stanr.info>
2025-06-08 08:48:28 +00:00
Wulpey
642b938358 Reduce combo scaling for osu!catch (#33417)
* Reduce combo scaling for osu!catch

This is a conservative reduction, a middle point between the current
scaling and the CSR proposals.

* Reduce osu!catch combo scaling further

0.45 makes little difference so let's reduce it a bit more.

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-06-07 14:17:46 +00:00
Eloise
6a9aeda5d4 Remove multipliers nerfing ez (#33415) 2025-06-06 16:46:33 +03:00
Eloise
b982c3cd20 Remove stamina skill buff from strain length bonus (#33380)
Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-06-03 14:47:42 +01:00
Givikap120
366f2469ef Fix incorrect limit for sliderbreak estimation (#33110)
* fix incorrect clamp

* Add inline comment to explain `possibleBreaks` calculation

* move limit to aim and speed functions

* fix negative okMehAdjustment

* fix cases where lazer effective misscount gets reduced

* Simplify scope of changes

* Correct variable name

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-06-03 09:29:16 +01:00
Bartłomiej Dach
737ec8b2a8 Merge branch 'master' into pp-dev 2025-05-31 19:55:56 +02:00
Givikap120
63654ad1e0 Replace HD acc scaling adjust with reverse lerp util (#33271) 2025-05-28 13:59:23 +01:00
Givikap120
01d9c526d9 Rebalance HD bonus (#33237)
* initial commit

* changed HD curve

* removed AR variable

* update for new rework

* nerf HD acc bonus for AR>10

* add another HD nerf for AR>10

* Update OsuDifficultyCalculator.cs

* fix speed part being missing

* Update OsuDifficultyCalculator.cs

* rework to difficulty-based high AR nerf

* move TC back to perfcalc

* fix nvicka

* fix comment

* use utils function instead of manual one

* Clean up

* Use "visibility" term instead

* Store `mechanicalDifficultyRating` field

* Rename `isFullyHidden` to `isAlwaysPartiallyVisible` and clarify intent

* Remove redundant comment

* Add `calculateDifficultyRating` method

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-05-26 13:16:48 +03:00
Jay Lawton
ace74824b8 Add a consistency factor to osu!taiko diffcalc (#33233)
* add consistency attribute

* write attributes to json for serialisation

* comment change

* fix json, add mechanical difficulty

* write new attributes to database

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-05-23 11:57:37 +00:00
Givikap120
ee055ba8f5 Add spinners support to combo based estimated misscount (#33170)
* add spinner support

* Make `CalculateSpinnerScore` private & clarify comments

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-05-22 22:27:16 +00:00
StanR
60eaf088df Buff precision difficulty rating in osu! (#28877)
* Buff precision difficulty rating in osu!

* Fix position repetition calculation

* Fix aim evaluator crashing, move small circle bonus calculation, adjust the curve slightly

* Refactor

* Fix code quality

* Semicolon

* Apply small circle bonus to speed too

* Fix formatting

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-05-22 09:11:51 +01:00
James Wilson
4a343ceaf1 Move Ruleset and DifficultyCalculator allocations to global setup (#33220) 2025-05-21 11:25:20 +00:00
James Wilson
553a8601ed Add AimEstimatedSliderBreaks and SpeedEstimatedSliderBreaks performance attributes (#33181) 2025-05-18 12:50:29 +00:00
Givikap120
9314ea94b5 Change effective misscount to be based on legacy score and combo at the same time (#33066)
* implement stuff

* fix basic issues

* rework calculations

* sanity check

* don't use score based misscount if no scorev1 present

* Update OsuPerformanceCalculator.cs

* update misscount diff attribute names

* add raw score misscount attribute

* introduce more reasonable high bound for misscount

* code quality changes

* Fix osu!catch SR buzz slider detection (#32412)

* Use `normalized_hitobject_radius` during osu!catch buzz slider detection

Currently the algorithm considers some buzz sliders as standstills when
in reality they require movement. This happens because `HalfCatcherWidth`
isn't normalized while `exactDistanceMoved` is, leading to an inaccurate
comparison.

`normalized_hitobject_radius` is the normalized value of `HalfCatcherWidth`
and replacing one with the other fixes the problem.

* Rename `normalized_hitobject_radius` to `normalized_half_catcher_width`

The current name is confusing because hit objects have no radius in the
context of osu!catch difficulty calculation. The new name conveys the
actual purpose of the value.

* Only set `normalized_half_catcher_width` in `CatchDifficultyHitObject`

Prevents potential bugs if the value were to be changed in one of the
classes but not in both.

* Use `CatchDifficultyHitObject.NORMALIZED_HALF_CATCHER_WIDTH` directly

Requested during code review.

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>

* Move osu!catch movement diffcalc to an evaluator (#32655)

* Move osu!catch movement state into `CatchDifficultyHitObject`

In order to port `Movement` to an evaluator, the state has to be either
moved elsewhere or calculated inside the evaluator. The latter requires
backtracking for every hit object, which in the worst case is continued
until the beginning of the map is reached. Limiting backtracking can
lead to difficulty value changes.

Thus, the first option was chosen for its simplicity.

* Move osu!catch movement difficulty calculation to an evaluator

Makes the code more in line with the other game modes.

* Add documentation for `CatchDifficultyHitObject` fields

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>

* Move all score-independent bonuses into star rating (#31351)

* basis refactor to allow for more complex SR calculations

* move all possible bonuses into star rating

* decrease star rating scaling to account for overall gains

* add extra FL guard for safety

* move star rating multiplier into a constant

* Reorganise some things

* Add HD and SO to difficulty adjustment mods

* Move non-legacy mod multipliers back to PP

* Some merge fixes

* Fix application of flashlight rating multiplier

* Fix Hidden bonuses being applied when Blinds mod is in use

* Move part of speed OD scaling into difficulty

* Move length bonus back to PP

* Remove blinds special case

* Revert star rating multiplier decrease

* More balancing

---------

Co-authored-by: StanR <hi@stanr.info>

* Add diffcalc considerations for Magnetised mod (#33004)

* Add diffcalc considerations for Magnetised mod

* Make speed reduction scale with power too

* cleaning up

* Update OsuPerformanceCalculator.cs

* Update OsuPerformanceCalculator.cs

* add new check to avoid overestimation

* fix code style

* fix nvicka

* add database attributes

* Refactor

* Rename `Working` to `WorkingBeatmap`

* Remove redundant condition

* Remove useless variable

* Remove `get` wording

* Rename `calculateScoreAtCombo`

* Remove redundant operator

* Add comments to explain how score-based miss count derivations work

* Remove redundant `decimal` calculations

* use static method to improve performance

* move stuff around for readability

* move logic into helper class

* fix the bug

* Delete OsuLegacyScoreProcessor.cs

* Delete ILegacyScoreProcessor.cs

* revert static method for multiplier

* use only basic combo score attribute

* Clean-up

* Remove unused param

* Update osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs

Co-authored-by: StanR <castl@inbox.ru>

* rename variables

* Add `LegacyScoreUtils`

* Add fail safe

* Move `countMiss`

* Better explain `CalculateRelevantScoreComboPerObject`

* Add `OsuLegacyScoreMissCalculator`

* Move `CalculateScoreAtCombo` and `CalculateRelevantScoreComboPerObject`

* Remove unused variables

* Move `GetLegacyScoreMultiplier`

* Add `estimated` wording

---------

Co-authored-by: wulpine <wulpine@proton.me>
Co-authored-by: James Wilson <tsunyoku@gmail.com>
Co-authored-by: StanR <hi@stanr.info>
Co-authored-by: StanR <castl@inbox.ru>
2025-05-16 23:38:12 +00:00
James Wilson
d22b3fb200 Remove track usage in difficulty and performance calculations (#33132) 2025-05-14 12:37:08 +00:00
KermitNuggies
3165b147ee Use proportion of difficult sliders to better estimate sliderbreaks on classic accuracy scores (#31234)
* scale misscount by proportion of difficult sliders

* cap sliderbreak count at count100 + count50

* use countMiss instead of effectiveMissCount as the base for sliderbreaks

* make code inspector happy + cleanup

* refactor to remove unnecesary calculation and need for new tuple

* scale sliderbreaks with combo

* use aimNoSliders for sliderbreak factor

* code cleanup

* make inspect code happy

* use diffcalcutils

* fix errors (oops)

* scaling changes

* fix div by zeros

* Fix compilation error

* Add online attributes for new difficulty attributes

* Formatting

* Rebase fixes

* Make `CountTopWeightedSliders` to remove weird protected `SliderStrains` list

* Prevent top weighted slider factor from being Infinity

---------

Co-authored-by: tsunyoku <tsunyoku@gmail.com>
2025-05-12 14:05:07 +01:00
StanR
ce73dbbcc6 Add diffcalc considerations for Magnetised mod (#33004)
* Add diffcalc considerations for Magnetised mod

* Make speed reduction scale with power too
2025-05-01 11:52:43 +01:00
Nathan Corbett
4f298760de Use sliders in acc pp if scorev2 is enabled (#32634)
Co-authored-by: StanR <hi@stanr.info>
2025-04-27 11:57:51 +00:00
James Wilson
2aeb80a8bd Move all score-independent bonuses into star rating (#31351)
* basis refactor to allow for more complex SR calculations

* move all possible bonuses into star rating

* decrease star rating scaling to account for overall gains

* add extra FL guard for safety

* move star rating multiplier into a constant

* Reorganise some things

* Add HD and SO to difficulty adjustment mods

* Move non-legacy mod multipliers back to PP

* Some merge fixes

* Fix application of flashlight rating multiplier

* Fix Hidden bonuses being applied when Blinds mod is in use

* Move part of speed OD scaling into difficulty

* Move length bonus back to PP

* Remove blinds special case

* Revert star rating multiplier decrease

* More balancing

---------

Co-authored-by: StanR <hi@stanr.info>
2025-04-27 12:30:05 +01:00
wulpine
7a9d31adb6 Move osu!catch movement diffcalc to an evaluator (#32655)
* Move osu!catch movement state into `CatchDifficultyHitObject`

In order to port `Movement` to an evaluator, the state has to be either
moved elsewhere or calculated inside the evaluator. The latter requires
backtracking for every hit object, which in the worst case is continued
until the beginning of the map is reached. Limiting backtracking can
lead to difficulty value changes.

Thus, the first option was chosen for its simplicity.

* Move osu!catch movement difficulty calculation to an evaluator

Makes the code more in line with the other game modes.

* Add documentation for `CatchDifficultyHitObject` fields

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-04-10 15:47:11 +00:00
StanR
cf7fdc0627 Move difficulty calculation fields from Slider to OsuDifficultyHitObject (#32410)
* Move difficulty calculation fields from `Slider` to `OsuDifficultyHitObject`

* Remove redundant check

* Use `LastObject` where possible

* Update tests

* Make `LazyTravelDistance` `double`

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-04-09 13:37:26 +00:00
StanR
30f9716db9 Reduce RX Ok multiplier (#32434) 2025-04-09 12:48:18 +00:00
James Wilson
69c90f9926 Use Precision.AlmostEquals to compare deviation lower bound (#32694) 2025-04-06 09:36:18 +01:00
wulpine
0c3ee1938e Fix osu!catch SR buzz slider detection (#32412)
* Use `normalized_hitobject_radius` during osu!catch buzz slider detection

Currently the algorithm considers some buzz sliders as standstills when
in reality they require movement. This happens because `HalfCatcherWidth`
isn't normalized while `exactDistanceMoved` is, leading to an inaccurate
comparison.

`normalized_hitobject_radius` is the normalized value of `HalfCatcherWidth`
and replacing one with the other fixes the problem.

* Rename `normalized_hitobject_radius` to `normalized_half_catcher_width`

The current name is confusing because hit objects have no radius in the
context of osu!catch difficulty calculation. The new name conveys the
actual purpose of the value.

* Only set `normalized_half_catcher_width` in `CatchDifficultyHitObject`

Prevents potential bugs if the value were to be changed in one of the
classes but not in both.

* Use `CatchDifficultyHitObject.NORMALIZED_HALF_CATCHER_WIDTH` directly

Requested during code review.

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-03-24 20:04:40 +03:00
Jay Lawton
8b11be5ac0 osu!taiko skills refactor (#32426)
Co-authored-by: James Wilson <tsunyoku@gmail.com>
2025-03-24 10:07:23 +00:00
Dan Balasescu
9eadc9f68c Merge branch 'master' into pp-dev 2025-03-24 10:49:46 +09:00
StanR
2c88e60ed3 Add difficulty calculation benchmarks (#32542) 2025-03-23 21:08:41 +00:00
LukynkaCZE
1e2468d2bb Fix SkinDeserialisationTest failing 2025-03-08 23:02:57 +01:00
LukynkaCZE
cc7e60daab forgot remove initializer vlaue 2025-03-08 21:46:17 +01:00
LukynkaCZE
bb588566e6 fix ToString 2025-03-08 21:38:45 +01:00
LukynkaCZE
cbab183ea1 add test scene 2025-03-08 21:34:27 +01:00
LukynkaCZE
b1e0cf8532 add ArgonJudgementCounterDisplay 2025-03-08 21:07:51 +01:00
Kian Masri
245ade004a new: rank Taiko single tap 2024-12-11 09:47:17 -07:00
Kian Masri
6cb46106fe new: also the single tap mod, it's the same thing 2024-12-10 10:04:36 -07:00
Kian Masri
3666e4c332 new: rank the alternate mode 2024-12-10 09:50:48 -07:00
901 changed files with 24311 additions and 5601 deletions

View File

@@ -19,6 +19,11 @@ indent_style = space
indent_size = 4
trim_trailing_whitespace = true
# temporary workaround for https://youtrack.jetbrains.com/issue/RIDER-130051/Cannot-resolve-symbol-inspections-incorrectly-firing-for-xmldoc-protected-member-references
resharper_c_sharp_warnings_cs1574_cs1584_cs1581_cs1580_highlighting = hint
# temporary workaround for https://youtrack.jetbrains.com/issue/RIDER-130381/Rider-does-not-respect-propagated-NoWarn-CS1591?backToIssues=false
dotnet_diagnostic.CS1591.severity = none
#license header
file_header_template = Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\nSee the LICENCE file in the repository root for full licence text.

View File

@@ -1,12 +1,6 @@
blank_issues_enabled: false
blank_issues_enabled: true
contact_links:
- name: Help
url: https://github.com/ppy/osu/discussions/categories/q-a
about: osu! not working or performing as you'd expect? Not sure it's a bug? Check the Q&A section!
- name: Suggestions or feature request
url: https://github.com/ppy/osu/discussions/categories/ideas
about: Got something you think should change or be added? Search for or start a new discussion!
- name: osu!stable issues
url: https://github.com/ppy/osu-stable-issues
about: For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support.
url: https://t.me/jvnkosu_chat
about: Your jvnkosu! is not working right? Please contact us using our Telegram chat

View File

@@ -1,8 +1,10 @@
name: Update osu-web mod definitions
name: Update osu-web mod definitions (DO NOT USE YET!!!!!)
on:
push:
tags:
- '*'
workflow_dispatch:
# push:
# tags:
# - '*'
permissions:
contents: read # to fetch code (actions/checkout)

View File

@@ -1,4 +1,10 @@
on: [push, pull_request]
on:
push:
tags:
- '*'
workflow_dispatch:
name: Continuous Integration
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -33,7 +39,7 @@ jobs:
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
- name: Dotnet code style
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf -p:EnforceCodeStyleInBuild=true
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
- name: CodeFileSanity
run: |
@@ -148,9 +154,7 @@ jobs:
# https://github.com/dotnet/macios/issues/19157
# https://github.com/actions/runner-images/issues/12758
- name: Use Xcode 16.4
run: |
sudo xcode-select -switch /Applications/Xcode_16.4.app
xcodebuild -downloadPlatform iOS
run: sudo xcode-select -switch /Applications/Xcode_16.4.app
- name: Build
run: dotnet build -c Debug osu.iOS.slnf

View File

@@ -4,6 +4,7 @@ on:
push:
tags:
- '*'
workflow_dispatch:
jobs:
notify_pending_production_deploy:
@@ -12,7 +13,7 @@ jobs:
- name: Submit pending deployment notification
run: |
export TITLE="Pending osu Production Deployment: $GITHUB_REF_NAME"
export URL="https://github.com/ppy/osu/actions/runs/$GITHUB_RUN_ID"
export URL="https://github.com/jvnkosu-dev/client/actions/runs/$GITHUB_RUN_ID"
export DESCRIPTION="Awaiting approval for building NuGet packages for tag $GITHUB_REF_NAME:
[View Workflow Run]($URL)"
export ACTOR_ICON="https://avatars.githubusercontent.com/u/$GITHUB_ACTOR_ID"

View File

@@ -21,9 +21,9 @@ jobs:
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ppy
SENTRY_PROJECT: osu
SENTRY_URL: https://sentry.ppy.sh/
SENTRY_ORG: jvnkosu
SENTRY_PROJECT: client
SENTRY_URL: https://satellite.jvnko.boats/
with:
environment: production
version: osu@${{ github.ref_name }}
version: jvnkosu@${{ github.ref_name }}

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"dotnet.defaultSolution": "osu.Desktop.slnf"
}

View File

@@ -73,6 +73,9 @@ Aside from the above, below is a brief checklist of things to watch out when you
After you're done with your changes and you wish to open the PR, please observe the following recommendations:
- Please submit the pull request from a [topic branch](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#_topic_branch) (not `master`), and keep the *Allow edits from maintainers* check box selected, so that we can push fixes to your PR if necessary.
- Please pick the following target branch for your pull request:
- `pp-dev`, if the change impacts star rating or performance points calculations for any of the rulesets,
- `master`, otherwise.
- Please avoid pushing untested or incomplete code.
- Please do not force-push or rebase unless we ask you to.
- Please do not merge `master` continually if there are no conflicts to resolve. We will do this for you when the change is ready for merge.

View File

@@ -49,7 +49,7 @@
<PackageProjectUrl>https://github.com/ppy/osu</PackageProjectUrl>
<RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl>
<PackageReleaseNotes>Automated release.</PackageReleaseNotes>
<Company>ppy Pty Ltd</Company>
<Company>ppy Pty Ltd, jvnkosu! team</Company>
<Copyright>Copyright (c) 2025 ppy Pty Ltd</Copyright>
<PackageTags>osu game</PackageTags>
</PropertyGroup>

149
README.md
View File

@@ -1,147 +1,40 @@
<p align="center">
<img width="500" alt="osu! logo" src="assets/lazer.png">
</p>
# jvnkosu! client
# osu!
A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!
[![Build status](https://github.com/ppy/osu/actions/workflows/ci.yml/badge.svg?branch=master&event=push)](https://github.com/ppy/osu/actions/workflows/ci.yml)
[![GitHub release](https://img.shields.io/github/release/ppy/osu.svg)](https://github.com/ppy/osu/releases/latest)
[![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu)
[![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/osu-web/localized.svg)](https://crowdin.com/project/osu-web)
## Disclaimer
A free-to-win rhythm game. Rhythm is just a *click* away!
*osu!* is a registered trademark of ppy Pty Ltd.
jvnkosu! is not affiliated with, or endorsed by ppy Pty Ltd., but makes use of its open-source components and resources.
This is the future and final iteration of the [osu!](https://osu.ppy.sh) game client which marks the beginning of an open era! Currently known by and released under the release codename "*lazer*". As in sharper than cutting-edge.
## License
Client source code is licensed under the MIT license, see the [LICENCE](LICENCE) file in repository root for more info.
## Status
Game assets are included as a NuGet package and licensed under the CC BY-NC 4.0, which prohibits commercial use. See [ppy/osu-resources](https://github.com/ppy/osu-resources) for more info.
This project is under constant development, but we do our best to keep things in a stable state. Players are encouraged to install from a release alongside their stable *osu!* client. This project will continue to evolve until we eventually reach the point where most users prefer it over the previous "osu!stable" release.
Registered trademarks "osu!" and "ppy" are property of ppy Pty Ltd., and protected by trademark law.
A few resources are available as starting points to getting involved and understanding the project:
## Compiling from source
Building jvnkosu! from source is pretty much possible (and welcome here).
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
- Track our current efforts [towards improving the game](https://github.com/orgs/ppy/projects/7/views/6).
First, you must have a desktop platform with [.NET Core SDK 8](https://dotnet.microsoft.com/download) installed. Windows, Linux, macOS should work well. You can check if you have the SDK installed by running `dotnet --version` in your command prompt/terminal.
## Running osu!
If you are just looking to give the game a whirl, you can grab the latest release for your platform:
### Latest release:
| [Windows 10+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 12+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------- | ------------- | ------------- |
You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download).
If your platform is unsupported or not listed above, there is still a chance you can run the release or manually build it by following the instructions below.
**For iOS/iPadOS users**: The iOS testflight link fills up very fast (Apple has a hard limit of 10,000 users). We reset it occasionally. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements. Our goal is to get the game on mobile app stores very soon so we don't have to live with this limitation.
## Developing a custom ruleset
osu! is designed to allow user-created gameplay variations, called "rulesets". Building one of these allows a developer to harness the power of the osu! beatmap library, game engine, and general UX for a new style of gameplay. To get started working on a ruleset, we have some templates available [here](https://github.com/ppy/osu/tree/master/Templates).
You can see some examples of custom rulesets by visiting the [custom ruleset directory](https://github.com/ppy/osu/discussions/13096).
## Developing osu!
### Prerequisites
Please make sure you have the following prerequisites:
- A desktop platform with the [.NET 8.0 SDK](https://dotnet.microsoft.com/download) installed.
When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as the latest version of [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Visual Studio Code](https://code.visualstudio.com/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) plugin installed.
### Downloading the source code
Clone the repository:
```shell
git clone https://github.com/ppy/osu
cd osu
Then, download the source code. You may download it as an archive and unzip it, but using [Git](https://git-scm.com/) instead is recommended:
```
git clone https://gitea.jvnko.boats/jvnkosu/client
```
To update the source code to the latest commit, run the following command inside the `osu` directory:
```shell
git pull
To **run** the project, switch to project's directory and run the following:
```
### Building
#### From an IDE
You should load the solution via one of the platform-specific `.slnf` files, rather than the main `.sln`. This will reduce dependencies and hide platforms that you don't care about. Valid `.slnf` files are:
- `osu.Desktop.slnf` (most common)
- `osu.Android.slnf`
- `osu.iOS.slnf`
Run configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `osu! (Tests)` project/configuration. More information on this is provided [below](#contributing).
To build for mobile platforms, you will likely need to run `sudo dotnet workload restore` if you haven't done so previously. This will install Android/iOS tooling required to complete the build.
#### From CLI
You can also build and run *osu!* from the command-line with a single command:
```shell
dotnet run --project osu.Desktop
```
When running locally to do any kind of performance testing, make sure to add `-c Release` to the build command, as the overhead of running with the default `Debug` configuration can be large (especially when testing with local framework modifications as below).
If the build fails, try to restore NuGet packages with `dotnet restore`.
### Testing with resource/framework modifications
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be quickly achieved using included commands:
Windows:
```ps
UseLocalFramework.ps1
UseLocalResources.ps1
To **compile**:
```
dotnet build osu.Desktop
```
macOS / Linux:
To reduce performance overhead in custom builds, it's recommended to build with the `-c Release` flag, that will use the release profile and remove possibly unneeded debugging code.
```ps
UseLocalFramework.sh
UseLocalResources.sh
```
Note that these commands assume you have the relevant project(s) checked out in adjacent directories:
```
|- osu // this repository
|- osu-framework
|- osu-resources
```
### Code analysis
Before committing your code, please run a code formatter. This can be achieved by running `dotnet format` in the command line, or using the `Format code` command in your IDE.
We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself.
JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice.
## Contributing
When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible.
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
## Licence
*osu!*'s code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
Please note that this *does not cover* the usage of the "osu!" or "ppy" branding in any software, resources, advertising or promotion, as this is protected by trademark law.
Please also note that game resources are covered by a separate licence. Please see the [ppy/osu-resources](https://github.com/ppy/osu-resources) repository for clarifications.
### See the [original readme](README.original.md) for more info.

147
README.original.md Normal file
View File

@@ -0,0 +1,147 @@
<p align="center">
<img width="500" alt="osu! logo" src="assets/lazer.png">
</p>
# osu!
[![Build status](https://github.com/ppy/osu/actions/workflows/ci.yml/badge.svg?branch=master&event=push)](https://github.com/ppy/osu/actions/workflows/ci.yml)
[![GitHub release](https://img.shields.io/github/release/ppy/osu.svg)](https://github.com/ppy/osu/releases/latest)
[![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu)
[![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/osu-web/localized.svg)](https://crowdin.com/project/osu-web)
A free-to-win rhythm game. Rhythm is just a *click* away!
This is the future and final iteration of the [osu!](https://osu.ppy.sh) game client which marks the beginning of an open era! Currently known by and released under the release codename "*lazer*". As in sharper than cutting-edge.
## Status
This project is under constant development, but we do our best to keep things in a stable state. Players are encouraged to install from a release alongside their stable *osu!* client. This project will continue to evolve until we eventually reach the point where most users prefer it over the previous "osu!stable" release.
A few resources are available as starting points to getting involved and understanding the project:
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
- Track our current efforts [towards improving the game](https://github.com/orgs/ppy/projects/7/views/6).
## Running osu!
If you are just looking to give the game a whirl, you can grab the latest release for your platform:
### Latest release:
| [Windows 10+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 12+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------- | ------------- | ------------- |
You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download).
If your platform is unsupported or not listed above, there is still a chance you can run the release or manually build it by following the instructions below.
**For iOS/iPadOS users**: The iOS testflight link fills up very fast (Apple has a hard limit of 10,000 users). We reset it occasionally. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements. Our goal is to get the game on mobile app stores very soon so we don't have to live with this limitation.
## Developing a custom ruleset
osu! is designed to allow user-created gameplay variations, called "rulesets". Building one of these allows a developer to harness the power of the osu! beatmap library, game engine, and general UX for a new style of gameplay. To get started working on a ruleset, we have some templates available [here](https://github.com/ppy/osu/tree/master/Templates).
You can see some examples of custom rulesets by visiting the [custom ruleset directory](https://github.com/ppy/osu/discussions/13096).
## Developing osu!
### Prerequisites
Please make sure you have the following prerequisites:
- A desktop platform with the [.NET 8.0 SDK](https://dotnet.microsoft.com/download) installed.
When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as the latest version of [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Visual Studio Code](https://code.visualstudio.com/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) plugin installed.
### Downloading the source code
Clone the repository:
```shell
git clone https://github.com/ppy/osu
cd osu
```
To update the source code to the latest commit, run the following command inside the `osu` directory:
```shell
git pull
```
### Building
#### From an IDE
You should load the solution via one of the platform-specific `.slnf` files, rather than the main `.sln`. This will reduce dependencies and hide platforms that you don't care about. Valid `.slnf` files are:
- `osu.Desktop.slnf` (most common)
- `osu.Android.slnf`
- `osu.iOS.slnf`
Run configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `osu! (Tests)` project/configuration. More information on this is provided [below](#contributing).
To build for mobile platforms, you will likely need to run `sudo dotnet workload restore` if you haven't done so previously. This will install Android/iOS tooling required to complete the build.
#### From CLI
You can also build and run *osu!* from the command-line with a single command:
```shell
dotnet run --project osu.Desktop
```
When running locally to do any kind of performance testing, make sure to add `-c Release` to the build command, as the overhead of running with the default `Debug` configuration can be large (especially when testing with local framework modifications as below).
If the build fails, try to restore NuGet packages with `dotnet restore`.
### Testing with resource/framework modifications
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be quickly achieved using included commands:
Windows:
```ps
UseLocalFramework.ps1
UseLocalResources.ps1
```
macOS / Linux:
```ps
UseLocalFramework.sh
UseLocalResources.sh
```
Note that these commands assume you have the relevant project(s) checked out in adjacent directories:
```
|- osu // this repository
|- osu-framework
|- osu-resources
```
### Code analysis
Before committing your code, please run a code formatter. This can be achieved by running `dotnet format` in the command line, or using the `Format code` command in your IDE.
We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself.
JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice.
## Contributing
When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible.
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
## Licence
*osu!*'s code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
Please note that this *does not cover* the usage of the "osu!" or "ppy" branding in any software, resources, advertising or promotion, as this is protected by trademark law.
Please also note that game resources are covered by a separate licence. Please see the [ppy/osu-resources](https://github.com/ppy/osu-resources) repository for clarifications.

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageType>Template</PackageType>
<PackageId>ppy.osu.Game.Templates</PackageId>
<PackageId>jvnkosu.Client.Templates</PackageId>
<Title>osu! templates</Title>
<Authors>ppy Pty Ltd</Authors>
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>

View File

@@ -10,7 +10,7 @@
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2025.808.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2025.1209.0" />
</ItemGroup>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="sh.ppy.osulazer" android:installLocation="auto">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="boats.jvnko.osu.android" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
<application android:allowBackup="true"
android:supportsRtl="true"

View File

@@ -29,7 +29,7 @@ namespace osu.Desktop
{
internal partial class DiscordRichPresence : Component
{
private const string client_id = "1216669957799018608";
private const string client_id = "1440647613358800918";
private DiscordRpcClient client = null!;
@@ -189,7 +189,7 @@ namespace osu.Desktop
}
// user party
if (!hideIdentifiableInformation && multiplayerClient.Room != null)
if (!hideIdentifiableInformation && multiplayerClient.Room != null && multiplayerClient.Room.Settings.MatchType != MatchType.Matchmaking)
{
MultiplayerRoom room = multiplayerClient.Room;

View File

@@ -115,12 +115,10 @@ namespace osu.Desktop
if (IsFirstRun)
LocalConfig.SetValue(OsuSetting.ReleaseStream, ReleaseStream.Lazer);
// if (IsPackageManaged)
// return new NoActionUpdateManager();
if (IsPackageManaged)
return new NoActionUpdateManager();
// return new VelopackUpdateManager();
return new NoActionUpdateManager(); // for now, APIs are useless for actually downloading the releases. TODO: adapt UpdateManager for gitea
return new VelopackUpdateManager(); // yay
}
public override bool RestartAppWhenExited()
@@ -150,7 +148,13 @@ namespace osu.Desktop
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
if (iconStream != null)
try
{
host.Window.SetIconFromStream(iconStream);
}
catch
{
}
host.Window.Title = Name;
}

View File

@@ -44,7 +44,7 @@ namespace osu.Desktop
// While .NET 8 only supports Windows 10 and above, running on Windows 7/8.1 may still work. We are limited by realm currently, as they choose to only support 8.1 and higher.
// See https://www.mongodb.com/docs/realm/sdk/dotnet/compatibility/
if (windowsVersion.Major < 6 || (windowsVersion.Major == 6 && windowsVersion.Minor <= 2))
if (windowsVersion.Major < 6)
{
unsafe
{
@@ -53,13 +53,26 @@ namespace osu.Desktop
// We could also better detect compatibility mode if required:
// https://stackoverflow.com/questions/10744651/how-i-can-detect-if-my-application-is-running-under-compatibility-mode#comment58183249_10744730
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
"Your operating system is too old to run osu!"u8,
"This version of osu! requires at least Windows 8.1 to run.\n"u8
+ "Please upgrade your operating system or consider using an older version of osu!.\n\n"u8
+ "If you are running a newer version of windows, please check you don't have \"Compatibility mode\" turned on for osu!"u8, null);
"Your operating system is too old to run this game!"u8,
"This version of the game requires at least Windows 8.1 to run reliably.\n"u8
+ "You may try to run it on Windows 8 or older, but it's not guaranteed to actually work.\n\n"u8
+ "Please upgrade your operating system or consider using an older game version.\n\n"u8
+ "If you are running a newer version of Windows, please check you don't have \"Compatibility mode\" turned on for the game's executable."u8, null);
return;
}
}
if (windowsVersion.Major == 6 && windowsVersion.Minor <= 2)
{
unsafe
{
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_WARNING,
"Your operating system is too old to run this game!"u8,
"While the version of Windows you're using may be able to launch it, it's likely to work unreliably and crash.\n"u8
+ "Please upgrade your operating system or consider using an older game version.\n\n"u8
+ "If you are running a newer version of Windows, please check you don't have \"Compatibility mode\" turned on for the game's executable."u8, null);
}
}
}
// NVIDIA profiles are based on the executable name of a process.
@@ -208,9 +221,10 @@ namespace osu.Desktop
[SupportedOSPlatform("windows")]
private static void configureWindows(VelopackApp app)
{
app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
// we do not want associations here, as that breaks official lazer's associations
// app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
// app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
// app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
}
}
}

View File

@@ -55,7 +55,7 @@ namespace osu.Desktop.Updater
try
{
IUpdateSource updateSource = new GithubSource(@"https://github.com/ppy/osu", null, ReleaseStream.Value == Game.Configuration.ReleaseStream.Tachyon);
IUpdateSource updateSource = new GiteaSource(@"https://gitea.jvnko.boats/jvnkosu/client", null, ReleaseStream.Value == Game.Configuration.ReleaseStream.Tachyon);
Velopack.UpdateManager updateManager = new Velopack.UpdateManager(updateSource, new UpdateOptions
{
AllowVersionDowngrade = true

View File

@@ -53,8 +53,8 @@ namespace osu.Desktop.Windows
private static readonly UriAssociation[] uri_associations =
{
new UriAssociation(@"osu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
new UriAssociation(@"osump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
new UriAssociation(@"jvnkosu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
new UriAssociation(@"jvnkosump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
};
/// <summary>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 401 KiB

View File

@@ -3,11 +3,11 @@
<TargetFramework>net8.0</TargetFramework>
<OutputType>WinExe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>A free-to-win rhythm game. Rhythm is just a *click* away!</Description>
<Description>A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!</Description>
<AssemblyName>osu!</AssemblyName>
<AssemblyTitle>osu!(lazer)</AssemblyTitle>
<Title>osu!</Title>
<Product>osu!(lazer)</Product>
<AssemblyTitle>jvnkosu!</AssemblyTitle>
<Title>jvnkosu!</Title>
<Product>jvnkosu!</Product>
<ApplicationIcon>lazer.ico</ApplicationIcon>
<Version>0.0.0</Version>
<FileVersion>0.0.0</FileVersion>

View File

@@ -3,16 +3,19 @@
<metadata>
<id>osulazer</id>
<version>0.0.0</version>
<title>osu!</title>
<authors>ppy Pty Ltd</authors>
<title>jvnkosu!</title>
<authors>ppy Pty Ltd., jvnkosu! team</authors>
<owners>Dean Herbert</owners>
<projectUrl>https://osu.ppy.sh/</projectUrl>
<projectUrl>https://osu.jvnko.boats/</projectUrl>
<iconUrl>https://github.com/ppy/osu/blob/master/assets/lazer-nuget.png?raw=true</iconUrl>
<icon>icon.png</icon>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>A free-to-win rhythm game. Rhythm is just a *click* away!</description>
<description>A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!</description>
<releaseNotes>testing</releaseNotes>
<copyright>Copyright (c) 2025 ppy Pty Ltd</copyright>
<copyright>
Copyright (c) 2025 ppy Pty Ltd
Copyright (c) 2025 jvnkosu! team
</copyright>
<language>en-AU</language>
</metadata>
<files>

View File

@@ -0,0 +1,77 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.IO;
using BenchmarkDotNet.Attributes;
using osu.Framework.IO.Stores;
using osu.Game.Beatmaps;
using osu.Game.IO;
using osu.Game.IO.Archives;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko;
using osu.Game.Tests.Resources;
namespace osu.Game.Benchmarks
{
public class BenchmarkDifficultyCalculation : BenchmarkTest
{
private DifficultyCalculator osuCalculator = null!;
private DifficultyCalculator taikoCalculator = null!;
private DifficultyCalculator catchCalculator = null!;
private DifficultyCalculator maniaCalculator = null!;
public override void SetUp()
{
using var resources = new DllResourceStore(typeof(TestResources).Assembly);
using var archive = resources.GetStream("Resources/Archives/241526 Soleily - Renatus.osz");
using var archiveReader = new ZipArchiveReader(archive);
var osuBeatmap = readBeatmap(archiveReader, "Soleily - Renatus (Gamu) [Insane].osu");
var taikoBeatmap = readBeatmap(archiveReader, "Soleily - Renatus (MMzz) [Oni].osu");
var catchBeatmap = readBeatmap(archiveReader, "Soleily - Renatus (Deif) [Salad].osu");
var maniaBeatmap = readBeatmap(archiveReader, "Soleily - Renatus (ExPew) [Another].osu");
osuCalculator = new OsuRuleset().CreateDifficultyCalculator(osuBeatmap);
taikoCalculator = new TaikoRuleset().CreateDifficultyCalculator(taikoBeatmap);
catchCalculator = new CatchRuleset().CreateDifficultyCalculator(catchBeatmap);
maniaCalculator = new ManiaRuleset().CreateDifficultyCalculator(maniaBeatmap);
}
private WorkingBeatmap readBeatmap(ZipArchiveReader archiveReader, string beatmapName)
{
using var beatmapStream = new MemoryStream();
archiveReader.GetStream(beatmapName).CopyTo(beatmapStream);
beatmapStream.Seek(0, SeekOrigin.Begin);
using var reader = new LineBufferedReader(beatmapStream);
var decoder = Beatmaps.Formats.Decoder.GetDecoder<Beatmap>(reader);
return new FlatWorkingBeatmap(decoder.Decode(reader));
}
[Benchmark]
public void CalculateDifficultyOsu() => osuCalculator.Calculate();
[Benchmark]
public void CalculateDifficultyTaiko() => taikoCalculator.Calculate();
[Benchmark]
public void CalculateDifficultyCatch() => catchCalculator.Calculate();
[Benchmark]
public void CalculateDifficultyMania() => maniaCalculator.Calculate();
[Benchmark]
public void CalculateDifficultyOsuHundredTimes()
{
for (int i = 0; i < 100; i++)
{
osuCalculator.Calculate();
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,2 +0,0 @@
[General]
// no version specified means v1

View File

@@ -157,7 +157,7 @@ namespace osu.Game.Rulesets.Catch.Tests
}
[Test]
public void TestTinyDropletMissPreservesCatcherState()
public void TestTinyDropletMissChangesCatcherState()
{
AddStep("catch hyper kiai fruit", () => attemptCatch(new TestKiaiFruit
{
@@ -165,8 +165,8 @@ namespace osu.Game.Rulesets.Catch.Tests
}));
AddStep("catch tiny droplet", () => attemptCatch(new TinyDroplet()));
AddStep("miss tiny droplet", () => attemptCatch(new TinyDroplet { X = 100 }));
// catcher state and hyper dash state is preserved
checkState(CatcherAnimationState.Kiai);
// catcher state is changed but hyper dash state is preserved
checkState(CatcherAnimationState.Fail);
checkHyperDash(true);
}

View File

@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
private float halfCatcherWidth;
public override int Version => 20250306;
public override int Version => 20251020;
public CatchDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
: base(ruleset, beatmap)

View File

@@ -3,13 +3,13 @@
using System;
using System.Linq;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Scoring.Legacy;
using osu.Game.Utils;
namespace osu.Game.Rulesets.Catch.Difficulty
{
@@ -51,15 +51,13 @@ namespace osu.Game.Rulesets.Catch.Difficulty
// Combo scaling
if (catchAttributes.MaxCombo > 0)
value *= Math.Min(Math.Pow(score.MaxCombo, 0.8) / Math.Pow(catchAttributes.MaxCombo, 0.8), 1.0);
value *= Math.Min(Math.Pow(score.MaxCombo, 0.35) / Math.Pow(catchAttributes.MaxCombo, 0.35), 1.0);
var difficulty = score.BeatmapInfo!.Difficulty.Clone();
score.Mods.OfType<IApplicableToDifficulty>().ForEach(m => m.ApplyToDifficulty(difficulty));
var track = new TrackVirtual(10000);
score.Mods.OfType<IApplicableToTrack>().ForEach(m => m.ApplyToTrack(track));
double clockRate = track.Rate;
double clockRate = ModUtils.CalculateRateWithMods(score.Mods);
// this is the same as osu!, so there's potential to share the implementation... maybe
double preempt = IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450) / clockRate;

View File

@@ -0,0 +1,65 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Preprocessing;
namespace osu.Game.Rulesets.Catch.Difficulty.Evaluators
{
public static class MovementEvaluator
{
private const double direction_change_bonus = 21.0;
public static double EvaluateDifficultyOf(DifficultyHitObject current, double catcherSpeedMultiplier)
{
var catchCurrent = (CatchDifficultyHitObject)current;
var catchLast = (CatchDifficultyHitObject)current.Previous(0);
var catchLastLast = (CatchDifficultyHitObject)current.Previous(1);
double weightedStrainTime = catchCurrent.StrainTime + 13 + (3 / catcherSpeedMultiplier);
double distanceAddition = (Math.Pow(Math.Abs(catchCurrent.DistanceMoved), 1.3) / 510);
double sqrtStrain = Math.Sqrt(weightedStrainTime);
double edgeDashBonus = 0;
// Direction change bonus.
if (Math.Abs(catchCurrent.DistanceMoved) > 0.1)
{
if (current.Index >= 1 && Math.Abs(catchLast.DistanceMoved) > 0.1 && Math.Sign(catchCurrent.DistanceMoved) != Math.Sign(catchLast.DistanceMoved))
{
double bonusFactor = Math.Min(50, Math.Abs(catchCurrent.DistanceMoved)) / 50;
double antiflowFactor = Math.Max(Math.Min(70, Math.Abs(catchLast.DistanceMoved)) / 70, 0.38);
distanceAddition += direction_change_bonus / Math.Sqrt(catchLast.StrainTime + 16) * bonusFactor * antiflowFactor * Math.Max(1 - Math.Pow(weightedStrainTime / 1000, 3), 0);
}
// Base bonus for every movement, giving some weight to streams.
distanceAddition += 12.5 * Math.Min(Math.Abs(catchCurrent.DistanceMoved), CatchDifficultyHitObject.NORMALIZED_HALF_CATCHER_WIDTH * 2)
/ (CatchDifficultyHitObject.NORMALIZED_HALF_CATCHER_WIDTH * 6) / sqrtStrain;
}
// Bonus for edge dashes.
if (catchCurrent.LastObject.DistanceToHyperDash <= 20.0f)
{
if (!catchCurrent.LastObject.HyperDash)
edgeDashBonus += 5.7;
distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash) / 20)
* Math.Pow((Math.Min(catchCurrent.StrainTime * catcherSpeedMultiplier, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values
}
// There is an edge case where horizontal back and forth sliders create "buzz" patterns which are repeated "movements" with a distance lower than
// the platter's width but high enough to be considered a movement due to the absolute_player_positioning_error and NORMALIZED_HALF_CATCHER_WIDTH offsets
// We are detecting this exact scenario. The first back and forth is counted but all subsequent ones are nullified.
// To achieve that, we need to store the exact distances (distance ignoring absolute_player_positioning_error and NORMALIZED_HALF_CATCHER_WIDTH)
if (current.Index >= 2 && Math.Abs(catchCurrent.ExactDistanceMoved) <= CatchDifficultyHitObject.NORMALIZED_HALF_CATCHER_WIDTH * 2
&& catchCurrent.ExactDistanceMoved == -catchLast.ExactDistanceMoved && catchLast.ExactDistanceMoved == -catchLastLast.ExactDistanceMoved
&& catchCurrent.StrainTime == catchLast.StrainTime && catchLast.StrainTime == catchLastLast.StrainTime)
distanceAddition = 0;
return distanceAddition / weightedStrainTime;
}
}
}

View File

@@ -11,15 +11,49 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
{
public class CatchDifficultyHitObject : DifficultyHitObject
{
private const float normalized_hitobject_radius = 41.0f;
public const float NORMALIZED_HALF_CATCHER_WIDTH = 41.0f;
private const float absolute_player_positioning_error = 16.0f;
public new PalpableCatchHitObject BaseObject => (PalpableCatchHitObject)base.BaseObject;
public new PalpableCatchHitObject LastObject => (PalpableCatchHitObject)base.LastObject;
/// <summary>
/// Normalized position of <see cref="BaseObject"/>.
/// </summary>
public readonly float NormalizedPosition;
/// <summary>
/// Normalized position of <see cref="LastObject"/>.
/// </summary>
public readonly float LastNormalizedPosition;
/// <summary>
/// Normalized position of the player required to catch <see cref="BaseObject"/>, assuming the player moves as little as possible.
/// </summary>
public float PlayerPosition { get; private set; }
/// <summary>
/// Normalized position of the player after catching <see cref="LastObject"/>.
/// </summary>
public float LastPlayerPosition { get; private set; }
/// <summary>
/// Normalized distance between <see cref="LastPlayerPosition"/> and <see cref="PlayerPosition"/>.
/// </summary>
/// <remarks>
/// The sign of the value indicates the direction of the movement: negative is left and positive is right.
/// </remarks>
public float DistanceMoved { get; private set; }
/// <summary>
/// Normalized distance the player has to move from <see cref="LastPlayerPosition"/> in order to catch <see cref="BaseObject"/> at its <see cref="NormalizedPosition"/>.
/// </summary>
/// <remarks>
/// The sign of the value indicates the direction of the movement: negative is left and positive is right.
/// </remarks>
public float ExactDistanceMoved { get; private set; }
/// <summary>
/// Milliseconds elapsed since the start time of the previous <see cref="CatchDifficultyHitObject"/>, with a minimum of 40ms.
/// </summary>
@@ -29,13 +63,35 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
: base(hitObject, lastObject, clockRate, objects, index)
{
// We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps.
float scalingFactor = normalized_hitobject_radius / halfCatcherWidth;
float scalingFactor = NORMALIZED_HALF_CATCHER_WIDTH / halfCatcherWidth;
NormalizedPosition = BaseObject.EffectiveX * scalingFactor;
LastNormalizedPosition = LastObject.EffectiveX * scalingFactor;
// Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure
StrainTime = Math.Max(40, DeltaTime);
setMovementState();
}
private void setMovementState()
{
LastPlayerPosition = Index == 0 ? LastNormalizedPosition : ((CatchDifficultyHitObject)Previous(0)).PlayerPosition;
PlayerPosition = Math.Clamp(
LastPlayerPosition,
NormalizedPosition - (NORMALIZED_HALF_CATCHER_WIDTH - absolute_player_positioning_error),
NormalizedPosition + (NORMALIZED_HALF_CATCHER_WIDTH - absolute_player_positioning_error)
);
DistanceMoved = PlayerPosition - LastPlayerPosition;
// For the exact position we consider that the catcher is in the correct position for both objects
ExactDistanceMoved = NormalizedPosition - LastPlayerPosition;
// After a hyperdash we ARE in the correct position. Always!
if (LastObject.HyperDash)
PlayerPosition = NormalizedPosition;
}
}
}

View File

@@ -1,8 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
using osu.Game.Rulesets.Catch.Difficulty.Evaluators;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods;
@@ -11,10 +10,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
{
public class Movement : StrainDecaySkill
{
private const float absolute_player_positioning_error = 16f;
private const float normalized_hitobject_radius = 41.0f;
private const double direction_change_bonus = 21.0;
protected override double SkillMultiplier => 1;
protected override double StrainDecayBase => 0.2;
@@ -24,12 +19,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
protected readonly float HalfCatcherWidth;
private float? lastPlayerPosition;
private float lastDistanceMoved;
private float lastExactDistanceMoved;
private double lastStrainTime;
private bool isInBuzzSection;
/// <summary>
/// The speed multiplier applied to the player's catcher.
/// </summary>
@@ -49,80 +38,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
protected override double StrainValueOf(DifficultyHitObject current)
{
var catchCurrent = (CatchDifficultyHitObject)current;
lastPlayerPosition ??= catchCurrent.LastNormalizedPosition;
float playerPosition = Math.Clamp(
lastPlayerPosition.Value,
catchCurrent.NormalizedPosition - (normalized_hitobject_radius - absolute_player_positioning_error),
catchCurrent.NormalizedPosition + (normalized_hitobject_radius - absolute_player_positioning_error)
);
float distanceMoved = playerPosition - lastPlayerPosition.Value;
// For the exact position we consider that the catcher is in the correct position for both objects
float exactDistanceMoved = catchCurrent.NormalizedPosition - lastPlayerPosition.Value;
double weightedStrainTime = catchCurrent.StrainTime + 13 + (3 / catcherSpeedMultiplier);
double distanceAddition = (Math.Pow(Math.Abs(distanceMoved), 1.3) / 510);
double sqrtStrain = Math.Sqrt(weightedStrainTime);
double edgeDashBonus = 0;
// Direction change bonus.
if (Math.Abs(distanceMoved) > 0.1)
{
if (Math.Abs(lastDistanceMoved) > 0.1 && Math.Sign(distanceMoved) != Math.Sign(lastDistanceMoved))
{
double bonusFactor = Math.Min(50, Math.Abs(distanceMoved)) / 50;
double antiflowFactor = Math.Max(Math.Min(70, Math.Abs(lastDistanceMoved)) / 70, 0.38);
distanceAddition += direction_change_bonus / Math.Sqrt(lastStrainTime + 16) * bonusFactor * antiflowFactor * Math.Max(1 - Math.Pow(weightedStrainTime / 1000, 3), 0);
}
// Base bonus for every movement, giving some weight to streams.
distanceAddition += 12.5 * Math.Min(Math.Abs(distanceMoved), normalized_hitobject_radius * 2) / (normalized_hitobject_radius * 6) / sqrtStrain;
}
// Bonus for edge dashes.
if (catchCurrent.LastObject.DistanceToHyperDash <= 20.0f)
{
if (!catchCurrent.LastObject.HyperDash)
edgeDashBonus += 5.7;
else
{
// After a hyperdash we ARE in the correct position. Always!
playerPosition = catchCurrent.NormalizedPosition;
}
distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash) / 20)
* Math.Pow((Math.Min(catchCurrent.StrainTime * catcherSpeedMultiplier, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values
}
// There is an edge case where horizontal back and forth sliders create "buzz" patterns which are repeated "movements" with a distance lower than
// the platter's width but high enough to be considered a movement due to the absolute_player_positioning_error and normalized_hitobject_radius offsets
// We are detecting this exact scenario. The first back and forth is counted but all subsequent ones are nullified.
// To achieve that, we need to store the exact distances (distance ignoring absolute_player_positioning_error and normalized_hitobject_radius)
if (Math.Abs(exactDistanceMoved) <= HalfCatcherWidth * 2 && exactDistanceMoved == -lastExactDistanceMoved && catchCurrent.StrainTime == lastStrainTime)
{
if (isInBuzzSection)
distanceAddition = 0;
else
isInBuzzSection = true;
}
else
{
isInBuzzSection = false;
}
lastPlayerPosition = playerPosition;
lastDistanceMoved = distanceMoved;
lastStrainTime = catchCurrent.StrainTime;
lastExactDistanceMoved = exactDistanceMoved;
return distanceAddition / weightedStrainTime;
return MovementEvaluator.EvaluateDifficultyOf(current, catcherSpeedMultiplier);
}
}
}

View File

@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private double placementStartTime;
private double placementEndTime;
protected override bool IsValidForPlacement => Precision.DefinitelyBigger(HitObject.Duration, 0);
protected override bool IsValidForPlacement => base.IsValidForPlacement && (PlacementActive == PlacementState.Waiting || Precision.DefinitelyBigger(HitObject.Duration, 0));
public BananaShowerPlacementBlueprint()
{

View File

@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private InputManager inputManager = null!;
protected override bool IsValidForPlacement => Precision.DefinitelyBigger(HitObject.Duration, 0);
protected override bool IsValidForPlacement => base.IsValidForPlacement && (PlacementActive == PlacementState.Waiting || Precision.DefinitelyBigger(HitObject.Duration, 0));
public JuiceStreamPlacementBlueprint()
{

View File

@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using osu.Framework.Allocation;
@@ -224,7 +225,8 @@ namespace osu.Game.Rulesets.Catch.Edit
#region Clipboard handling
public override string ConvertSelectionToString()
=> string.Join(',', EditorBeatmap.SelectedHitObjects.Cast<CatchHitObject>().OrderBy(h => h.StartTime).Select(h => (h.IndexInCurrentCombo + 1).ToString()));
=> string.Join(',', EditorBeatmap.SelectedHitObjects.Cast<CatchHitObject>().OrderBy(h => h.StartTime)
.Select(h => (h.IndexInCurrentCombo + 1).ToString(CultureInfo.InvariantCulture)));
// 1,2,3,4 ...
private static readonly Regex selection_regex = new Regex(@"^\d+(,\d+)*$", RegexOptions.Compiled);

View File

@@ -51,7 +51,8 @@ namespace osu.Game.Rulesets.Catch.Mods
return string.Empty;
string format(string acronym, DifficultyBindable bindable) => $"{acronym}{bindable.Value!.Value.ToStandardFormattedString(1)}";
string format(string acronym, DifficultyBindable bindable)
=> $"{acronym}{bindable.Value!.Value.ToStandardFormattedString(1)}";
}
}

View File

@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Mods
public override BindableBool ComboBasedSize { get; } = new BindableBool(true);
public override float DefaultFlashlightSize => 325;
public override float DefaultFlashlightSize => 203.125f;
protected override Flashlight CreateFlashlight() => new CatchFlashlight(this, playfield);

View File

@@ -3,6 +3,7 @@
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
@@ -16,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Mods
public override string Acronym => "FF";
public override LocalisableString Description => "The fruits are... floating?";
public override double ScoreMultiplier => 1;
public override IconUsage? Icon => FontAwesome.Solid.Cloud;
public override IconUsage? Icon => OsuIcon.ModFloatingFruits;
public void ApplyToDrawableRuleset(DrawableRuleset<CatchHitObject> drawableRuleset)
{

View File

@@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Mods;
@@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Mods
public override LocalisableString Description => "Dashing by default, slow down!";
public override ModType Type => ModType.Fun;
public override double ScoreMultiplier => 1;
public override IconUsage? Icon => FontAwesome.Solid.Running;
public override IconUsage? Icon => OsuIcon.ModMovingFast;
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax) };
private DrawableCatchRuleset drawableRuleset = null!;

View File

@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;
@@ -53,13 +54,25 @@ namespace osu.Game.Rulesets.Catch.Objects
public override IEnumerable<string> LookupNames => lookup_names;
public BananaHitSampleInfo(int volume = 100)
: base(string.Empty, volume: volume)
public BananaHitSampleInfo()
: this(string.Empty)
{
}
public sealed override HitSampleInfo With(Optional<string> newName = default, Optional<string> newBank = default, Optional<string?> newSuffix = default, Optional<int> newVolume = default, Optional<bool> newEditorAutoBank = default)
=> new BananaHitSampleInfo(newVolume.GetOr(Volume));
public BananaHitSampleInfo(HitSampleInfo info)
: this(info.Name, info.Bank, info.Suffix, info.Volume, info.EditorAutoBank, info.UseBeatmapSamples)
{
}
private BananaHitSampleInfo(string name, string bank = SampleControlPoint.DEFAULT_BANK, string? suffix = null, int volume = 100, bool editorAutoBank = true, bool useBeatmapSamples = false)
: base(name, bank, suffix, volume, editorAutoBank, useBeatmapSamples)
{
}
public sealed override HitSampleInfo With(Optional<string> newName = default, Optional<string> newBank = default, Optional<string?> newSuffix = default, Optional<int> newVolume = default,
Optional<bool> newEditorAutoBank = default, Optional<bool> newUseBeatmapSamples = default)
=> new BananaHitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank), newSuffix.GetOr(Suffix), newVolume.GetOr(Volume),
newEditorAutoBank.GetOr(EditorAutoBank), newUseBeatmapSamples.GetOr(UseBeatmapSamples));
public bool Equals(BananaHitSampleInfo? other)
=> other != null;

View File

@@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
StartTime = time,
BananaIndex = count,
Samples = new List<HitSampleInfo> { new Banana.BananaHitSampleInfo(CreateHitSampleInfo().Volume) }
Samples = new List<HitSampleInfo> { new Banana.BananaHitSampleInfo(CreateHitSampleInfo()) }
});
count++;

View File

@@ -224,7 +224,20 @@ namespace osu.Game.Rulesets.Catch.UI
addLighting(result, drawableObject.AccentColour.Value, positionInStack.X);
}
// droplet doesn't affect the catcher state
if (result.IsHit)
CurrentState = hitObject.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle;
else if (hitObject is not Banana)
CurrentState = CatcherAnimationState.Fail;
if (palpableObject.HitObject.LastInCombo)
{
if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result))
Explode();
else
Drop();
}
// droplet doesn't affect hyperdash state
if (hitObject is TinyDroplet) return;
// if a hyper fruit was already handled this frame, just go where it says to go.
@@ -244,19 +257,6 @@ namespace osu.Game.Rulesets.Catch.UI
else
SetHyperDashState();
}
if (result.IsHit)
CurrentState = hitObject.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle;
else if (!(hitObject is Banana))
CurrentState = CatcherAnimationState.Fail;
if (palpableObject.HitObject.LastInCombo)
{
if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result))
Explode();
else
Drop();
}
}
public void OnRevertResult(JudgementResult result)

View File

@@ -8,7 +8,7 @@
<PropertyGroup Label="Nuget">
<Title>osu!catch (ruleset)</Title>
<PackageId>ppy.osu.Game.Rulesets.Catch</PackageId>
<PackageId>jvnkosu.Client.Rulesets.Catch</PackageId>
<IsPackable>true</IsPackable>
</PropertyGroup>

View File

@@ -5,6 +5,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Testing;
using osu.Game.Rulesets.Edit;
@@ -16,6 +17,7 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Screens.Edit;
using osu.Game.Tests.Visual;
using osuTK.Input;
@@ -36,21 +38,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
[Test]
public void TestPlaceBeforeCurrentTimeDownwards()
{
AddStep("seek to 200", () => HitObjectContainer.Dependencies.Get<EditorClock>().Seek(200));
AddStep("move mouse before current time", () =>
{
var column = this.ChildrenOfType<Column>().Single();
InputManager.MoveMouseTo(column.ScreenSpacePositionAtTime(-100));
});
AddStep("click", () => InputManager.Click(MouseButton.Left));
AddAssert("note start time < 0", () => getNote().StartTime < 0);
}
[Test]
public void TestPlaceAfterCurrentTimeDownwards()
{
AddStep("move mouse after current time", () =>
{
var column = this.ChildrenOfType<Column>().Single();
InputManager.MoveMouseTo(column.ScreenSpacePositionAtTime(100));
@@ -58,7 +47,22 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
AddStep("click", () => InputManager.Click(MouseButton.Left));
AddAssert("note start time > 0", () => getNote().StartTime > 0);
AddAssert("note start time < 200", () => getNote().StartTime < 200);
}
[Test]
public void TestPlaceAfterCurrentTimeDownwards()
{
AddStep("seek to 200", () => HitObjectContainer.Dependencies.Get<EditorClock>().Seek(200));
AddStep("move mouse after current time", () =>
{
var column = this.ChildrenOfType<Column>().Single();
InputManager.MoveMouseTo(column.ScreenSpacePositionAtTime(300));
});
AddStep("click", () => InputManager.Click(MouseButton.Left));
AddAssert("note start time > 200", () => getNote().StartTime > 200);
}
private Note getNote() => this.ChildrenOfType<DrawableNote>().FirstOrDefault()?.HitObject;

View File

@@ -18,15 +18,11 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
public void TestNormalSelection()
{
addStepClickLink("00:05:920 (5920|3,6623|3,6857|2,7326|1)");
AddAssert("selected group", () => checkSnapAndSelectColumn(5_920, new List<(int, int)>
{ (5_920, 3), (6_623, 3), (6_857, 2), (7_326, 1) }
));
AddAssert("selected group", () => checkSnapAndSelectColumn(5_920, [(5_920, 3), (6_623, 3), (6_857, 2), (7_326, 1)]));
addReset();
addStepClickLink("00:42:716 (42716|3,43420|2,44123|0,44357|1,45295|1)");
AddAssert("selected ungrouped", () => checkSnapAndSelectColumn(42_716, new List<(int, int)>
{ (42_716, 3), (43_420, 2), (44_123, 0), (44_357, 1), (45_295, 1) }
));
AddAssert("selected ungrouped", () => checkSnapAndSelectColumn(42_716, [(42_716, 3), (43_420, 2), (44_123, 0), (44_357, 1), (45_295, 1)]));
addReset();
AddStep("add notes to row", () =>
@@ -41,15 +37,20 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
EditorBeatmap.AddRange(new[] { second, third, forth });
});
addStepClickLink("00:11:545 (11545|0,11545|1,11545|2,11545|3)");
AddAssert("selected in row", () => checkSnapAndSelectColumn(11_545, new List<(int, int)>
{ (11_545, 0), (11_545, 1), (11_545, 2), (11_545, 3) }
));
AddAssert("selected in row", () => checkSnapAndSelectColumn(11_545, [(11_545, 0), (11_545, 1), (11_545, 2), (11_545, 3)]));
addReset();
addStepClickLink("01:36:623 (96623|1,97560|1,97677|1,97795|1,98966|1)");
AddAssert("selected in column", () => checkSnapAndSelectColumn(96_623, new List<(int, int)>
{ (96_623, 1), (97_560, 1), (97_677, 1), (97_795, 1), (98_966, 1) }
));
AddAssert("selected in column", () => checkSnapAndSelectColumn(96_623, [(96_623, 1), (97_560, 1), (97_677, 1), (97_795, 1), (98_966, 1)]));
}
[Test]
public void TestRoundingToNearestMillisecondApplied()
{
AddStep("resnap note to have fractional coordinates",
() => EditorBeatmap.HitObjects.OfType<ManiaHitObject>().Single(ho => ho.StartTime == 85_373 && ho.Column == 1).StartTime = 85_373.125);
addStepClickLink("01:25:373 (85373|1)");
AddAssert("selected note", () => checkSnapAndSelectColumn(85_373.125, [(85_373.125, 1)]));
}
[Test]
@@ -75,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
private void addReset() => addStepClickLink("00:00:000", "reset", false);
private bool checkSnapAndSelectColumn(double startTime, IReadOnlyCollection<(int, int)>? columnPairs = null)
private bool checkSnapAndSelectColumn(double startTime, IReadOnlyCollection<(double, int)>? columnPairs = null)
{
bool checkColumns = columnPairs != null
? EditorBeatmap.SelectedHitObjects.All(x => columnPairs.Any(col => isNoteAt(x, col.Item1, col.Item2)))

View File

@@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Mania.Tests
[TestCase("mania-samples")]
[TestCase("mania-slider")] // e.g. second and fourth notes of https://osu.ppy.sh/beatmapsets/73883#mania/216407
[TestCase("slider-convert-samples")]
[TestCase("spinner-convert-samples")]
public void Test(string name) => base.Test(name);
protected override IEnumerable<SampleConvertValue> CreateConvertValue(HitObject hitObject)

View File

@@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Tests
}
[TestCase]
public void TestFilterIntersection()
public void TestKeysFilterIntersection()
{
var criteria = new ManiaFilterCriteria();
criteria.TryParseCustomKeywordCriteria("keys", Operator.Greater, "4");
@@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Mania.Tests
}
[TestCase]
public void TestInvalidFilters()
public void TestInvalidKeysFilters()
{
var criteria = new ManiaFilterCriteria();
@@ -183,5 +183,132 @@ namespace osu.Game.Rulesets.Mania.Tests
Assert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.NotEqual, "4,some text"));
Assert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.GreaterOrEqual, "4,5,6"));
}
[TestCase]
public void TestLnsEqual()
{
var criteria = new ManiaFilterCriteria();
var filterCriteria = new FilterCriteria
{
Ruleset = new ManiaRuleset().RulesetInfo
};
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "0");
BeatmapInfo beatmapInfo1 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 0,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo1, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "0");
BeatmapInfo beatmapInfo2 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 100,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo2, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "100");
BeatmapInfo beatmapInfo3 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 100,
EndTimeObjectCount = 100
};
Assert.True(criteria.Matches(beatmapInfo3, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "1");
BeatmapInfo beatmapInfo4 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 100,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo4, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "0.1");
BeatmapInfo beatmapInfo5 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 1000,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo5, filterCriteria));
}
[TestCase]
public void TestLnsGreaterOrEqual()
{
var criteria = new ManiaFilterCriteria();
var filterCriteria = new FilterCriteria
{
Ruleset = new ManiaRuleset().RulesetInfo
};
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "0");
BeatmapInfo beatmapInfo1 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 0,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo1, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "0");
BeatmapInfo beatmapInfo2 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 100,
EndTimeObjectCount = 0
};
Assert.True(criteria.Matches(beatmapInfo2, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "100");
BeatmapInfo beatmapInfo3 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 100,
EndTimeObjectCount = 100
};
Assert.True(criteria.Matches(beatmapInfo3, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "1");
BeatmapInfo beatmapInfo4 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 100,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo4, filterCriteria));
criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "0.1");
BeatmapInfo beatmapInfo5 = new BeatmapInfo(new ManiaRuleset().RulesetInfo)
{
TotalObjectCount = 1000,
EndTimeObjectCount = 1
};
Assert.True(criteria.Matches(beatmapInfo5, filterCriteria));
}
[TestCase]
public void TestLnsNotManiaRuleset()
{
var criteria = new ManiaFilterCriteria();
var filterCriteria = new FilterCriteria
{
Ruleset = new ManiaRuleset().RulesetInfo
};
criteria.TryParseCustomKeywordCriteria("lns", Operator.LessOrEqual, "100");
BeatmapInfo beatmapInfo = new BeatmapInfo
{
TotalObjectCount = 100,
EndTimeObjectCount = 50
};
Assert.False(criteria.Matches(beatmapInfo, filterCriteria));
}
[TestCase]
public void TestInvalidLnsFilters()
{
var criteria = new ManiaFilterCriteria();
Assert.False(criteria.TryParseCustomKeywordCriteria("lns", Operator.Equal, "some text"));
Assert.False(criteria.TryParseCustomKeywordCriteria("lns", Operator.GreaterOrEqual, "1some text"));
}
}
}

View File

@@ -0,0 +1,10 @@
osu file format v14
[General]
Mode: 0
[TimingPoints]
0,300,4,0,2,100,1,0
[HitObjects]
444,320,1000,5,2,0:0:0:0:

View File

@@ -0,0 +1,16 @@
{
"Mappings": [{
"StartTime": 1000.0,
"Objects": [{
"StartTime": 1000.0,
"EndTime": 8000.0,
"Column": 0,
"PlaySlidingSamples": false,
"NodeSamples": [
["Gameplay/soft-hitnormal"],
["Gameplay/soft-hitnormal", "Gameplay/soft-hitfinish"]
],
"Samples": ["Gameplay/soft-hitnormal", "Gameplay/soft-hitfinish"],
}]
}]
}

View File

@@ -0,0 +1,18 @@
osu file format v14
[General]
Mode: 0
[Difficulty]
HPDrainRate:5
CircleSize:5
OverallDifficulty:5
ApproachRate:5
SliderMultiplier:1.4
SliderTickRate:1
[TimingPoints]
0,500,4,2,0,100,1,0
[HitObjects]
256,192,1000,8,4,8000,0:2:0:0:

View File

@@ -45,5 +45,19 @@ namespace osu.Game.Rulesets.Mania.Tests
AssertBeatmapLookup(expected_sample);
AssertNoLookup(unwanted_sample);
}
[Test]
public void TestConvertHitObjectCustomSampleBank()
{
const string beatmap_sample = "normal-hitwhistle2";
const string user_skin_sample = "normal-hitnormal";
SetupSkins(beatmap_sample, user_skin_sample);
CreateTestWithBeatmap("convert-beatmap-custom-sample-bank.osu");
AssertBeatmapLookup(beatmap_sample);
AssertUserLookup(user_skin_sample);
}
}
}

View File

@@ -85,7 +85,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
Duration = endTime - HitObject.StartTime,
Column = column,
Samples = HitObject.Samples,
NodeSamples = (HitObject as IHasRepeats)?.NodeSamples
NodeSamples =
[
HitObject.Samples.Where(s => s.Name == HitSampleInfo.HIT_NORMAL).ToList(),
HitObject.Samples
]
};
}
else

View File

@@ -0,0 +1,37 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Utils;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
namespace osu.Game.Rulesets.Mania.Difficulty.Evaluators
{
public class IndividualStrainEvaluator
{
public static double EvaluateDifficultyOf(DifficultyHitObject current)
{
var maniaCurrent = (ManiaDifficultyHitObject)current;
double startTime = maniaCurrent.StartTime;
double endTime = maniaCurrent.EndTime;
double holdFactor = 1.0; // Factor to all additional strains in case something else is held
// We award a bonus if this note starts and ends before the end of another hold note.
foreach (var maniaPrevious in maniaCurrent.PreviousHitObjects)
{
if (maniaPrevious is null)
continue;
if (Precision.DefinitelyBigger(maniaPrevious.EndTime, endTime, 1) &&
Precision.DefinitelyBigger(startTime, maniaPrevious.StartTime, 1))
{
holdFactor = 1.25;
break;
}
}
return 2.0 * holdFactor;
}
}
}

View File

@@ -0,0 +1,61 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Utils;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Utils;
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
namespace osu.Game.Rulesets.Mania.Difficulty.Evaluators
{
public class OverallStrainEvaluator
{
private const double release_threshold = 30;
public static double EvaluateDifficultyOf(DifficultyHitObject current)
{
var maniaCurrent = (ManiaDifficultyHitObject)current;
double startTime = maniaCurrent.StartTime;
double endTime = maniaCurrent.EndTime;
bool isOverlapping = false;
double closestEndTime = Math.Abs(endTime - startTime); // Lowest value we can assume with the current information
double holdFactor = 1.0; // Factor to all additional strains in case something else is held
double holdAddition = 0; // Addition to the current note in case it's a hold and has to be released awkwardly
foreach (var maniaPrevious in maniaCurrent.PreviousHitObjects)
{
if (maniaPrevious is null)
continue;
// The current note is overlapped if a previous note or end is overlapping the current note body
isOverlapping |= Precision.DefinitelyBigger(maniaPrevious.EndTime, startTime, 1) &&
Precision.DefinitelyBigger(endTime, maniaPrevious.EndTime, 1) &&
Precision.DefinitelyBigger(startTime, maniaPrevious.StartTime, 1);
// We give a slight bonus to everything if something is held meanwhile
if (Precision.DefinitelyBigger(maniaPrevious.EndTime, endTime, 1) &&
Precision.DefinitelyBigger(startTime, maniaPrevious.StartTime, 1))
holdFactor = 1.25;
closestEndTime = Math.Min(closestEndTime, Math.Abs(endTime - maniaPrevious.EndTime));
}
// The hold addition is given if there was an overlap, however it is only valid if there are no other note with a similar ending.
// Releasing multiple notes is just as easy as releasing 1. Nerfs the hold addition by half if the closest release is release_threshold away.
// holdAddition
// ^
// 1.0 + - - - - - -+-----------
// | /
// 0.5 + - - - - -/ Sigmoid Curve
// | /|
// 0.0 +--------+-+---------------> Release Difference / ms
// release_threshold
if (isOverlapping)
holdAddition = DifficultyCalculationUtils.Logistic(x: closestEndTime, multiplier: 0.27, midpointOffset: release_threshold);
return (1 + holdAddition) * holdFactor;
}
}
}

View File

@@ -65,13 +65,22 @@ namespace osu.Game.Rulesets.Mania.Difficulty
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
{
var sortedObjects = beatmap.HitObjects.ToArray();
int totalColumns = ((ManiaBeatmap)beatmap).TotalColumns;
LegacySortHelper<HitObject>.Sort(sortedObjects, Comparer<HitObject>.Create((a, b) => (int)Math.Round(a.StartTime) - (int)Math.Round(b.StartTime)));
List<DifficultyHitObject> objects = new List<DifficultyHitObject>();
List<DifficultyHitObject>[] perColumnObjects = new List<DifficultyHitObject>[totalColumns];
for (int column = 0; column < totalColumns; column++)
perColumnObjects[column] = new List<DifficultyHitObject>();
for (int i = 1; i < sortedObjects.Length; i++)
objects.Add(new ManiaDifficultyHitObject(sortedObjects[i], sortedObjects[i - 1], clockRate, objects, objects.Count));
{
var currentObject = new ManiaDifficultyHitObject(sortedObjects[i], sortedObjects[i - 1], clockRate, objects, perColumnObjects, objects.Count);
objects.Add(currentObject);
perColumnObjects[currentObject.Column].Add(currentObject);
}
return objects;
}

View File

@@ -12,9 +12,59 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Preprocessing
{
public new ManiaHitObject BaseObject => (ManiaHitObject)base.BaseObject;
public ManiaDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, List<DifficultyHitObject> objects, int index)
private readonly List<DifficultyHitObject>[] perColumnObjects;
private readonly int columnIndex;
public readonly int Column;
// The hit object earlier in time than this note in each column
public readonly ManiaDifficultyHitObject?[] PreviousHitObjects;
public readonly double ColumnStrainTime;
public ManiaDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, List<DifficultyHitObject> objects, List<DifficultyHitObject>[] perColumnObjects, int index)
: base(hitObject, lastObject, clockRate, objects, index)
{
int totalColumns = perColumnObjects.Length;
this.perColumnObjects = perColumnObjects;
Column = BaseObject.Column;
columnIndex = perColumnObjects[Column].Count;
PreviousHitObjects = new ManiaDifficultyHitObject[totalColumns];
ColumnStrainTime = StartTime - PrevInColumn(0)?.StartTime ?? StartTime;
if (index > 0)
{
ManiaDifficultyHitObject prevNote = (ManiaDifficultyHitObject)objects[index - 1];
for (int i = 0; i < prevNote.PreviousHitObjects.Length; i++)
PreviousHitObjects[i] = prevNote.PreviousHitObjects[i];
// intentionally depends on processing order to match live.
PreviousHitObjects[prevNote.Column] = prevNote;
}
}
/// <summary>
/// The previous object in the same column as this <see cref="ManiaDifficultyHitObject"/>, exclusive of Long Note tails.
/// </summary>
/// <param name="backwardsIndex">The number of notes to go back.</param>
/// <returns>The object in this column <paramref name="backwardsIndex"/> notes back, or null if this is the first note in the column.</returns>
public ManiaDifficultyHitObject? PrevInColumn(int backwardsIndex)
{
int index = columnIndex - (backwardsIndex + 1);
return index >= 0 && index < perColumnObjects[Column].Count ? (ManiaDifficultyHitObject)perColumnObjects[Column][index] : null;
}
/// <summary>
/// The next object in the same column as this <see cref="ManiaDifficultyHitObject"/>, exclusive of Long Note tails.
/// </summary>
/// <param name="forwardsIndex">The number of notes to go forward.</param>
/// <returns>The object in this column <paramref name="forwardsIndex"/> notes forward, or null if this is the last note in the column.</returns>
public ManiaDifficultyHitObject? NextInColumn(int forwardsIndex)
{
int index = columnIndex + (forwardsIndex + 1);
return index >= 0 && index < perColumnObjects[Column].Count ? (ManiaDifficultyHitObject)perColumnObjects[Column][index] : null;
}
}
}

View File

@@ -2,10 +2,9 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Utils;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Difficulty.Utils;
using osu.Game.Rulesets.Mania.Difficulty.Evaluators;
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mods;
@@ -15,23 +14,17 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Skills
{
private const double individual_decay_base = 0.125;
private const double overall_decay_base = 0.30;
private const double release_threshold = 30;
protected override double SkillMultiplier => 1;
protected override double StrainDecayBase => 1;
private readonly double[] startTimes;
private readonly double[] endTimes;
private readonly double[] individualStrains;
private double individualStrain;
private double highestIndividualStrain;
private double overallStrain;
public Strain(Mod[] mods, int totalColumns)
: base(mods)
{
startTimes = new double[totalColumns];
endTimes = new double[totalColumns];
individualStrains = new double[totalColumns];
overallStrain = 1;
}
@@ -39,64 +32,23 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Skills
protected override double StrainValueOf(DifficultyHitObject current)
{
var maniaCurrent = (ManiaDifficultyHitObject)current;
double startTime = maniaCurrent.StartTime;
double endTime = maniaCurrent.EndTime;
int column = maniaCurrent.BaseObject.Column;
bool isOverlapping = false;
double closestEndTime = Math.Abs(endTime - startTime); // Lowest value we can assume with the current information
double holdFactor = 1.0; // Factor to all additional strains in case something else is held
double holdAddition = 0; // Addition to the current note in case it's a hold and has to be released awkwardly
individualStrains[maniaCurrent.Column] = applyDecay(individualStrains[maniaCurrent.Column], maniaCurrent.ColumnStrainTime, individual_decay_base);
individualStrains[maniaCurrent.Column] += IndividualStrainEvaluator.EvaluateDifficultyOf(current);
for (int i = 0; i < endTimes.Length; ++i)
{
// The current note is overlapped if a previous note or end is overlapping the current note body
isOverlapping |= Precision.DefinitelyBigger(endTimes[i], startTime, 1) &&
Precision.DefinitelyBigger(endTime, endTimes[i], 1) &&
Precision.DefinitelyBigger(startTime, startTimes[i], 1);
// Take the hardest individualStrain for notes that happen at the same time (in a chord).
// This is to ensure the order in which the notes are processed does not affect the resultant total strain.
highestIndividualStrain = maniaCurrent.DeltaTime <= 1 ? Math.Max(highestIndividualStrain, individualStrains[maniaCurrent.Column]) : individualStrains[maniaCurrent.Column];
// We give a slight bonus to everything if something is held meanwhile
if (Precision.DefinitelyBigger(endTimes[i], endTime, 1) &&
Precision.DefinitelyBigger(startTime, startTimes[i], 1))
holdFactor = 1.25;
closestEndTime = Math.Min(closestEndTime, Math.Abs(endTime - endTimes[i]));
}
// The hold addition is given if there was an overlap, however it is only valid if there are no other note with a similar ending.
// Releasing multiple notes is just as easy as releasing 1. Nerfs the hold addition by half if the closest release is release_threshold away.
// holdAddition
// ^
// 1.0 + - - - - - -+-----------
// | /
// 0.5 + - - - - -/ Sigmoid Curve
// | /|
// 0.0 +--------+-+---------------> Release Difference / ms
// release_threshold
if (isOverlapping)
holdAddition = DifficultyCalculationUtils.Logistic(x: closestEndTime, multiplier: 0.27, midpointOffset: release_threshold);
// Decay and increase individualStrains in own column
individualStrains[column] = applyDecay(individualStrains[column], startTime - startTimes[column], individual_decay_base);
individualStrains[column] += 2.0 * holdFactor;
// For notes at the same time (in a chord), the individualStrain should be the hardest individualStrain out of those columns
individualStrain = maniaCurrent.DeltaTime <= 1 ? Math.Max(individualStrain, individualStrains[column]) : individualStrains[column];
// Decay and increase overallStrain
overallStrain = applyDecay(overallStrain, current.DeltaTime, overall_decay_base);
overallStrain += (1 + holdAddition) * holdFactor;
// Update startTimes and endTimes arrays
startTimes[column] = startTime;
endTimes[column] = endTime;
overallStrain = applyDecay(overallStrain, maniaCurrent.DeltaTime, overall_decay_base);
overallStrain += OverallStrainEvaluator.EvaluateDifficultyOf(current);
// By subtracting CurrentStrain, this skill effectively only considers the maximum strain of any one hitobject within each strain section.
return individualStrain + overallStrain - CurrentStrain;
return highestIndividualStrain + overallStrain - CurrentStrain;
}
protected override double CalculateInitialStrain(double offset, DifficultyHitObject current)
=> applyDecay(individualStrain, offset - current.Previous(0).StartTime, individual_decay_base)
protected override double CalculateInitialStrain(double offset, DifficultyHitObject current) =>
applyDecay(highestIndividualStrain, offset - current.Previous(0).StartTime, individual_decay_base)
+ applyDecay(overallStrain, offset - current.Previous(0).StartTime, overall_decay_base);
private double applyDecay(double value, double deltaTime, double decayBase)

View File

@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
[Resolved]
private IScrollingInfo scrollingInfo { get; set; } = null!;
protected override bool IsValidForPlacement => Precision.DefinitelyBigger(HitObject.Duration, 0);
protected override bool IsValidForPlacement => base.IsValidForPlacement && (PlacementActive == PlacementState.Waiting || Precision.DefinitelyBigger(HitObject.Duration, 0));
public HoldNotePlacementBlueprint()
: base(new HoldNote())

View File

@@ -1,10 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using osu.Framework.Allocation;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
@@ -54,7 +56,8 @@ namespace osu.Game.Rulesets.Mania.Edit
};
public override string ConvertSelectionToString()
=> string.Join(',', EditorBeatmap.SelectedHitObjects.Cast<ManiaHitObject>().OrderBy(h => h.StartTime).Select(h => $"{h.StartTime}|{h.Column}"));
=> string.Join(',', EditorBeatmap.SelectedHitObjects.Cast<ManiaHitObject>().OrderBy(h => h.StartTime)
.Select(h => FormattableString.Invariant($"{Math.Round(h.StartTime)}|{h.Column}")));
// 123|0,456|1,789|2 ...
private static readonly Regex selection_regex = new Regex(@"^\d+\|\d+(,\d+\|\d+)*$", RegexOptions.Compiled);
@@ -73,10 +76,10 @@ namespace osu.Game.Rulesets.Mania.Edit
if (split.Length != 2)
continue;
if (!double.TryParse(split[0], out double time) || !int.TryParse(split[1], out int column))
if (!int.TryParse(split[0], out int time) || !int.TryParse(split[1], out int column))
continue;
ManiaHitObject? current = remainingHitObjects.FirstOrDefault(h => h.StartTime == time && h.Column == column);
ManiaHitObject? current = remainingHitObjects.FirstOrDefault(h => Precision.AlmostEquals(h.StartTime, time, 0.5) && h.Column == column);
if (current == null)
continue;

View File

@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Bindables;
@@ -19,12 +20,16 @@ namespace osu.Game.Rulesets.Mania
public class ManiaFilterCriteria : IRulesetFilterCriteria
{
private readonly HashSet<int> includedKeyCounts = Enumerable.Range(1, LegacyBeatmapDecoder.MAX_MANIA_KEY_COUNT).ToHashSet();
private FilterCriteria.OptionalRange<float> longNotePercentage;
public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria)
{
int keyCount = ManiaBeatmapConverter.GetColumnCount(LegacyBeatmapConversionDifficultyInfo.FromBeatmapInfo(beatmapInfo), criteria.Mods);
return includedKeyCounts.Contains(keyCount);
bool keyCountMatch = includedKeyCounts.Contains(keyCount);
bool longNotePercentageMatch = !longNotePercentage.HasFilter || (!isConvertedBeatmap(beatmapInfo) && longNotePercentage.IsInRange(calculateLongNotePercentage(beatmapInfo)));
return keyCountMatch && longNotePercentageMatch;
}
public bool TryParseCustomKeywordCriteria(string key, Operator op, string strValues)
@@ -84,6 +89,10 @@ namespace osu.Game.Rulesets.Mania
return false;
}
}
case "ln":
case "lns":
return FilterQueryParser.TryUpdateCriteriaRange(ref longNotePercentage, op, strValues);
}
return false;
@@ -103,5 +112,18 @@ namespace osu.Game.Rulesets.Mania
return false;
}
private static bool isConvertedBeatmap(BeatmapInfo beatmapInfo)
{
return !beatmapInfo.Ruleset.Equals(new ManiaRuleset().RulesetInfo);
}
private static float calculateLongNotePercentage(BeatmapInfo beatmapInfo)
{
int holdNotes = beatmapInfo.EndTimeObjectCount;
int totalNotes = Math.Max(1, beatmapInfo.TotalObjectCount);
return holdNotes / (float)totalNotes * 100;
}
}
}

View File

@@ -79,6 +79,7 @@ namespace osu.Game.Rulesets.Mania
return new ManiaArgonSkinTransformer(skin, beatmap);
case DefaultLegacySkin:
case RetroSkin:
return new ManiaClassicSkinTransformer(skin, beatmap);
case LegacySkin:

View File

@@ -14,8 +14,8 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Acronym => Name;
public abstract int KeyCount { get; }
public override ModType Type => ModType.Conversion;
public override double ScoreMultiplier => 0.9;
public override bool Ranked => UsesDefaultConfiguration;
public override double ScoreMultiplier => 1;
public override bool Ranked => true;
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
{

View File

@@ -4,6 +4,7 @@
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
@@ -21,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override LocalisableString Description => "No more tricky speed changes!";
public override IconUsage? Icon => FontAwesome.Solid.Equals;
public override IconUsage? Icon => OsuIcon.ModConstantSpeed;
public override ModType Type => ModType.Conversion;

View File

@@ -4,8 +4,10 @@
using System;
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.UI;
namespace osu.Game.Rulesets.Mania.Mods
@@ -14,6 +16,7 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public override string Name => "Cover";
public override string Acronym => "CO";
public override IconUsage? Icon => OsuIcon.ModCover;
public override LocalisableString Description => @"Decrease the playfield's viewing area.";
@@ -27,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Mods
typeof(ManiaModFadeIn)
}).ToArray();
public override bool Ranked => false;
public override bool Ranked => true;
public override bool ValidForFreestyleAsRequiredMod => false;

View File

@@ -7,5 +7,20 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModDifficultyAdjust : ModDifficultyAdjust
{
public override DifficultyBindable OverallDifficulty { get; } = new DifficultyBindable
{
Precision = 0.1f,
MinValue = 0,
MaxValue = 10,
// Use larger extended limits for mania to include OD values that occur with EZ or HR enabled
#if !DEBUG
ExtendedMaxValue = 15,
ExtendedMinValue = -15,
#else
ExtendedMinValue = -250,
ExtendedMaxValue = 50,
#endif
ReadCurrentFromDifficulty = diff => diff.OverallDifficulty,
};
}
}

View File

@@ -1,8 +1,10 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mods;
@@ -13,6 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Name => "Dual Stages";
public override string Acronym => "DS";
public override LocalisableString Description => @"Double the stages, double the fun!";
public override IconUsage? Icon => OsuIcon.ModDualStages;
public override ModType Type => ModType.Conversion;
public override double ScoreMultiplier => 1;

View File

@@ -3,7 +3,9 @@
using System;
using System.Linq;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.UI;
namespace osu.Game.Rulesets.Mania.Mods
@@ -12,6 +14,7 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public override string Name => "Fade In";
public override string Acronym => "FI";
public override IconUsage? Icon => OsuIcon.ModFadeIn;
public override LocalisableString Description => @"Keys appear out of nowhere!";
public override double ScoreMultiplier => 1;
public override bool ValidForFreestyleAsRequiredMod => false;

View File

@@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModHardRock : ModHardRock, IApplicableToHitObject
{
public override double ScoreMultiplier => 1;
public override bool Ranked => false;
public override bool Ranked => true;
public const double HIT_WINDOW_DIFFICULTY_MULTIPLIER = 1.4;

View File

@@ -9,6 +9,8 @@ using osu.Game.Rulesets.Mods;
using osu.Framework.Graphics.Sprites;
using System.Collections.Generic;
using osu.Framework.Localisation;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Beatmaps;
namespace osu.Game.Rulesets.Mania.Mods
@@ -23,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override LocalisableString Description => @"Replaces all hold notes with normal notes.";
public override IconUsage? Icon => FontAwesome.Solid.DotCircle;
public override IconUsage? Icon => OsuIcon.ModHoldOff;
public override ModType Type => ModType.Conversion;
@@ -33,6 +35,8 @@ namespace osu.Game.Rulesets.Mania.Mods
{
var maniaBeatmap = (ManiaBeatmap)beatmap;
double mostCommonBeatLengthBefore = beatmap.GetMostCommonBeatLength();
var newObjects = new List<ManiaHitObject>();
foreach (var h in beatmap.HitObjects.OfType<HoldNote>())
@@ -47,6 +51,17 @@ namespace osu.Game.Rulesets.Mania.Mods
}
maniaBeatmap.HitObjects = maniaBeatmap.HitObjects.OfType<Note>().Concat(newObjects).OrderBy(h => h.StartTime).ToList();
double mostCommonBeatLengthAfter = beatmap.GetMostCommonBeatLength();
// the process of removing hold notes can result in shortening the beatmap's play time,
// and therefore, as a side effect, changing the most common BPM, which will change scroll speed.
// to compensate for this, apply a multiplier to effect points in order to maintain the beatmap's original intended scroll speed.
if (!Precision.AlmostEquals(mostCommonBeatLengthBefore, mostCommonBeatLengthAfter))
{
foreach (var effectPoint in beatmap.ControlPointInfo.EffectPoints)
effectPoint.ScrollSpeed *= mostCommonBeatLengthBefore / mostCommonBeatLengthAfter;
}
}
}
}

View File

@@ -8,6 +8,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
@@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override LocalisableString Description => "Hold the keys. To the beat.";
public override IconUsage? Icon => FontAwesome.Solid.YinYang;
public override IconUsage? Icon => OsuIcon.ModInvert;
public override ModType Type => ModType.Conversion;

View File

@@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Mania.Mods
{
@@ -10,7 +12,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override int KeyCount => 1;
public override string Name => "One Key";
public override string Acronym => "1K";
public override IconUsage? Icon => OsuIcon.ModOneKey;
public override LocalisableString Description => @"Play with one key.";
public override bool Ranked => false;
}
}

View File

@@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Mania.Mods
{
@@ -10,7 +12,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override int KeyCount => 10;
public override string Name => "Ten Keys";
public override string Acronym => "10K";
public override IconUsage? Icon => OsuIcon.ModTenKeys;
public override LocalisableString Description => @"Play with ten keys.";
public override bool Ranked => false;
}
}

View File

@@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Mania.Mods
{
@@ -10,7 +12,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override int KeyCount => 2;
public override string Name => "Two Keys";
public override string Acronym => "2K";
public override IconUsage? Icon => OsuIcon.ModTwoKeys;
public override LocalisableString Description => @"Play with two keys.";
public override bool Ranked => false;
}
}

View File

@@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Mania.Mods
{
@@ -10,7 +12,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override int KeyCount => 3;
public override string Name => "Three Keys";
public override string Acronym => "3K";
public override IconUsage? Icon => OsuIcon.ModThreeKeys;
public override LocalisableString Description => @"Play with three keys.";
public override bool Ranked => false;
}
}

View File

@@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Mania.Mods
{
@@ -10,6 +12,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override int KeyCount => 4;
public override string Name => "Four Keys";
public override string Acronym => "4K";
public override IconUsage? Icon => OsuIcon.ModFourKeys;
public override LocalisableString Description => @"Play with four keys.";
}
}

Some files were not shown because too many files have changed in this diff Show More