1769 Commits

Author SHA1 Message Date
7d38e6c8eb bump to upstream 2026.307.0-tachyon, some fixups 2026-03-08 09:28:33 +03:00
Dean Herbert
c4402e9ce5 Fix potential crash due to handling scores in leaderboard post-disposal (#36860)
Closes https://github.com/ppy/osu/issues/36858. Classic.
2026-03-07 04:40:25 +09:00
Dean Herbert
de9cf751d2 Fix LoadingLayer centering
oops.
2026-03-07 02:51:50 +09:00
Dan Balasescu
0988552567 Implement ranked play (#36819)
I don't really have much to say here. Instead, I'll give a brief history
rundown that lists many pages of documentation you can read, if
interested.

- Started off as BTMC + Happy24 (Vivi)'s ["The
Vision"](https://docs.google.com/document/d/1p1IpPmd2RICp8G4OqkCSs7u8Ug8FbFv8qqP0mfSrHf0/edit?tab=t.0#heading=h.fol093d9f9xi)
- Initial
[designs](https://www.figma.com/design/f5qqC57t9jFlgpzhRqUNVX/The-Vision?node-id=0-1&p=f)
were led by Vivi.
- Designs
[morphed](https://www.figma.com/design/vtFmLrXKvWNyYiRjTezFTM/Untitled--Copy-?node-id=0-1&p=f)
during development into what's currently present, led by @minetoblend.
- There is some more ongoing work creating a [game design
document](https://docs.google.com/document/d/1iffJFCsIBfYF0D4ogItSBEj6YBmbp-rdCpItAeaJiTA/edit?tab=t.0).

**tl;dr:** Create something with the mechanics of a trading card game
within osu!. The name of this is "ranked play".

---

To be frank, a lot of stuff is missing here. Some of it I don't want to
mention, because the point of this exercise is to get the system into
the hands of players, gather feedback especially around mechanics, and
discuss any further direction with the team.

I am expecting a blanket approval on all of the new code, with
particular attention to changes in existing components that I'll point
out in a self review.

There is also some [ongoing
work](https://github.com/smoogipoo/osu/pulls) that may arrive in this
branch prior to being merged.

---------

Co-authored-by: maarvin <minetoblend@gmail.com>
Co-authored-by: Marvin <m.schuerz@hautzy.com>
Co-authored-by: Jamie Taylor <me@nekodex.net>
Co-authored-by: ArijanJ <arijanj@proton.me>
Co-authored-by: Dean Herbert <pe@ppy.sh>
Co-authored-by: Tim Oliver <git@tim.dev>
Co-authored-by: Joseph Madamba <madamba.joehu@outlook.com>
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
Co-authored-by: nil <25884226+voidstar0@users.noreply.github.com>
Co-authored-by: Ботников Максим <mr.botnikoff@ya.ru>
Co-authored-by: Denis Titovets <den232titovets@yandex.ru>
Co-authored-by: Michael Middlezong <119022671+mmiddlezong@users.noreply.github.com>
Co-authored-by: SupDos <6813986+SupDos@users.noreply.github.com>
Co-authored-by: failaip12 <86018517+failaip12@users.noreply.github.com>
2026-03-07 02:30:50 +09:00
复予
0fd0bd3580 Consider comments in wiki's front matter YAML (#36758)
This PR makes front matter items with comments able to be parsed
correctly by the client, for example:

```markdown
---
tags:
  - keyboard
  - tap
  - hybrid
  - play style
needs_cleanup: true  # https://github.com/ppy/osu-wiki/issues/9919
---

# Hybrid

...
```

The front matter YAML used by osu!wiki not complicated, so simply
splitting with `#` is possible.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-03-07 01:41:59 +09:00
Bartłomiej Dach
16bc1de9fd Allow changing addition bank button state when objects are selected even if the selection has no addition sounds (#36808)
Before:


https://github.com/user-attachments/assets/d87bd7e3-37f8-4634-9e6a-5859d5bade57

After:


https://github.com/user-attachments/assets/4de940af-1e30-4266-9aac-5ccd12f38742

---

The title is convoluted but basically I'm angling to close
https://github.com/ppy/osu/issues/36705 with this.

The point is that on current `master`, the keyboard-hotkey-based toggles
on the left of the screen get disabled if you select a range of objects
which contains no addition samples. The report linked above finds this
annoying because it means you basically always need to add an addition
sound *first* and *then* pick a bank.

This is not necessary, and this commit changes the behaviour such that
the bank selection toggles are no longer blocked when you select a range
of objects without additions. Choosing an addition bank when there are
no additions still does nothing to the selected object, *but* adding a
sound *after* that bank preselection will use the preselected bank
rather than auto.
2026-03-07 00:47:35 +09:00
Bartłomiej Dach
0d74983551 Fix rotation of certain objects breaking change states (#36852)
Closes https://github.com/ppy/osu/issues/36830.

This is a regression from https://github.com/ppy/osu/pull/36681.

Due to the aforementioned pull request's changes, rotating an object
that could not scale on the X or Y axis (due to having that dimension
zero) would trigger `CanScale{X,Y}` to change as said rotated object's
width or height became not zero. This in turn would cause `SelectionBox`
to *fully recreate* all of its handles and buttons, *including* the
rotation handle that initiated the rotation operation, therefore
dropping the ongoing rotation operation completely and leaving the
editor in a half-broken state.

The suggested solution here is to recreate handles more granularly to
prevent this from happening. (I've probably not improved it as much as I
could have, but this is as far as I'm willing to go for now unless
review finds it unpalatable.)
2026-03-07 00:20:10 +09:00
Dean Herbert
b46656e7d3 Fix loading spinner not being centered correctly (#36849)
One of those things you can't un-see.

Closes https://github.com/ppy/osu/issues/36832.
2026-03-06 12:11:16 +01:00
Dean Herbert
482d31d598 Fix "no tablet" settings display not updating after language change (#36848)
Closes https://github.com/ppy/osu/issues/36833.

Schedule is unfortunate but I'm not really wanting to go down a rabbit
hole right now.
2026-03-06 12:11:04 +01:00
Bartłomiej Dach
f9e863af01 Remove "copy labels from linked issues" github workflow (#36854)
[It still doesn't
work.](https://github.com/ppy/osu/actions/runs/22759488243/job/66012293202)

Looking at the [job
output](https://github.com/ppy/osu/actions/runs/22759488243/job/66012293202#step:1:21)
it appears that the permissions of the `GITHUB_TOKEN` are
*automatically* constrained to `read` even if you request more scopes.
Would be nice if that was *actually documented* somewhere!

Also given supply-chain attacks that people are running on github [via
*issue titles* these
days](https://grith.ai/blog/clinejection-when-your-ai-tool-installs-another)
I'm not sure we want any automation near where it can reach code. Sure,
much of the fault in the aforementioned attack was the fault of meatbags
trusting clankers *WAY* too much, which is a mistake we *would not* do,
but given everpresent software degradation *from unknown sources and for
unknown reasons* let's not ~~COPILOT~~ *ahem* tempt fate...
2026-03-06 19:54:44 +09:00
Dean Herbert
04767f44bb Allow editor 100% background dim (#36847)
Whatever at this point.

https://github.com/ppy/osu/discussions/30421
2026-03-06 19:32:34 +09:00
Dean Herbert
8fe63ade31 Adjust padding and text size in editor inspector (#36843)
It was taking up way too much vertical space previously.

I'm using the same font specs that are in the new dropdown header, which
seem to work quite well. Negative padding because without it everything
is way too vertically sparse.

Why? I was looking at [this
discussion](https://github.com/ppy/osu/discussions/36708) and like "we
need to have SV visible here" but there's really not much room with all
this text in the way.
2026-03-06 19:32:19 +09:00
Eeli Ogata
c1555af620 Only play nightcore hat sounds when tick rate is a multiple of 2 (#36459)
Closes #13513

Matches stable behavior where hat only plays when the slider tick rate
is a multiple of 2.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-03-06 17:56:14 +09:00
Eeli Ogata
e911217980 Fix crash when clicking panels during recycling (#36457)
Closes #36246

This PR overrides `HandlePositionalInput` to reject all positional input
when `Item` is null.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-03-06 09:36:39 +01:00
Bartłomiej Dach
ba2ae3218e Show first two slider repeats with the rest of the combo in Freeze Frame mod (#36427)
Before:


https://github.com/user-attachments/assets/95b19bdb-12c5-4ee7-b7e2-f9098aecd2fa

After:


https://github.com/user-attachments/assets/937081c5-92cb-4bea-a774-e53afbdbb1fb

---

This is a subjective diff and can be closed on the spot with no
discussion if deemed incorrect. I mostly just want to get it off my list
of unresolved forum threads.

The catalyst for this change is [this
thread](https://osu.ppy.sh/community/forums/topics/2171493?n=1), wherein
the complaint is that you can get jumpscared by a slider repeat in a
combo because the slider repeats do not fade in with the rest of the
combo. Which means that you don't immediately know whether a slider will
need to be repeated or not and you have to watch out for potential
slider repeats fading in, which could happen at an *arbitrary* time
because it's still dependent on the map's original AR.

This seems pretty anti-user so I made it fade in with the rest of the
combo. The original comment cited "broken layering" which I guess refers
to the fact that sliders can repeat *more* than once and the second
repeat will show *under the slider head*. It's pretty broken, sure, but
I don't think it's *that* bad, and I *do* think that it's better than
the current behaviour.

The reason it shows only the first two repeats is that there's no point
in showing more for reasons that are hopefully obvious.
2026-03-06 15:29:47 +09:00
Krzysztof Gutkowski
b76a7e1bb6 Refactor ShearedButton to allow easier relative sizing (#36802)
This commit rearranges the contents of `ShearedButtons` to be more
independent of each other in regards to sizing. Thanks to that, the
custom logic related to enabling autosizing is no longer necessary.
Witdh and height are no longer set via the constructor, and can be
freely configured using the initializer syntax.

Additionally, this allows the button to use relative sizing without
having to resort to any hackery with `Size` (this will come in handy for
me when implementing the new footer on multiplayer screens).

Given that most of the `ShearedButton`s currently in use set their width
explicitly, I did not set `AutoSizeAxes = Axes.X` like it would be by
default previously. Instead it is set on the only two such buttons (show
converts/selected mods on ssv2). I suppose it might be a good idea to
have it set that by default if no `Width` is specified, as right now
it'll just not show anything.

Also I've set the margin on the text field by default in all cases
instead of only when autosizing like how it was previously, since
otherwise it would be a pain to set that on each button instance when
needed. I've checked all affected components and could not find any text
overflowing issues that this could cause.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-03-06 02:09:05 +09:00
Bartłomiej Dach
6b10ef8709 Disable presenting scores in online song selects (#36826)
RFC. Closes https://github.com/ppy/osu/issues/36815 I guess.

Song select V1 completely disabled the ability to view a score outside
of solo play in ways that are very easy to let fly under the radar:


5fc836d1f0/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs (L26)
46db3ad96d/osu.Game/Screens/Select/PlaySongSelect.cs (L47-L53)

therefore the issue this is trying to close would never even manifest
there.

The direct cause of the issue is that the results screen is pushed to
the relevant online screen's *substack* of screens rather than the
game-global parent stack. That means that when the back button is
pressed, the following logic fires:


6fa4a7152f/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs (L174-L189)

This logic fires *on the parent screen* even though *the child screen*
is the one the user is attempting to back out of. And none of the
exemptions for the screen substack inside of the above method fire
because the subscreen is not an `IOnlinePlaySubScreen` (it's
`SoloResultsScreen` in this case).

Now the direct cause here is probably fixable, although possibly not
without some significant pulling of footer-shaped teeth. *However*, I
kind of question as to why viewing scores should be permitted on online
song selects in the first place - it kind of distracts from the primary
purpose of the screens which is to *just pick a map already*.
2026-03-06 00:19:10 +09:00
Bartłomiej Dach
43897457fb Fix subscription leak from composer reloads (#36828)
The reproduction scenario for the subscription leak is as follows:

1. Switch to a scrolling ruleset (anything but osu! from the standard
ones).
2. Select a beatmap to edit.
3. Load the composer.
4. Go to timing tab.
5. Change a timing point.
6. Go back to the composer.

At this point, `EditorChangeHandler.OnStateChange` will have multiple of
the same delegate in the invocation list.

<img width="691" height="311" alt="Screenshot 2026-03-05 at 11 15 55"
src="https://github.com/user-attachments/assets/57788341-9573-48f1-b360-f21036891081"
/>

That in turn is caused by the fact that changing a timing point *does*
incur a full reload of the composer via the following flow:


15b6e28ebe/osu.Game/Rulesets/Edit/ScrollingHitObjectComposer.cs (L145)
64a29313a8/osu.Game/Screens/Edit/Editor.cs (L1137-L1145)

This flow is my "fault"; see https://github.com/ppy/osu/pull/28444. The
reason why a full composer reload is used is not clear to my
recollection at this time, but it is likely because it's just the least
likely to fail. A smarter solution that wouldn't require a full reload
would also entail checking that there exists a safe insertion point that
allows replacing timing points in a way that will reflect everywhere it
must. Including all of the `IScrollingAlgorithm` machinery and such.

In general it is not uncommon in the codebase to not bother to clean up
some event callbacks if it is implicitly or explicitly guaranteed that
both objects bound by the callback will always get disposed in tandem at
the same time. This *was* true with this particular flow to a point,
which was until that full composer reload was implemented.

<details>
<summary>To address the elephant in the room</summary>

Someone will inevitably notice https://github.com/ppy/osu/pull/36824
which was a clanked pull request pointing out this leak. And then
someone will inevitably call this "AI discrimination"! *Gasp!*

So first of all, let me stop you right there. Yes, as far as I am
_personally_ concerned, it is "AI discrimination". I invoke the full
force of the Butlerian Jihad.

The clank army's goal is to eradicate my job and make me work in an
Amazon warehouse instead. Or, if not that, at least my job is to be rid
of all remnants of fun I still get from it and for me to be reduced to
that one guy from the meme "i guess we're doin circles now". You know
the one.

I resent this. You attack me directly. I do not perceive the need to
meet you halfway or be civil.

That said, I have too much respect for the users of this software to
leave reports of potentially real issues unchecked. So I did check, and
it was real. And you know what? Good job to the clanker. It did what it
was designed to do: it parsed a code file, recognised a hole in a
pattern it was designed to recognise, and invoked forms of language
given to it to communicate this to the meatbag that opened that PR.

And here's the thing: my primary issue is with that meatbag that opened
that PR. That meatbag served no functional purpose in any of this. The
meatbag took a hose that spews 90% water and 10% raw sewage at random
intervals and pointed it at my house directly, claiming that they just
want to clean it. At no point did the meatbag appear to have the common
decency to pull out a container, pour some magic liquid out, check if
there's sewage in it, and filter it out if there is any. But no, that
would take *effort* and *thought*, would it not? The *effort* and
*thought* that is required of *me* to *review* the clanker's work?

The PR had no reproduction scenario, and had testing checkboxes that
were presumably meant for *me* to check off. Why is it *my* job to
figure all of this out rather than the submitter meatbag's?

I do *not* have obligations towards spew-hose-pointing meatbags. Point
that hose at your own backyard at your peril.

If you *actually manage* to get the clanker to filter out *all* of the
spew without fail itself, my only win condition is gone. But it is not
yet that time. So at least have the decency to check for the spew
yourself, rather than telling the clanker to put checkboxes in the PR
descriptions telling *me* to check for it.
</details>
2026-03-05 22:37:50 +09:00
Dean Herbert
bb289363a2 Update resources 2026-03-05 14:58:12 +09:00
Denis Titovets
28a18f768c Use web localisation on LeaderboardScopeSelector to match osu-web (#36814)
- regressed in
1f052bb195
- also see https://github.com/ppy/osu/pull/34074#discussion_r2211853662

did it by analogy with
a0ecbd7c87/osu.Game/Overlays/BeatmapSet/Scores/NoScoresPlaceholder.cs (L27-L49)

| master | pr | `osu-web` |
|-|-|-|
| <img width="1625" height="188" alt="osu_2026-03-04_18-26-44"
src="https://github.com/user-attachments/assets/9bd2690a-2ddf-4f03-9ca6-22003efbd895"
/> |
![osu_2026-03-04_18-36-12](https://github.com/user-attachments/assets/1498c4a9-7188-4e97-a6bd-3553b9befa5e)
| <img width="990" height="139" alt="Снимок экрана 2026-03-04 182558"
src="https://github.com/user-attachments/assets/1bf14bee-3097-478d-936b-6ecb7d912be2"
/> |

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-03-05 13:40:31 +09:00
Denis Titovets
45945e3bb1 Return tooltips to footer buttons on MultiplayerMatchSongSelect (#36817)
- reported by @Loreos7 in
https://discord.com/channels/188630481301012481/188630652340404224/1478809956076491006
- probably regressed in https://github.com/ppy/osu/pull/36752
2026-03-05 13:01:33 +09:00
Dean Herbert
cab50e94c8 Reduce online user list panel churn on initial display (#36811)
Yes this is a funny way of doing it, but it works and is better than
what we have for the initial release.

Don't expect this to stay around forever.
2026-03-05 00:44:03 +09:00
Dan Balasescu
ae032622ac Unimplement legacy compatibility method (#36812)
The spectator server invokes both legacy and non-legacy methods to keep
compatibility with older clients:


fe0dad3245/osu.Server.Spectator/Hubs/Multiplayer/Matchmaking/Queue/MatchmakingQueueBackgroundService.cs (L292-L299)

I thought that it'd be a good idea to implement the legacy method here,
but it turns out to not be such a good idea because it means ranked-play
clients will assume they're receiving a quick play invitation.
2026-03-05 00:31:43 +09:00
Dean Herbert
a0ecbd7c87 Merge pull request #36798 from bdach/tags-broken
Fix a bunch of breakage around user tags
2026-03-04 21:16:38 +09:00
Dean Herbert
459d5e8a45 Merge branch 'master' into tags-broken 2026-03-04 19:50:33 +09:00
Bartłomiej Dach
9b55e1dfdb Only show user tags above threshold by default 2026-03-04 10:34:35 +01:00
Bartłomiej Dach
4c873787c1 Merge pull request #36752 from peppy/song-select-v1-salute
Remove remnants of song select v1 and move v2 to final resting location
2026-03-04 10:27:07 +01:00
Bartłomiej Dach
43af89f75c Remove outdated xmldoc 2026-03-04 08:44:31 +01:00
Bartłomiej Dach
f74a21c1e1 Merge branch 'master' into song-select-v1-salute 2026-03-04 08:39:58 +01:00
Bartłomiej Dach
a028f0ba4a Fix loose spacers at top of leaderboard score context menu (#36799)
Closes https://github.com/ppy/osu/issues/36777.
2026-03-03 23:40:08 +09:00
Bartłomiej Dach
1aa42a73b1 Fix code quality 2026-03-03 13:38:23 +01:00
Bartłomiej Dach
d9e182230d Add bool flag for checking tag vote threshold & utilise as required
Closes https://github.com/ppy/osu/issues/36453.

My omission was in assuming that web was going to start filtering out
the tags below the threshold from API responses, which is not the case.

Whether or not the consumers want or not to display tags below threshold
is subjective. I figured that the matchmaking card tooltip might want to
display below threshold but I dunno.
2026-03-03 13:03:33 +01:00
Bartłomiej Dach
65b49137ee Move constant closer to helper 2026-03-03 13:03:33 +01:00
Bartłomiej Dach
2f96e96576 Migrate realm populating online lookup source to use helper method for retrieving tags
To reduce logic duplication.
2026-03-03 13:03:27 +01:00
Bartłomiej Dach
e64e0f0ca9 Fix beatmap set overlay not showing user tags at all
Regressed in 60d9c358b8.

In general an `APIBeatmap`'s `BeatmapSet` need not be present. In the
usage site of `osu.Game.Overlays.BeatmapSet.Info`, `Beatmap` and
`BeatmapSet` were actually two separate bindables. Moving the logic to a
helper, and therefore implicitly moving `BeatmapSet` from tracking said
separate bindable to instead refer to `Beatmap.BeatmapSet` broke this.
2026-03-03 12:44:29 +01:00
Bartłomiej Dach
d37f59430b Merge pull request #36796 from Joehuu/standardise-play-favourite-order
Standardise display order of playcount / favourites
2026-03-03 11:22:51 +01:00
Bartłomiej Dach
d748470754 Merge pull request #36795 from peppy/carousel-scrollbar-state-capture
Fix song select carousel state capture
2026-03-03 10:40:25 +01:00
Bartłomiej Dach
2539bd90fa Merge pull request #36794 from peppy/fix-tooltips-not-displaying-custom
Fix offset slider no longer showing explanatory tooltip correctly
2026-03-03 10:32:15 +01:00
Dean Herbert
317be21569 Final attempt to make copy labels work 2026-03-03 17:24:29 +09:00
Dean Herbert
b1044b6b2d Update framework 2026-03-03 17:20:14 +09:00
Dean Herbert
c28c64940a Move v2 files to final location
This contains only renames and namespace updates.
2026-03-03 16:45:15 +09:00
Dean Herbert
b4f40639a1 Add special not regarding collection dropdown 2026-03-03 16:45:15 +09:00
Dean Herbert
7e7421e1ea Update TestSceneDeleteLocalScore to use newer leaderboard 2026-03-03 16:45:14 +09:00
Dean Herbert
1a8d2855d4 Remove all song select v1 files
This contains no code changes (that would need review), only file
deletion and extraction where required in a few odd cases.
2026-03-03 16:45:14 +09:00
Dean Herbert
54a1417dd8 Move leaderboards classes to gameplay namespace for now 2026-03-03 16:45:13 +09:00
Dean Herbert
ce542b03db Move components only used by beatmap set overlay local to namespace 2026-03-03 16:45:13 +09:00
Dean Herbert
f20d182775 Update filter matching tests to be independent of old song select classes 2026-03-03 16:45:12 +09:00
Dean Herbert
a7e6286396 Fix a few remaining references to old song select 2026-03-03 16:45:12 +09:00
Dean Herbert
521a40d860 Remove now unused footer buttons 2026-03-03 16:25:58 +09:00
Joseph Madamba
564b6ebd0c Add tooltips to beatmap info overlay statistics 2026-03-02 22:53:09 -08:00
Joseph Madamba
7dfbab212e Add nominations statistic to beatmap info overlay
See 2198adfa68/resources/js/beatmapsets-show/header.tsx (L116-L123).
2026-03-02 22:47:10 -08:00
Joseph Madamba
b831bcbcd4 Change beatmap card play count and date icon to solid to match web 2026-03-02 22:40:16 -08:00
Joseph Madamba
c372f9b8f5 Standardise display order of playcount / favourites 2026-03-02 22:37:32 -08:00
Dean Herbert
b0759ff34d Fix song select carousel state capture
Closes #36776.
2026-03-03 15:36:46 +09:00
Dean Herbert
d60a12a351 Fix ordering of skins not working as expected (#36772)
As mentioned
[here](https://github.com/ppy/osu/pull/11536#issuecomment-3977314909).

Realm ordering is weird/broken so let's just do it at our end.
2026-03-03 14:03:55 +09:00
Dean Herbert
d27d0f40c1 Switch multiplayer to use song select v2 (#36747)
Tests pass and seems to work. Need to do a bit more self-testing for
higher confidence, but in theory..

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

---------

Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-03-03 13:41:48 +09:00
Dean Herbert
ee9f8d5e92 Fix custom tooltip formats no longer displaying in settings
Closes #36793.
2026-03-03 12:59:23 +09:00
Bartłomiej Dach
9c8dfaf386 Apply more sanity checks when handling files from archives 2026-03-02 13:11:01 +01:00
Linus Genz
033e13cb3b Fix song select navigation with page up/down (#36293)
Resolves #36099 

This PR fixes keyboard navigation in the beatmap select carousel for
lazer by implementing page-wise traversal with the Page Up and Page Down
keys and changing it from only scrolling to actually selecting items.

**Changes:**
- Added handling for `TraversalType.Page` in the keyboard traversal
switch.
- Implemented `traverseKeyboardPage(int direction)` method to move the
selection by approximately one "page" of visible items, accounting for
partially obscured items like the search bar. Also it does not wrap
around (like the current PageUp/Down functionality).
- Added new key bindings:
    - `PageUp` → SelectPreviousPage
    - `PageDown` → SelectNextPage

The code may be very explicit for the scroll logic with the page keys,
so I would appreciate some feedback when the PR is reviewed.
The naming of the keybinds may need to be adjusted. `Next page` and
`previous page` may be somewhat misleading.

**Behavior after the change:**
- Pressing Page Up/Down now moves the selection by a page of items.
- After navigating, pressing Left/Right selects the navigated song
instead of moving relative to the previous position.

**See:**
https://www.youtube.com/watch?v=JXmKAhhKiCc

---------

Signed-off-by: Linus Genz <linuslinuxgenz@gmail.com>
Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-03-02 02:08:19 +09:00
Krzysztof Gutkowski
b88cba0829 Refactor TestSceneScreenFooter to test entire OsuScreens (#36718)
Part of the `ScreenFooter` refactor, which intends to move the footer
content handling to `OsuScreen`. This commit updates the `ScreenFooter`
test to operate on entire `OsuScreen`s, in order to better test the
entire flow of pushing a screen, and having it create and add its own
content to the footer.

This should be 80-90% identical to the original test case structure
wise, just that instead of manually manipulating the footer with
`SetButtons()`, various screens with the appropriate buttons are being
moved around the screen stack.

Additionally this adds some more tests handling common use cases, as
well as removes `TestLoadOverlayAfterFooterIsDisplayed()`, since as far
as I understand the behaviour described in it doesn't actually happen in
production code. From what I can see, Screens instantiate their overlays
in `load()`, and then register them in `LoadComplete()`. There seems to
be no case where a `ShearedOverlayContainer` is created in the middle of
a screen's lifecycle.
2026-03-01 22:36:07 +09:00
Denis Titovets
9c489aacf8 Use better text structure for ScreenshotSaved notification (#36701)
reads a bit better when filename isn't in main text

also added "click to view" text by analogy with `LogsExportFinished`

| master | pr |
|-|-|
| <img width="336" height="114" alt="image"
src="https://github.com/user-attachments/assets/2555390c-1299-43ae-9be5-cb8d091b3387"
/> | <img width="336" height="108" alt="image"
src="https://github.com/user-attachments/assets/a8f18d9f-fa11-4d8f-82af-c88b0f82576c"
/> |
2026-02-28 22:58:07 +09:00
Krzysztof Gutkowski
105342e5bf Migrate sheared overlay tests to ScreenTestScene (#36736)
Part of the screen footer refactor.

Once footer content is being managed by `OsuScreen`, the current tests
which simply create the tested overlay and `ScreenFooter` in a container
will no longer work.

This PR refactors them to use `ScreenTestScene` with the setup being
creating a dedicated testing `OsuScreen` which does the bare minimum to
create the tested overlay and necessary components (eg.
`FooterButtonFreeModsV2` for `TestSceneFreeModsOverlay`).

Most of the changes here can be described as
`%s/<...>Overlay/screen.Overlay/g`, with some minor touchups as
necessary, given that we're now testing a more complete flow which
checks more things that were previously not handled by the tests.

## [Move footer to front in
ScreenTestScene](f8740e0403)

Self-explanatory. Without it the footer would show below the actual
overlay, breaking tests depending on manual input. For the sake of tests
not breaking in CI, both #36718 and this have this included - would
prefer the former to be merged first since it was already reviewed
there.

## `TestSceneModSelectOverlay`

There were a few tests (`TestColumnHidingOnIsValidChange`,
`TestColumnHidingOnTextFilterChange`, and
`TestHidingOverlayClearsTextSearch`) that would create a custom overlay
instance instead of the globally provided one. I've tested both and the
tests run fine with the default overlay, so they're now using that
instead.

## `TestSceneFreeModSelectOverlay`

Updated to use footer v2.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-02-28 04:22:58 +09:00
Dan Balasescu
c72b6412ea Add pool type to matchmaking room invited event (#36765)
Rebase of https://github.com/smoogipoo/osu/pull/193

Going forward, the client will have to know the type of pool being
invited to so that it can enter the appropriate screen when clicking the
notification.

Unfortunately, SignalR does not support overloading methods, or even
adding parameters to them, so this PR deprecates the
`MatchmakingRoomInvited` event and adds its replacement
`MatchmakingRoomInvitedWithParams` with a complex `invitation` parameter
that we _can_ extend in the future if required (such as potentially
adding the name of the pool).

This also prepares the notification by extracting some code to a
`Complete` method receiving said `invitation` parameter. This part of
code will be further modified to enter the correct screen:


0a4018045b/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/QueueController.cs (L200)

In particular, I have tested that new clients continue to work with the
old server (dev.ppy.sh) in quick play

|         | Old Server           | New Server  |
| ------------- |:-------------:| :-----:|
| Old Client      | 🟢  | 🟢 |
| New Client      | 🟢  | 🟢 |
2026-02-28 00:42:44 +09:00
Dean Herbert
2e659a79ec Merge pull request #36767 from LiquidPL/cleanup-online-play-tests
Remove redundant footer from `TestScenePlaylistsRoomSubscreen`
2026-02-27 20:13:21 +09:00
Krzysztof Gutkowski
5131b188d1 Remove redundant footer from TestScenePlaylistsRoomSubscreen
`ScreenTestScene` already provides one.
2026-02-27 11:12:30 +01:00
Bartłomiej Dach
7e2771c3f0 Improve usability of sample bank toggles (#36753)
- [x] Depends on https://github.com/ppy/osu/pull/36741 for merge
conflict avoidance

RFC, cc @OliBomby

## [Adjust behaviour of automatic bank assignment during
placement](547f55e9b3)

Diatribe time!

This is fallout of the discussion about auto bank in
https://github.com/ppy/osu/issues/36705.

Auto bank in lazer as written before this commit is confused. On stable,
auto bank is closer to "no bank", as in "go look up the current sample
timing point, get the bank of that, and use that". lazer has no timing
points anymore, but people still want auto bank. So what do?

Auto bank for normal samples is somewhat sane still. It only works
during placement, and will just copy the normal bank of the previous
object - if one exists. That said, one *might not* exist, but the
resulting object will still have its normal sample created with
`editorAutoBank: true`. That is largely cosmetic and without
consequences, but this commit fixes that.

Auto bank for *addition* samples, however... Hoo boy.

- For placed objects, auto bank means "take the normal sample, read its
bank, and use that". Simple enough, right?
- Hoooooowever. During placement, auto bank before this commit used to
mean "look at the *previous object*, check if it has an addition sound
and then use its bank, if not use *the previous object's* normal sample
and then use its bank" which is a completely different thing with its
own implications. Like, say, what happens if the previous object uses
the auto addition bank too? What should be copied over? Should it be the
notion of "auto bank" in that the addition bank should match the normal
bank, or should it be the literal bank that the previous object is
using?

This change attempts to define this unambiguously. "Auto additions bank"
means "the same bank as the normal bank of this object", full stop.

## [Do not touch sample toggle state if there are no selected
objects](052cde5987)

Fixes issue described in
https://github.com/ppy/osu/issues/36705#issuecomment-3953917163 wherein
opening a sample popover will disable addition bank toggles and toggle
off all addition samples.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-02-26 15:18:29 +09:00
Bartłomiej Dach
5174d8b918 Fix changing normal sample bank via keyboard hotkeys not updating addition bank if set to auto (#36741)
Closes https://github.com/ppy/osu/issues/36703.

It was only broken via keyboard hotkeys and not via the sample popover
because the sample popover has a separate copy of the logic that didn't
have the bug. Compare:


13aeed15f9/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs (L473-L475)

I considered splitting a helper to have one copy of the logic but it's
not very simple to do compared to a two-liner fix so I gave up.
2026-02-26 02:47:45 +09:00
Bartłomiej Dach
32d10406c9 Merge pull request #36751 from peppy/fix-hidden-controls-settings
Fix input settings being interactive even when collapsed
2026-02-25 10:38:10 +01:00
Neti
0dfb362b2d Use HotkeyDisplay for toolbar buttons (#36750)
Uses `HotkeyDisplay` for toolbar button tooltips rather than
`SpriteText`

<img width="433" height="160" alt="image"
src="https://github.com/user-attachments/assets/d74c4dd2-27fd-4e7c-881e-3c6152982dd6"
/>

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-02-25 16:31:36 +09:00
Dean Herbert
047ea7c09d Fix hidden settings flow content still being interactive
`AlwaysPresent` is a code smell here. Rather than doing this, let's just
using masking as we usually do.

Closes https://github.com/ppy/osu/issues/36748.
2026-02-25 14:35:24 +09:00
Dean Herbert
cb597c4120 Fix flow animating its display initially when it shouldn't 2026-02-25 14:34:50 +09:00
Dean Herbert
99ab245cf0 Tidy up how SettingsSubsection headings are created
Previously we were always making header content in the base class then
overwriting it, which felt ick.
2026-02-25 14:34:49 +09:00
Dean Herbert
ee8d99034c Rename one more missed song select v2 class 2026-02-25 02:18:18 +09:00
Dean Herbert
5b1d4ceb9d Merge pull request #36746 from bdach/fix-thing-again 2026-02-24 21:48:06 +09:00
Bartłomiej Dach
ccb0224a1b Attempt to fix "copy labels from issues" workflow permissions again
It's still broken:

https://github.com/ppy/osu/actions/runs/22310482792/job/64540909415

and I'm not sure what else it could be other than this, so I'm giving it
one more honest try before I throw up hands.

For better or worse,
https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#permissions
explicitly lists that the `pull-requests` permission allows tagging PRs,
so I'm holding out hope that this is it. Still terrible marks for
documentation here, both to the github action, as well as everything to
do with `GITHUB_TOKEN`.
2026-02-24 13:34:06 +01:00
Bartłomiej Dach
5602281bd9 Merge pull request #36745 from peppy/song-select-cleanup
Various song select class cleanup
2026-02-24 13:24:18 +01:00
Dean Herbert
fabce18552 Remove V2 suffix from migrated classes 2026-02-24 20:23:29 +09:00
Dean Herbert
cb12d35d8f Combine old classes to provide better starting point for migration 2026-02-24 20:23:28 +09:00
Dean Herbert
efc9a27d2d Remove no longer used class 2026-02-24 20:23:28 +09:00
Bartłomiej Dach
e2cbfb970e Merge pull request #36738 from peppy/user-button-animation-fix
Fix transient user stats animation changing speed after first display
2026-02-24 08:19:02 +01:00
Dean Herbert
f39615a374 Move spacing local to usages 2026-02-23 15:59:09 +09:00
Dean Herbert
4916c87f14 Move toolbar button text local to single usage in ToolbarUserButton 2026-02-23 15:58:57 +09:00
Dean Herbert
a09489d4c0 Move transformation logic local to transient drawable 2026-02-23 15:47:01 +09:00
Dean Herbert
d139f5997c Update resources 2026-02-23 03:37:40 +09:00
Joseph Madamba
29a39cbfb7 Fix spectator player cells not having initial shadow edge effect set (#36729)
- Fixes https://github.com/ppy/osu/issues/36727

Copies/sets the non-maximised edge effect initially:


c144cf188a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid.Cell.cs (L83-L88)
2026-02-21 23:19:32 +09:00
Arthur Araujo
c144cf188a Fix reversing straight perfect curve sliders positioning them weirdly (#36698) 2026-02-20 16:57:42 +01:00
Bartłomiej Dach
1e8b9a7639 Adjust nightcore sample playback to not stop randomly and be closer to stable (#36702)
- Closes https://github.com/ppy/osu/issues/30293
- Fixes https://osu.ppy.sh/community/forums/topics/2179339?n=1

Aside from fixing the off-by-one error that I mentioned in
https://github.com/ppy/osu/issues/30293#issuecomment-2413801663, this
also:

- Brings back the behaviour wherein if timing points are arranged very
weird and nightcore would play e.g. two first beats in a timing point
back-to-back, the second timing point is silent.
- Brings back the behaviour wherein the finish sample only plays if
`OmitFirstBarLine` on the timing point is disabled.

However:

- This does not bring back the behaviour wherein hat samples only play
if the slider tick rate is even because that only kind of makes sense in
common time, and if common time is mixed with waltz time or other time
signatures, it just gets weird.
- Also stable has zero attempt for compensating for waltz time anyway,
lazer's behaviour is bespoke, so that is not going to match any way you
cut it.

My testing procedure essentially consisted of getting stable to log when
it was playing nightcore samples and cross-checking the first 30sec or
so of https://osu.ppy.sh/beatmapsets/534385#osu/1131956 (check out the
timing of that beatmap, for something ranked it is DEEPLY messed up).

I guess I can add test cases if deemed required but I already wasted
much more time than I would have liked here...
2026-02-20 12:53:12 +09:00
Bartłomiej Dach
69c2747883 Merge pull request #36696 from peppy/multiplayer-freestyle-select
Migrate multiplayer freestyle select screen to use `SongSelectV2`
2026-02-19 12:16:51 +01:00
Bartłomiej Dach
d3b48364c5 Merge branch 'master' into multiplayer-freestyle-select 2026-02-19 10:55:30 +01:00
Bartłomiej Dach
9ae99648fb Merge pull request #36694 from peppy/freestyle-select-update
Migrate playlist freestyle select screen to use `SongSelectV2`
2026-02-19 10:55:07 +01:00
Bartłomiej Dach
f9f927fa45 Disable footer buttons on freestyle song select
- The mods button should not be visible because it is not hooked up
  properly to actually work with selecting user mods. As written it
  would show (and feign the ability to modify) required mods on the
  playlist item.

  You could probably adjust the logic to make user mods controllable via
  this button but this is simpler for now.

- The random and options buttons could perhaps remain, but they are of
  very limited use on this screen anyway.

The previous iteration disabled all footer buttons altogether, so I'm
just following precedent here mostly.
2026-02-19 10:07:51 +01:00
Dean Herbert
1153d17153 Disallow use of scoping button when at freestyle song select 2026-02-19 01:47:03 +09:00
Bartłomiej Dach
e15cb08b44 Privatise setter 2026-02-18 14:42:04 +01:00
Bartłomiej Dach
25d630898b Merge pull request #36695 from peppy/loading-layer-block-non-positional
Add ability for `LoadingLayer` to block all keyboard input
2026-02-18 14:40:31 +01:00
Dean Herbert
48544733c3 Migrate multiplayer freestyle select screen to use SongSelectV2 2026-02-18 20:50:17 +09:00
Dean Herbert
d33a6d5512 Add ability for LoadingLayer to block all keyboard input 2026-02-18 20:50:14 +09:00
Dean Herbert
110f11fa5e Fade out header line for now to avoid visual overlap 2026-02-18 20:48:17 +09:00
Dean Herbert
fb8c228d32 Add test coverage of actual user flows involving freestyle select screen
Of note, this test scene still doesn't use the new footer properly.
Should these even be here? Maybe it's better to leave these real world
flows to a `Navigation` style test so we're not dealing with weird test
setups that kinda do something but don't... or maybe do it in three
different ways (two footers present, three back buttons etc.)

Dunno. But this kind of covers what I want (except it doesn't cover the
new footer usage).
2026-02-18 20:48:16 +09:00
Dean Herbert
93d1a61dc2 Migrate playlist freestyle select screen to use SongSelectV2 2026-02-18 20:30:14 +09:00
Dean Herbert
83587e2265 Add ability for LoadingLayer to block all keyboard input 2026-02-18 20:01:38 +09:00
Dean Herbert
f15e086bb0 Add "spin" keyword for menu cursor rotation 2026-02-18 17:21:03 +09:00
Bartłomiej Dach
9fa78123a6 Merge pull request #36687 from peppy/legacy-key-counter-skinnable-font
Fix legacy key counter not using skin's font
2026-02-18 08:26:21 +01:00
Dean Herbert
7445efaecd Ensure state resets back to initial display on rewind 2026-02-18 02:25:09 +09:00
Dean Herbert
86ab507e2e Use default overlap of 1
Matches closer to stable spec.
2026-02-18 02:22:00 +09:00
Dean Herbert
cc9a5ede29 Update resources 2026-02-17 16:44:26 +09:00
Dean Herbert
6e03d5b00e Show initial key placeholder / trigger name using non-skinned font
In stable, there was support for mixed fonts (some coming from the
user's skin, with fallback missing characters generated from TTF
backend).

We don't really have support for this so this is a simple in-between for
the time being.
2026-02-17 16:02:13 +09:00
Dean Herbert
71583bc06f Add basic support for scoreentry- skinnable text 2026-02-17 15:54:31 +09:00
Vanni
94cec71502 Prevent tagging beatmaps when played with conversion mods (#36684)
Closes #36553.
Supersedes #36614.

As discussed in #36614, the only exception to this is `ModClassic`.
2026-02-17 14:49:59 +09:00
Bartłomiej Dach
42bf25442b Fix osu! editor composer scale handles not updating correctly when selected object is changed (#36681)
Before:


https://github.com/user-attachments/assets/d0a0373d-2d46-48a9-9ea5-bac82a612f32

After:


https://github.com/user-attachments/assets/f5785b54-d7fc-4ce0-86b0-60c96ff22bc3

---

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

Kinda shocking this went by unnoticed for this long.
2026-02-17 00:50:16 +09:00
Bartłomiej Dach
fc4e29793d Use directory of last-selected sample as initial directory in sample set add controls (#36680)
Closes https://github.com/ppy/osu/issues/36470.

Applied directly to relevant control for now.
2026-02-17 00:46:30 +09:00
Krzysztof Gutkowski
8e26cf4e1b Restore previous beatmap when leaving scoped mode (#36582)
Resolves #36288.

If the current selection is still available after leaving scoped mode,
it's left as is. If it's not, the selection from before entering scoped
mode is restored.


https://github.com/user-attachments/assets/b1ac3de1-7c7f-4949-82a9-1dd0459f3f61

---------

Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-02-17 00:40:29 +09:00
Bartłomiej Dach
810edebe87 Fix extra lives in Easy mod potentially getting reapplied during gameplay (#36678)
Closes https://github.com/ppy/osu/issues/36676.
2026-02-16 19:02:59 +09:00
Arthur Araujo
2f459dd94e Preserve bookmarks when creating a new difficulty from scratch (#36675)
Closes #33395

Copies the bookmarks from `referenceWorkingBeatmap` while creating a new
difficulty from scratch. I adapted the tests in
`TestSceneEditorBeatmapCreation` to include the bookmark checks.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-02-16 12:50:04 +09:00
Dean Herbert
87f323a2e5 Update resources 2026-02-15 23:25:46 +09:00
Bartłomiej Dach
94d9de955f Add explanations for scoring mode used in ranked & total score tooltips (#36663)
Because people get confused by how this works.

Shows on results screen where the post-play statistics updates go.


https://github.com/user-attachments/assets/ef3a91d1-86dd-4029-8f0f-bdf0b727ca6c
2026-02-14 01:24:42 +09:00
Neti
860427e4ae Fix corner radius for user tag glow (#36659)
Fixes incorrect glow corner radius around user tag buttons

Before:
<img width="267" height="123" alt="image"
src="https://github.com/user-attachments/assets/3e602e84-bb13-46f7-942c-85ddf3954946"
/>
After:
<img width="227" height="102" alt="image"
src="https://github.com/user-attachments/assets/4dca2e3d-80e2-4b6c-988e-d14f371cfbe8"
/>
2026-02-13 14:48:07 +09:00
Bartłomiej Dach
5afd6c6835 Add user role to MultiplayerRoomUser (#36652)
- Related to https://github.com/ppy/osu-server-spectator/issues/406

Adding this field to this model has several vague reasons that I can't
fully formulate yet, but I can't really see myself going forward
*without* this.

- People were very excited about having referees displayed on the room
participants' list, and so adding the referees as real
`MultiplayerRoomUser`s helps this. Having the role could even be used
client-side to show a special icon or other status on the participants
list. (Which isn't done yet, could be as an aesthetic follow-up after
the basics are in place.)
- Server-side, having this field is convenient for things like
permission checks or just plain logic, as with two hubs you just need to
do different *stuff* on a `MultiplayerRoomUser`.
2026-02-12 00:57:03 +09:00
Krzysztof Gutkowski
50426eb3c8 Refactor UpdateableTeamFlag for use on team overlay (#36286)
Part of #32584.

Very much inspired by the respective component for displaying profile
pictures on the user overlay

* allow disabling interactivity/tooltips
* add option to show placeholder on null team instead of hiding
component entirely
* move setting corner radius out to respective parent components to
allow for easier overriding
2026-02-10 23:18:36 +09:00
Dean Herbert
56bc80ffb9 Update resources 2026-02-10 22:08:07 +09:00
Dean Herbert
c59e5bf335 Merge pull request #36639 from bdach/actually-all-valid-hit-results
Refactor hit result methods on `Ruleset`
2026-02-10 17:07:04 +09:00
Bartłomiej Dach
655d725f0c Perform extra checks when loading rulesets (#36641) 2026-02-10 13:34:43 +09:00
Bartłomiej Dach
15c49a729e Adjust contract of Ruleset.GetValidHitResults() to always enumerate all results used 2026-02-09 12:48:53 +01:00
Bartłomiej Dach
3678ea0d0f Publicise Ruleset.GetValidHitResults() 2026-02-09 12:00:30 +01:00
Bartłomiej Dach
dbce8886f8 Rename Ruleset.GetHitResults{ -> ForDisplay}() 2026-02-09 12:00:15 +01:00
Dean Herbert
a1136c3cea Update framework (#36637) 2026-02-09 19:39:30 +09:00
Bartłomiej Dach
b613c1dcd5 Merge pull request #36635 from peppy/update-production-endpoints
Update production endpoints in an attempt to fix Russian player connections
2026-02-09 09:13:07 +01:00
Dean Herbert
cae8d3f4d4 Update production endpoints in an attempt to fix Russian player connections 2026-02-09 13:29:21 +09:00
Dean Herbert
f39b310eb5 Add missing wait step to fix flaky test in TestSceneModPresetColumn
See
https://github.com/ppy/osu/actions/runs/21799682256/job/62893024859?pr=36627
2026-02-09 12:50:40 +09:00
maarvin
efd4d12c21 Add info about damage dealt to ranked play user state (#36627)
Adds a `DamageInfo` property to `RankedPlayDamageInfo` to be used by the
result screen.

The issue this is trying to solve is that once the result screen
initializes, the HP value of each player has already been updated in the
room state so the previous values are no longer accessible. Doing this
without the state exposing it would require some kinda setup to keep the
previous MatchState's HP values around on the client which would
introduce a lot of unnecessary weirdness.
2026-02-09 12:39:27 +09:00
Denis Titovets
60d98f0afd Improve adjusting mods settings values with keyboard (#36090)
- closes https://github.com/ppy/osu/issues/36016

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-02-09 11:35:01 +09:00
failaip12
01982030ec Allow binding left/right modifier keys separately for gameplay bindings (#36585)
Addresses #36583.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-02-09 10:15:34 +09:00
Dean Herbert
bb83f3dcf2 Fix unreliable async loading due to incorrect single-child assumption
See https://github.com/ppy/osu/actions/runs/21807684945/job/62913744850.
2026-02-09 10:05:13 +09:00
Joseph Madamba
0a4497db3c Fix local beatmap metadata not being cleared when previously selected beatmap is online (#36632)
- Closes https://github.com/ppy/osu/issues/36584

The last two commits could be either fixes to the issue above, but in a
code quality perspective, the scheduler in `setLink()` seems unnecessary
as the other set methods don't have it (other than making it run last)
and the other commit is self explanatory.
2026-02-09 09:55:36 +09:00
Denis Titovets
bb04a18060 Localise "lounge" & "quick play" in ButtonSystem (#36220) 2026-02-09 01:52:43 +09:00
Bartłomiej Dach
7263551aa8 Improve handling of account registration errors (#36600)
## [Specify `Accept` header in registration
request](28edb788f7)

The lack of it meant that in specific scenarios web would respond with a
chunk of HTML instead of JSON.

## [Allow showing registration error message even if no redirect is
given](6ad49941ff)

There are scenarios where this can happen, and if it did, previously the
strict requirement to have both would cause the specific message to be
discarded and replaced with the generic "something happened" one.
2026-02-09 00:51:31 +09:00
Joseph Madamba
239951eda9 Fix seeking to previous bookmark not working when song is playing (#36616)
- Closes https://github.com/ppy/osu/issues/35389

Same as:

2efe0c95e6/osu.Game/Screens/Edit/Editor.cs (L1173-L1180)

There's also seeking hit objects and sample points, but the seeks are
relatively close to each other and probably useless when playing(?). If
we want to make those cases not stuck at the same point in time, I
believe the leniency should be lower than 1000 ms.

With the above, that is why I just copy-pasted the code, as we may want
to have different leniencies.

Edit: forgot the automated label thing, will not label next time
2026-02-08 23:57:22 +09:00
SupDos
5cdf07c7e1 Make grouped friend notifications Transient and not important (#36620)
Grouped notifications for more than 1 person were added in
https://github.com/ppy/osu/pull/36180 but it looks like they forgot to
add the Transient and IsImportant flags, which means the grouped
notifications would still stay in the notification list/flash the
taskbar.

Before:


https://github.com/user-attachments/assets/8a34bbc0-2b5c-4086-b2ee-1daa6d1e6e10



After:


https://github.com/user-attachments/assets/03c25ba6-7c8e-464c-bbb1-688ab9da6bb6
2026-02-08 23:16:39 +09:00
Bartłomiej Dach
2efe0c95e6 Fix "copy labels from issues" workflow not having the appropriate permissions to do what it claims to do (#36602) 2026-02-06 20:22:53 +09:00
Denis Titovets
a616fa61c9 Localise some more strings in settings (#36590) 2026-02-06 19:23:02 +09:00
Ботников Максим
e77e08c049 Localize "Effect, Master, Music" in VolumeOverlay (#36594) 2026-02-06 19:22:06 +09:00
Michael Middlezong
5231cfa1c7 Change difficulty range slider colors to match star rating more closely (#36564)
my attempt at #36452: changes difficulty range slider in song select V2
to use the new star difficulty text gradient colors from #36292.

closes #36405


https://github.com/user-attachments/assets/134ace54-a8f8-4024-a32e-f1604c868232

to match star rating more closely for sr <= 7.5 (where i don't think the
colors are so intense that they break harmony with the rest of the
design), i removed the Lighten by 0.4f on color update

also improved the transition from 7.9 to 8.0 which is quite abrupt in
the current version

https://github.com/ppy/osu/pull/33425#issuecomment-2951914385 is
relevant here
2026-02-06 19:15:57 +09:00
Denis Titovets
40b331654e Localise some strings on SSV2 (#36591) 2026-02-06 19:12:07 +09:00
Bartłomiej Dach
5e01dda411 Fix star rating no longer updating from mod setting changes after re-entering song select (#36601) 2026-02-06 19:00:20 +09:00
Ботников Максим
5d4bb1bd37 Localise "running" in DigitalClockDisplay (#36589) 2026-02-05 23:22:25 +09:00
Dan Balasescu
1230da33a5 Implement sorting and display styles for currently online users (#33649)
- Adds sorting and display styles.
- Saves sort/display modes to the config.
- Improves performance, especially on the 2nd+ time opening the overlay.


https://github.com/user-attachments/assets/e32b50d0-58a1-4eef-b18c-988fb497e545

---

Coming off some recent feedback in
https://github.com/ppy/osu/discussions/33426#discussioncomment-13431275,
I decided to take a bit of a detour and get a little bit more
functionality in.

Sorting by rank, although it should technically work, doesn't work right
now. This is because the osu!web API doesn't return user rank on
`/user/` lookups - it's only returned for the friends request. I'm
leaving this open as a discussion topic.
- We can make osu!web return the rank and osu! will require no further
changes to work correctly, or
- We can try to implement additional paths through
`osu-server-spectator` which would blow this PR out of proportion and is
best left for a task of its own.

For simplicity, I've re-implemented this display mostly as its own
component for now, lifting code from `FriendDisplay` which was recently
overhauled. These implementations should eventually be combined somehow
but that's dependent on:
1. Figuring out the styling - friends can display offline users for
which it makes no sense to display the "spectate" button.
2. Figuring out how to handle the different users/presence pathways.
It's mostly a code complexity issue.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-02-05 01:22:36 +09:00
Bartłomiej Dach
57222ea0c7 Merge pull request #36580 from peppy/fix-revert-button-wrong-size
Fix revert to default button not resizing correctly after changing languages
2026-02-04 07:48:26 +01:00
Dean Herbert
892e34b1f8 Add automation to copy labels from issue when PR is opened
https://github.com/marketplace/actions/copy-issue-labels
2026-02-04 14:37:35 +09:00
Dean Herbert
b8b6327624 Fix revert to default button not resizing correctly after changing languages
Closes #36519.
2026-02-03 18:17:53 +09:00
nil
85b8480e46 Fix two mod presets having key binding of 1 (#36563)
Fixes #36562 

Currently there exists a bug where the mod preset hotkeys will wrap
outside of the intended bounds.

Fix is making sure the preset index is < 10

Before:
<img width="486" height="358" alt="image"
src="https://github.com/user-attachments/assets/77f1ca9e-4fd0-4b29-b9f5-f53e652db42d"
/>

After:
<img width="1007" height="1295" alt="image"
src="https://github.com/user-attachments/assets/ca81cc39-2f86-462c-a26b-002aceed77f4"
/>
2026-02-02 00:42:49 +09:00
Dan Balasescu
9e9b5cfc50 Invert quick play queue backgrounding and canceling flow (#36247)
- Exiting while queueing will now background the search.
- The "queue in background" button changed to "stop queueing".

Exiting while in the "pending accept"/"waiting for players" states will
exit from the queue. There is also a small period during the in-room
state (where the matchmaking screen hasn't been pushed yet but "good
luck" is displaying) where the user cannot exit from the screen. I've
removed the exit confirmation dialogs to streamline the process and
align with this.


https://github.com/user-attachments/assets/8c172502-0624-42cd-ae0c-bb710068267c
2026-02-01 02:19:20 +09:00
Bartłomiej Dach
c9a50b40d0 Merge pull request #36387 from ArijanJ/cycle-skins
Add skin cycling with shortcuts for next and previous skin
2026-01-30 08:57:23 +01:00
Bartłomiej Dach
8c21a5ba06 Merge pull request #36536 from peppy/silence-timeouts
Fix unobserved timeouts still showing to user
2026-01-30 08:34:13 +01:00
Joseph Madamba
2ab7492759 Fix initial solo gameplay leaderboard position and color (#36496)
- Closes https://github.com/ppy/osu/issues/35743

Matches playlists. Multiplayer seems to not have it, but I think that's
expected (i.e. there's no past scores, so having the initial position be
"-" and no initial green color seems right).

| Before | After |
| --- | --- |
| ![Kapture 2026-01-27 at 15 49
29](https://github.com/user-attachments/assets/39ad2cda-87e4-49e4-a872-4588ec07cae1)
| ![Kapture 2026-01-27 at 15 47
30](https://github.com/user-attachments/assets/1b8f1e42-5468-4634-8397-ba455c453761)
|
| ![Kapture 2026-01-27 at 15 51
57](https://github.com/user-attachments/assets/29b0a4b9-551a-4ac0-9b83-c8eb853422ae)
| ![Kapture 2026-01-27 at 15 52
45](https://github.com/user-attachments/assets/7b4b4c9b-4353-4845-9be1-8467326d3f6b)
|
2026-01-30 15:45:02 +09:00
Dean Herbert
cf09ed3e0d Fix unobserved timeouts still showing to user
As reported in https://osu.ppy.sh/community/forums/topics/2174881?n=1.
2026-01-30 15:37:01 +09:00
Tim Oliver
a774f19aef Updated iOS 26 app icon assets with newer version (#36535)
After testing out the icon on device for a bit, we decided the osu! logo
was a little too large.

This PR replaces the app icons with a new version where the sizing of
the logo itself is aligned to Apple's recommended boundary.

<img width="198" height="169" alt="Screenshot 2026-01-30 at 2 33 24 PM"
src="https://github.com/user-attachments/assets/c66fb016-9c19-4ff5-814a-6f302ec459ca"
/>
2026-01-30 14:40:25 +09:00
Denis Titovets
14d8cf7275 Add localisation support for DirectorySelector (#36371)
- depends on https://github.com/ppy/osu-framework/pull/6700
- closes https://github.com/ppy/osu/issues/36340
- supersedes and closes https://github.com/ppy/osu/pull/36352

<img width="676" height="451" alt="image"
src="https://github.com/user-attachments/assets/4f11c761-175b-495a-8b24-16fb6c481a15"
/>

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-29 19:13:02 +09:00
Bartłomiej Dach
7d476b4b7c Fix some text boxes no longer having borders (#36526)
Regressed in d6bf4fd90d.

One very visible instance of this regression is the login form.


https://github.com/user-attachments/assets/5ba10ac5-4cb1-49af-b55c-89cf58ca0b44

The `CommentEditor` usage was discovered with one of my favourite tricks
which is doing

```diff
diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
index fefe776b01..c17cca726b 100644
--- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
@@ -42,6 +42,12 @@ public partial class OsuTextBox : BasicTextBox
             Margin = new MarginPadding { Left = 2 },
         };
 
+        public new bool Masking
+        {
+            get => base.Masking;
+            set => base.Masking = value;
+        }
+
         protected bool DrawBorder { get; init; } = true;
 
         private OsuCaret? caret;

```

and then looking for usages of the setter. That's all due diligence
you're getting here, I'm not auditing every single text box in the game.

And yes, the `CommentEditor` usage is OMEGA dodgy but the change applied
here is the only one that preserves its visual appearance. I'm not
putting in time to fix it.
2026-01-29 19:11:10 +09:00
Bartłomiej Dach
de97660fa4 Fix hitsounds becoming loud in editor after entering setup section (#36512)
Probably closes https://github.com/ppy/osu/issues/36492.

This is dumb but it's in large part my stupidity.

To begin with, the immediate direct offending call that causes the
observed symptoms is


a401c7d5e9/osu.Game/Screens/Edit/Components/FormSampleSet.cs (L296)

The reason why this "invalidation" affects sample volume is that in the
framework implementation, the call [removes the relevant sample factory
from the sample store which is an audio
component](5b716dcbef/osu.Framework/Audio/Sample/SampleStore.cs (L65-L72)).
In the process it also [unbinds audio
adjustments](5b716dcbef/osu.Framework/Audio/AudioCollectionManager.cs (L37-L38)),
which *would* have the effect of resetting the sample volume to 100%,
effectively (and I've pretty much confirmed that that's what happens).

Now for why this call sometimes does the right thing and sometimes
doesn't: Sometimes the call is made in response to an *actual* change to
the beatmap skin, which is correct and expected, if very indirect, but
sometimes it is made *over-eagerly* when there is no reason to recycle
anything yet.

One such circumstance is entering the setup screen, which will still
"invalidate" (read: remove) the samples, but the compose tab hasn't seen
any change to the beatmap skin, so when it is returned to, it has no
reason to retrieve the sample again, and as such it will try to play
samples which are for better or worse in a completely undefined state
because they're not supposed to be *in use* anymore.

Therefore, the right thing here would seem to be to take the
responsibility of invalidation from a random component, and move it to a
place that's *actually* correlated to every other component needing to
recycle samples, e.g. `EditorBeatmapSkin` responding to changes in the
beatmap resources via raising `BeatmapSkinChanged`.

Unfortunately, because of the structure of everything, this recycle
needs to go from targeted to individual samples, to nuking the entire
store. The reason for this is that `RealmBackedResourceStore` does not
provide information as to *what* resources changed, it just says that
*the set of them* did.

For the recycle to be smarter, `EditorBeatmapSkin` would need to know
not only which samples were added or replaced, but also which ones were
*removed*, so that users don't hear phantom samples that no longer exist
in the editor later. That would however be a lot of hassle for nothing,
so I just recycle everything here and hope it won't matter.

As to why I could only reproduce this on this one beatmap - I'm not
super sure. The failure does not seem to be specific to beatmaps, but it
may be exacerbated by certain patterns of accessing samples which means
that beatmaps with high BPM like the one I managed to reproduce this on
may just be more susceptible to this.

As a final note, I do realise that this is not fundamentally improving
the surrounding systems and it's still a pretty rickety thing to do.
It's still on the consumers to know and respond to the sample store
recycle and this is likely to fail if a consumer ever doesn't. That
said, I have no brighter ideas at this point in time that won't involve
me spending a week refactoring audio.
2026-01-29 19:10:48 +09:00
Bartłomiej Dach
5468215de8 Merge pull request #36523 from smoogipoo/fix-team-display
Fix multiplayer team display becoming inconsistent
2026-01-29 10:20:21 +01:00
Bartłomiej Dach
1885ab86f5 Make Difficulty Adjust and Target Practice mods incompatible (#36524)
Closes https://github.com/ppy/osu/issues/36490.

While I'm out here already taking heat for deleting mod combinations let
me do more of that.

The main problem with the mod combination here, again, is that the
application of the mods does not commute.

- The current behaviour is that TP is applied first, then DA. This is,
again, "enforced" by the mod select overlay implicitly enforcing order
of the mod instances in the global mod bindable to match the display
order of mods inside it.

Even this doesn't "work" correctly as is, because as the bug reporter
points out, if they throw on DA with no changes expecting the map's
default AR to be applied, it still gets halved. This is because DA works
in a way wherein if you don't touch the AR slider, DA does not touch AR.
Which means that the DA slider should *really* be at *half* of the map's
base AR by default in this case because TP is active. How do you program
this?

- The *alternative* behaviour would be that DA is applied first, then
TP. This in turn would mean that the effective range of AR adjustment
offered by DA when TP is active would be halved to [0, 5] (or [-5, 5.5]
with extended ranges). How do you program this?

The above is just client-side concerns, while leaving out the other
giant concern, which is "how do you get every single place in the game
that may want to apply mods to a beatmap to apply them *in the same
order*?". Then extend that to server-side components, then extend that
to every external library that may want to re-implement SR/PP
calculations, etc. etc.

One additional remark:
What the bug reporter *did not* say however, but I am saying, is that
there's an elephant in the room, and that is the Easy mod, which *also*
changes AR, but also *happens* to apply commutatively with Target
Practice simply because both mods are implemented to halve the AR, which
means that the order of application doesn't matter. If I were *really*
bent on being a bad guy and just deleting mod combinations
indiscriminately, I'd delete that one as well. But I'm not doing that.
2026-01-29 17:59:28 +09:00
Dan Balasescu
586b2987a7 Fix multiplayer team display becoming inconsistent 2026-01-29 17:01:52 +09:00
Bartłomiej Dach
9bf52034d7 Make Hidden and Freeze Frame mods incompatible (#36515)
Effectively closing https://github.com/ppy/osu/issues/21471 as a
wontfix.

The issue is demonstrated by the following test case:

<details>
<summary>patch</summary>

```diff
diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs
index 31498295da..36b4fe5122 100644
--- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs
+++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs
@@ -55,5 +55,49 @@ public void TestSkipToFirstSpinnerNotSuppressed()
                 PassCondition = () => Player.GameplayClockContainer.GameplayStartTime > 0
             });
         }
+
+        [Test]
+        public void TestFreezeFrameAppliedBeforeHidden()
+        {
+            CreateModTest(new ModTestData
+            {
+                Mods =
+                [
+                    new OsuModFreezeFrame(),
+                    new OsuModHidden(),
+                ],
+                CreateBeatmap = () => new OsuBeatmap
+                {
+                    HitObjects =
+                    {
+                        new HitCircle { StartTime = 3000, Position = OsuPlayfield.BASE_SIZE / 2, NewCombo = true },
+                        new HitCircle { StartTime = 5000, Position = OsuPlayfield.BASE_SIZE / 2 },
+                    }
+                },
+                PassCondition = () => ((HitCircle)Player.GameplayState.Beatmap.HitObjects[1]).TimeFadeIn == 480
+            });
+        }
+
+        [Test]
+        public void TestFreezeFrameAppliedAfterHidden()
+        {
+            CreateModTest(new ModTestData
+            {
+                Mods =
+                [
+                    new OsuModHidden(),
+                    new OsuModFreezeFrame(),
+                ],
+                CreateBeatmap = () => new OsuBeatmap
+                {
+                    HitObjects =
+                    {
+                        new HitCircle { StartTime = 3000, Position = OsuPlayfield.BASE_SIZE / 2, NewCombo = true },
+                        new HitCircle { StartTime = 5000, Position = OsuPlayfield.BASE_SIZE / 2 },
+                    }
+                },
+                PassCondition = () => ((HitCircle)Player.GameplayState.Beatmap.HitObjects[1]).TimeFadeIn == 480
+            });
+        }
     }
 }

```

</details>

The reason that this is happening is a data dependency. Freeze Frame
modifies `TimePreempt` of hitobjects:


54c0b2c20c/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs (L53)

while Hidden uses `TimePreempt` to set `TimeFadeIn`:


54c0b2c20c/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs (L45)

Therefore the final value of `TimeFadeIn` with these two mods active
depends on the order of application.

The reason why I'm bothering to do this is that I was pinged from the PP
development server about this again in the context of some ongoing
'rework' and I wish to get ahead of this before it becomes a bigger
problem than it already is.

The current order of application of these mods as done in `Player` is
constant, but essentially undefined. I'm not even sure what even
enforces the current order. It's currently Hidden, then Freeze Frame. If
I were to guess, the thing "enforcing" (insert 400 tonne solid lead air
quotes) it is probably the mod select overlay with its "I need to own
all of the mod instances in the global bindable" substitution logic.

I'm already getting pushback for this from the PP server crowd who are
attempting to justify the current "behaviour" by saying that the player
base wants this or by saying that it's already broken so it should
remain that way forever. I am however not willing to accept
[stable-taiko-tier stupidity
again](https://github.com/ppy/osu/pull/27136#issuecomment-1957055402)
and am not willing to accept the complexity this would invite everywhere
else.

I do not see any other easy way of fixing this problem at this point in
time. I had hoped that I could inline the `TimePreempt` read in
`OsuModHidden`, but it's not that easy because it's set in multiple
places.

Existing HDFF scores would probably need to be delisted from the
leaderboards. I'm not even sure I can get myself to pretend to care.
2026-01-29 16:35:13 +09:00
Bartłomiej Dach
a53ba5e4ef Merge pull request #36517 from YHSabc233/localisation/editor-show-storyboard
Localise "Show storyboard" in `Editor`
2026-01-29 08:35:01 +01:00
Bartłomiej Dach
35b9c74cf8 Merge pull request #36516 from peppy/fix-beatmap-invalidation-F-A-I-L
Fix star ratings sometimes not updating after editing a beatmap
2026-01-29 08:31:56 +01:00
YHSabc233
64a29313a8 Localise "Show storyboard" in Editor 2026-01-29 02:07:46 +08:00
Dean Herbert
d5ef0d75fc Reorder strings and enums too for consistency 2026-01-29 02:42:28 +09:00
Dean Herbert
3b3bb266fc Rewrite everything for code quality's sake 2026-01-29 02:40:24 +09:00
Dean Herbert
487347dac6 Merge branch 'master' into cycle-skins 2026-01-29 02:19:36 +09:00
Dean Herbert
d7648afe96 Fix back-to-front ordering of keys in displays 2026-01-29 02:19:21 +09:00
Dean Herbert
c86f76b972 Fix obliteration of key bindings due to not reading above comment 2026-01-29 02:18:31 +09:00
Tim Oliver
8e5eed63e1 Update iOS app icon to iOS 26 Liquid Glass variants (#36510)
Removes the previous `AppIcon.appiconset` bundle and replaces it with
all of the necessary asset slices to enable all of the Liquid Glass
variants of the app icon on iOS 26, while also preserving backwards
compatibility with older iOS versions.

<img width="1164" height="388" alt="LiquidGlass"
src="https://github.com/user-attachments/assets/7d6e7a90-3fe5-4853-9c63-35144359f49e"
/>

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-29 02:12:41 +09:00
Dean Herbert
b705313d3f Fix BeatmapDifficultyCache's bindable tracking not correctly updating BeatmapInfo metadata on invalidation 2026-01-29 01:47:13 +09:00
Dean Herbert
5dd34f165f Add failing test coverage 2026-01-29 01:47:13 +09:00
Dean Herbert
10651512a5 Avoid triggering bindable updates if mods haven't actually changed 2026-01-29 00:28:58 +09:00
Dean Herbert
4c2ffa0f79 More aggressively cancel debounced tracked bindable updates
If we've run an update since we can cancel the scheduled debounce run.
2026-01-29 00:28:58 +09:00
Dean Herbert
6997f89698 Add assertion that we always get the up-to-date beatmap file in a WorkingBeatmap 2026-01-29 00:28:58 +09:00
Bartłomiej Dach
0ed4a8dbe5 Merge pull request #36511 from MayoCollector/localisation/sample-set-chooser
Localise "Custom sample sets" caption in `FormSampleSetChooser` dropdown
2026-01-28 14:48:37 +01:00
BoomboxRapsody
c47f9c5259 Localise "Custom sample sets" in FormSampleSetChooser dropdown 2026-01-28 22:06:54 +09:00
Bartłomiej Dach
a401c7d5e9 Merge pull request #36498 from smoogipoo/ranked-play-models
Add server-side models for ranked play
2026-01-28 11:31:57 +01:00
Bartłomiej Dach
6185a81bd5 Merge pull request #36504 from peppy/fix-double-checking-sounds
Fix `FormCheckbox` playing sounds twice
2026-01-28 11:07:17 +01:00
Dan Balasescu
6d54d20943 Apply default value changes from review 2026-01-28 17:45:15 +09:00
Bartłomiej Dach
02fbcaba23 Merge pull request #36500 from peppy/playlist-ssv2-all-mods-display
Fix "ALL MODS" display not displaying in new playlist song select
2026-01-28 09:39:35 +01:00
Dean Herbert
7b7777bb56 Fix FormCheckbox playing sounds twice
This removes the disabled sound, but I think that's fine. If we want
that, it should be handled by `HoverClickSounds` (which I'm currently
intentionally not using because it can be a bit noisy).

Closes #36503.
2026-01-28 16:55:43 +09:00
Dean Herbert
ca7b850c8c Remove leaking knowledge of freestyle in normal song select component 2026-01-28 16:37:39 +09:00
Bartłomiej Dach
88e5ac4834 Merge pull request #36499 from peppy/fix-dropdown-animations
Fix dropdown margins and animations being weird
2026-01-28 08:09:40 +01:00
Dean Herbert
b9d5606fd4 Limit maximum size of mod tooltip to avoid it going offscreen 2026-01-28 16:08:02 +09:00
Dean Herbert
c8c91cedfa Combine implementation of mods text drawable
I don't want to have to update things in multiple places with different
code in each place.

This also closes https://github.com/ppy/osu/issues/36412.
2026-01-28 16:02:14 +09:00
Dean Herbert
0c90cf3cef Fix mod count overlay flashing when switching freestyle on and off 2026-01-28 15:01:23 +09:00
Dean Herbert
1a0193001d Fix "ALL MODS" display not displaying in new playlist song select
Closes https://github.com/ppy/osu/issues/36411.
2026-01-28 14:42:41 +09:00
Dean Herbert
6bdb0e1cbb Fix dropdown margins and animations being weird
This was attempted to be fixed by frenzibyte using some hack workaround
logic, but this is the true fix.

Things were never matching due to `UpdateSize` spamming `Resize`
transforms every frame, causing the fade out to complete before
transforms have reached a final state.
2026-01-28 14:22:41 +09:00
Dean Herbert
0d3b7ab6be Remove workaround for dropdowns animating weirdly 2026-01-28 14:22:31 +09:00
Dan Balasescu
8202ad18d0 Add comments 2026-01-28 14:00:44 +09:00
Dan Balasescu
fa5a278cf3 Add ranked play match type 2026-01-28 13:42:59 +09:00
Dan Balasescu
70321e2f89 Add ranked play models 2026-01-28 13:42:59 +09:00
Dan Balasescu
c1fc1edd9c Add type parameter to pool retrieval method 2026-01-28 13:42:58 +09:00
Dan Balasescu
40e55ecb6e Add type to matchmaking pools 2026-01-28 13:38:40 +09:00
ArijanJ
4a5dbea2a2 Use ctrl-shift-E/T for shortcuts 2026-01-27 19:49:38 +01:00
Bartłomiej Dach
cffeb92248 Merge pull request #36486 from peppy/ui-tweaking
First pass adjustments to new settings design
2026-01-27 14:33:25 +01:00
Eeli Ogata
2c56419fe9 Fix panel expansion not being set on initial song select load (#36456)
Closes #36445.

Fixes a regression from #36404

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-27 14:32:51 +01:00
Bartłomiej Dach
add67b95c7 Apply extracted background in one more location 2026-01-27 12:09:31 +01:00
Dean Herbert
6fad798227 Add insult to injury for autosize workaround
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-01-27 19:58:45 +09:00
Dean Herbert
60690cbccc Add localisation support for "Device:" prefix 2026-01-27 19:03:23 +09:00
Dean Herbert
6329e3ee1b Add back FinishTransforms at what cost 2026-01-27 19:02:28 +09:00
Dean Herbert
fa22d1f202 Use enum for background states 2026-01-27 18:58:03 +09:00
Dean Herbert
12eeab581e Remove unnecessary depth change 2026-01-27 18:51:04 +09:00
Dean Herbert
b5e93b98c9 Fix mismatching spacing in dropdown form menus 2026-01-27 18:49:53 +09:00
Dean Herbert
786ea35274 Fix revert button not always matching control's size 2026-01-27 18:36:49 +09:00
Dean Herbert
d6bf4fd90d Fix border showing for inner text boxes incorrectly
I turned masking back on on these for better visuals (text masking
aligns with rest of elements) but turns out this implicitly makes
borders draw.
2026-01-27 18:36:37 +09:00
Dean Herbert
c407e07514 Adjust paddings to give more width to settings 2026-01-27 17:43:28 +09:00
Dean Herbert
ed0051d119 Adjust size and icon of revert-to-default button 2026-01-27 17:06:15 +09:00
Dean Herbert
99ea19d55c Make binding configuration button bigger
It's one of the more important sections so I want to make it easier to
find.
2026-01-27 17:06:14 +09:00
Dean Herbert
dba17b1fa6 Standardise hover sounds for form elements
Closes #36444.
2026-01-27 17:06:14 +09:00
Dean Herbert
fdf28474bf Add prefix for input device header 2026-01-27 17:06:13 +09:00
Dean Herbert
42dc73d849 Standardise animations 2026-01-27 17:06:13 +09:00
Dean Herbert
6983227240 Various metrics and visual tweaks 2026-01-27 17:06:13 +09:00
Dean Herbert
585ce682ef Fix button spacing being weirdly small 2026-01-27 17:06:12 +09:00
Dean Herbert
3db3b603bc Fix revert button height 2026-01-27 17:06:12 +09:00
Dean Herbert
1c537a3278 Make switch buttons look more like old version 2026-01-27 17:06:11 +09:00
Dean Herbert
c88f10ca1b Standardise background across form controls 2026-01-27 17:06:11 +09:00
Dean Herbert
7fef2ce1de Increase size of caption text 2026-01-27 03:04:45 +09:00
Dean Herbert
9a5fd0addb Remove enabled/disabled text from FormCheckbox 2026-01-27 03:04:45 +09:00
Dean Herbert
9c0b1a4914 Adjust tooltip response speed and avoid using per-frame transforms 2026-01-27 03:04:45 +09:00
Dean Herbert
acdb4477f7 Fix logs failing to export after multiple failure attempts on file locks (#36469)
Even if one file fails, we usually don't care and still want the archive
to finish exporting.

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

---------

Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-01-26 10:10:04 +01:00
Dean Herbert
4ff29339ed Merge pull request #36471 from peppy/fix-previous-username-depth
Fix previous usernames display showing underneath other elements
2026-01-26 10:09:39 +01:00
Dean Herbert
f1f4a0001b Apply new inspections from 2026.1EAP1
Nothing really egregious here so not bothering with PR review. One dodgy
bug which has been
[reported](https://youtrack.jetbrains.com/issue/RIDER-135036/Incorrect-recursive-on-all-execution-paths-inspection)
and temporarily ignored.
2026-01-26 15:12:52 +09:00
StanR
df1dc46603 Move Traceable to difficulty increasing mods section (#35500)
TC is a mod that always increases difficulty and is quite similar to HD.
Given we even have diffcalc/pp considerations for it it's time to move
it to the category it belongs.

This doesn't cover any other mods that might need reshuffling too
because TC is the only one that has actual impact on difficulty-based
leaderboards (as in pp) and some people are actively playing it for the
difficulty increase and not just as a fun gimmick.

After a quick search turns out it was difficulty increasing from the
start but was moved to fun in review
https://github.com/ppy/osu/pull/3569#discussion_r300085523 but I don't
really agree with that.

Also as far as I know multimods don't do anything anymore?.. I've put it
into HD multimod for consistency, but can move it to be separate if you
want

Co-authored-by: Dan Balasescu <smoogipoo@smgi.me>
2026-01-25 20:30:01 +09:00
Denis Titovets
84ec4bb866 Fix score tooltips being displayed when hovering freemods status bar on PlaylistsSSV2 (#36413)
- similar to https://github.com/ppy/osu/pull/36332
2026-01-24 00:10:04 +09:00
Dean Herbert
9f0f9ef229 Merge pull request #36438 from bdach/bypass-test-fails-slider-bar
Work around flaky `TestSceneFirstRunSetupOverlay` tests
2026-01-24 00:01:56 +09:00
Dean Herbert
290b141d8f Merge pull request #36439 from bdach/late-firing-realm-subs
Locally schedule beatmap skin change callbacks to ensure they fire at valid times
2026-01-23 23:58:13 +09:00
Bartłomiej Dach
7cc025d8f4 Merge pull request #36436 from peppy/legacy-health-wrong-flash-texture
Fix legacy health display using incorrect bulge texture when at low HP
2026-01-23 14:01:58 +01:00
Bartłomiej Dach
978fc91b09 Locally schedule beatmap skin change callbacks to ensure they fire at valid times
See CI failures like
https://github.com/ppy/osu/actions/runs/21238110652/job/61110112412?pr=36404#step:5:21.

Hopefully works this time.
2026-01-23 13:41:44 +01:00
Bartłomiej Dach
259c5708f1 Add some more extra test coverage 2026-01-23 13:18:48 +01:00
Bartłomiej Dach
b7559f93f2 Work around flaky TestSceneFirstRunSetupOverlay tests
See inline commentary. I don't really have any energy left to provide
anything else, other than maybe a demonstration of how this dies in
framework:

diff --git a/osu.Framework.Tests/Visual/UserInterface/TestSceneScreenStackUnbindOnExit.cs b/osu.Framework.Tests/Visual/UserInterface/TestSceneScreenStackUnbindOnExit.cs
new file mode 100644
index 000000000..c74ce6636
--- /dev/null
+++ b/osu.Framework.Tests/Visual/UserInterface/TestSceneScreenStackUnbindOnExit.cs
@@ -0,0 +1,59 @@
+// 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 NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Screens;
+
+namespace osu.Framework.Tests.Visual.UserInterface
+{
+    public partial class TestSceneScreenStackUnbindOnExit : FrameworkTestScene
+    {
+        [Cached]
+        private ScreenStack screenStack = new ScreenStack();
+
+        [Test]
+        public void TestScreenExitUnbindDoesNotInterruptLoadComplete()
+        {
+            AddStep("set up the scenario", () =>
+            {
+                Child = screenStack;
+                screenStack.Push(new Screen());
+                screenStack.Push(new BrokenScreen());
+            });
+            AddUntilStep("wait to get to target screen", () => screenStack.CurrentScreen, Is.InstanceOf<Screen>);
+        }
+
+        private partial class BrokenSlider : BasicSliderBar<float>
+        {
+            [Resolved]
+            private ScreenStack screenStack { get; set; } = null!;
+
+            protected override void LoadComplete()
+            {
+                // exiting the current screen provokes the behaviour of unbinding all bindables in the screen's subtree
+                screenStack.CurrentScreen.Exit();
+
+                // ...but the following calls should still take correct effect inside `SliderBar`
+                // (namely one consisting of propagating `{Min,Max}Value` into `currentNumberInstantaneous`)
+                // so that it doesn't have its internal invariants violated
+                CurrentNumber.MinValue = -10;
+                CurrentNumber.MaxValue = 10;
+
+                // this notably calls `Scheduler.AddOnce(updateValue)` inside, which will happen *in the imminent future, in the same frame as `LoadComplete()` here.
+                // if the above mutations of `{Min,Max}Value` don't correctly propagate inside the slider bar due to an overly eager unbind, this will cause a crash.
+                base.LoadComplete();
+            }
+        }
+
+        private partial class BrokenScreen : Screen
+        {
+            [BackgroundDependencyLoader]
+            private void load()
+            {
+                InternalChild = new BrokenSlider();
+            }
+        }
+    }
+}

I attempted to address what I perceive to be the root issue here which
is that `ScreenStack` is allowed to arbitrarily unbind bindables under
drawables which are by all means still in the scene graph. The attempt
consisted of scheduling the unbind until after children of the screen
stack, but that caused 150 game-side tests to fail, seemingly on
something relevant to bindable leases, so I give up.
2026-01-23 13:07:42 +01:00
Dean Herbert
c2604e22c7 Update resources 2026-01-23 17:44:17 +09:00
Dean Herbert
dddd75b7f9 Merge pull request #36435 from bdach/sigh
Fix broken percentage formatting in form slider bars
2026-01-23 17:17:20 +09:00
Dean Herbert
d3c9548b52 Fix legacy health display using incorrect bulge texture when at low HP
Closes #36432.
2026-01-23 17:10:35 +09:00
Bartłomiej Dach
225f4d8814 Fix broken percentage formatting in form slider bars
closes https://github.com/ppy/osu/issues/36428

this one's my bad:
https://github.com/ppy/osu/pull/36195#discussion_r2698388405
2026-01-23 08:01:41 +01:00
Bartłomiej Dach
d80934c344 Add failing tests 2026-01-23 07:50:20 +01:00
Dean Herbert
6f038bff48 Merge pull request #36392 from iwa/feat/numeric-hotkeys-for-presets-mod-select
Mod Select: Support numeric row hotkeys to quick select Presets
2026-01-23 03:28:52 +09:00
Dean Herbert
98c6f6afcd Add test coverage 2026-01-23 01:13:49 +09:00
Bartłomiej Dach
ff28839a09 Merge pull request #36426 from peppy/disable-sentry-envvar
Add envvar to disable error reporting
2026-01-22 13:07:19 +01:00
Bartłomiej Dach
52d5c986ef Fix wrong type in enabled check 2026-01-22 12:57:47 +01:00
Dean Herbert
dd9e70b29c Merge pull request #36193 from frenzibyte/new-settings/overlay
Update settings to use new "form" style controls
2026-01-22 20:27:16 +09:00
Dean Herbert
04e378c09f Add visual hinting of keyboard shortcuts 2026-01-22 20:24:10 +09:00
Dean Herbert
d4cf46e3cd Fix some intermittent test failures 2026-01-22 19:25:25 +09:00
Dean Herbert
42302c45ec Merge branch 'master' into new-settings/overlay 2026-01-22 18:38:17 +09:00
Denis Titovets
e2dd4d86b4 Add localisation support for PlaylistsSongSelectV2 (#36410)
| master | pr |
|-|-|
| <img width="691" height="84" alt="osu_2026-01-20_18-16-38 — копия"
src="https://github.com/user-attachments/assets/24e24131-525b-4603-b6f7-dbdd6e8be188"
/> | <img width="694" height="76" alt="osu_2026-01-20_18-12-45 — копия"
src="https://github.com/user-attachments/assets/d880b9c8-8a69-494e-863f-170f904a71b2"
/> |
| <img width="581" height="191" alt="osu_2026-01-20_18-16-38"
src="https://github.com/user-attachments/assets/01256367-3275-40c3-9da2-0073e4e33a1d"
/> | <img width="570" height="184" alt="osu_2026-01-20_18-12-45"
src="https://github.com/user-attachments/assets/a9b2ce0a-b571-4f94-bf0e-7869bd32e6ae"
/> |
2026-01-22 18:18:02 +09:00
Dean Herbert
6693307064 Add envvar to disble error reporting
https://github.com/ppy/osu/discussions/31832#discussioncomment-15555080
2026-01-22 18:12:27 +09:00
Bartłomiej Dach
f0e7817dda Fix beatmap samples with incorrect 1 sample set suffix in the filename being shown in setup tab as belonging to custom sample bank 1 (#36425)
To explain on the wordy and probably incoherent title: The patient zero
for this was the following discord report:
https://discord.com/channels/188630481301012481/1097318920991559880/1463029073998774375

After information extraction, it turned out that the user manually used
the "Edit externally..." feature to rename a sample to
`normal-hitnormal1.mp3`, thinking (logically, to be fair), that the 1
bank works the same way that all the others do.

It doesn't, samples in the 1 bank do not have a numerical suffix in the
filename - but the logic retrieving the sample sets to display in the
setup tab was not checking that, leading to confusion wherein a sample
would only "work" in the setup tab but not in the actual editor
composer.

Can be tested with [the beatmap provided by the
user](https://discord.com/channels/188630481301012481/1097318920991559880/1463110516573470774).
2026-01-22 18:05:29 +09:00
Bartłomiej Dach
a1d325370c Merge pull request #36423 from peppy/standardise-ruleset-failure-logging
Standardise ruleset error logging to always include exception in logs
2026-01-22 08:59:18 +01:00
Dean Herbert
1e8ffdf128 Fix weird typo brain turned off 2026-01-22 16:43:46 +09:00
Bartłomiej Dach
ea0b281f48 Merge pull request #36404 from peppy/fix-carousel-thing
Fix random selection not showing selection when all groups are collapsed
2026-01-22 08:24:03 +01:00
Dean Herbert
fdd13cd7e1 Standardise ruleset error logging to always include exception in logs
Supersedes and closes https://github.com/ppy/osu/pull/36420.
2026-01-22 15:48:51 +09:00
Dean Herbert
6354286452 Simplify logic further and fix regressing case 2026-01-22 14:59:42 +09:00
Dean Herbert
6f146a5ce9 Add failing test case showing visual state desync 2026-01-22 14:59:41 +09:00
Dean Herbert
5d651628bc Merge branch 'master' into fix-carousel-thing 2026-01-22 01:55:28 +09:00
Dean Herbert
10dc1314f6 Fix carousel items becoming incorrectly selected due to bindable leakage (#36414)
As discussed in discord. Fixed from multiple angles.

---------

Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-01-22 01:06:40 +09:00
iwa
ce2d54f118 refactor: move presets hotkey logic inside ModPresetColumn class 2026-01-20 22:22:10 +01:00
iwa
042f716b2a revert: changes made for preset hotkeys in SequentialModHotkeyHandler 2026-01-20 22:21:21 +01:00
iwa
0ea060c612 revert: remove IPresetHotkeyHandler 2026-01-20 22:20:54 +01:00
ArijanJ
ea8788a509 Simplify cycleSkins, fix some logic and naming mistakes 2026-01-20 21:47:34 +01:00
Dean Herbert
46b2d5374e Refactor HandleFilterCompleted to (hopefully) be easier to parse
This is not required to fix the issue, but it is required for my brain
to follow the method to some degress.
2026-01-20 21:12:49 +09:00
Dean Herbert
8860eec9f9 Handle expand set logic locally rather than calling HandleItemSelected
This avoids the implicit group expansion happening that the added code
was attempting to fix.
2026-01-20 21:12:49 +09:00
Dean Herbert
8c86ff36a2 Revert "Do not forcibly re-expand carousel groups on refilters if the user manually collapsed them"
This reverts commit bc4d5d07d7.
2026-01-20 21:12:49 +09:00
Dean Herbert
fdf9092f41 Revert "Fix current beatmap set being incorrectly expanded after collapsing group with current selection"
This reverts commit 9ba9966078.
2026-01-20 21:12:48 +09:00
Dean Herbert
76f05a4837 Add failing test showing incorrect behaviour on random select with collapsed groups 2026-01-20 21:12:48 +09:00
Bartłomiej Dach
ae1402c9cd Merge pull request #36401 from peppy/fix-skin-save-crash
Fix skin saving crashing if hashable files are not present
2026-01-20 11:04:23 +01:00
Dean Herbert
741620d89c Fix skin saving crashing if hashable files are not present
This ends up with a bit of an undefined behaviour, but it's already a
bit of an edge case (files missing in the `files` folder that are
references in the database).

First and foremost, let's stop the exception. If we allow it to throw,
it's impossible to exit the skin editor in this state.

Closes https://github.com/ppy/osu/issues/36135.
2026-01-20 17:41:10 +09:00
Bartłomiej Dach
4ee4aac708 Fix changing combo colours in beatmap without custom samples opening new sample set popover (#36400)
Reported [on reddit of all
places](https://www.reddit.com/r/osugame/comments/1qhnfdn/every_time_i_make_an_adjustment_to_the_hitcircle/).

The reason that this is happening is as follows:

- Changing a combo colour raises `BeatmapSkinChanged`
- `BeatmapSkinChanged` getting raised triggers the sample chooser
dropdown to repopulate its items (as intended and correctly)
- Setting items of a dropdown can also change its `Current.Value`,
because the relevant logic attempts to ensure that `Current.Value` is
valid in line with the new items
- Therefore the `Current.Value` of the dropdown changes from `null` to
sample set `-1` which corresponds to the "Add new..." item as it's the
only item in the dropdown...
- which is indistinguishable from the sequence of events that happens if
the user manually opens the dropdown and clicks the "Add new..." item.

This change sidesteps this entire car crash by just ensuring that even
beatmaps without custom samples have at least set number 1 initialised
(even if it's empty and has no samples). This means that the initial
value of the dropdown is never `null`, and that every time that the
value changes to the set `-1` it actually is due to user action.

Should have known better than to play these dumb games.
2026-01-20 17:10:40 +09:00
Linus Genz
dfa7ac2082 Specialise mod setting hover text in song select scoreboard (#36391)
- resolves #35992

**Changes**

Introduced GetSettingTooltipText, which returns the value of the
respective setting. The function can be overwritten, allowing to
implement specific behavior. This allows you to define that a value of 0
for the “Muted” mod will instead display “always muted.”
In the same step, I also adjusted the "NoScope" mod, where we had the
same problem.
Wherever we want to implement specialization like this, we can simply
overwrite GetSettingTooltipText to customize the behavior for the mod
settings of the mod.

**Result**
<img width="2560" height="1440" alt="2026-01-19-122307_hyprshot"
src="https://github.com/user-attachments/assets/20e3aa9a-aa6f-4284-9cf1-3092f52c021d"
/>
<img width="2560" height="1440" alt="2026-01-19-122324_hyprshot"
src="https://github.com/user-attachments/assets/6f3fac5b-2a5d-4dd9-a56c-4b09c02cbcca"
/>
<img width="2560" height="1440" alt="2026-01-19-155307_hyprshot"
src="https://github.com/user-attachments/assets/f9ee75d3-c200-4536-9ee9-d20ddbd9fa44"
/>

Signed-off-by: Linus Genz <linuslinuxgenz@gmail.com>
2026-01-20 16:51:23 +09:00
iwa
2a0bafde8c fix: align OnKeyDown condition with existing from ModColumn 2026-01-19 22:07:32 +01:00
iwa
91ee5eebc9 feat: add logic to handle numeric hotkeys to select presets from mod select overlay 2026-01-19 17:15:15 +01:00
iwa
6bf95068ae feat: expose a public Toggle method for ModPresetPanel 2026-01-19 17:14:34 +01:00
iwa
6d999a8d8e refactor: rename HandleHotkeyPressed to HandleModHostkeyPressed to differentiate with presets handler 2026-01-19 17:14:02 +01:00
Bartłomiej Dach
c1d9de7e83 Fix sample set index entry box crashing on bad input (#36390)
closes https://github.com/ppy/osu/issues/36374
2026-01-19 22:21:20 +09:00
ArijanJ
763dbe1494 Add blank line for codeinspect 2026-01-19 13:34:25 +01:00
ArijanJ
65f7037e84 Add skin cycling with shortcuts for next and previous skin 2026-01-19 12:59:21 +01:00
Dan Balasescu
e62a01cf77 Add metadata endpoint to refresh friend listing (#36386)
Alternative to / closes https://github.com/ppy/osu/pull/36341
See also: https://github.com/ppy/osu-server-spectator/pull/415

This is a simple solution by adding a spectator endpoint to refresh the
friend listing. A more complicated form of this is to make
adding/removing friends only via spectator, but that would require
osu-web changes too.
2026-01-19 18:34:00 +09:00
Bartłomiej Dach
a60f262679 Remove mention of no-longer-existent "good first issue" label
It doesn't work in practice, because the skill baseline of an incoming
"contributor" is so wildly variant that any issue that isn't explicitly
a one-liner is automatically not suitable for *some* non-trivial subset
of "new contributor".

The label is also largely used by incoming contributors whose interests
are not necessarily aligned with the project but instead appear to have
other ulterior motives.
2026-01-19 09:26:22 +01:00
Dean Herbert
c0b644c905 Fix osu! logo appearing in at new playlist song select screen after opening mod select (#36385)
Closes https://github.com/ppy/osu/issues/36363.
2026-01-19 16:55:39 +09:00
MayoCollector
cf73f8f9e6 Localise "hold for menu" & "press for menu" in HoldForMenuButton (#36381) 2026-01-19 14:39:21 +09:00
Joseph Madamba
7608ed4d87 Remove now unnecessary mobile hold hack when song select v2 wasn't default (#36384)
This reverts commit 3931ae3499.
2026-01-19 13:31:48 +09:00
Denis Titovets
eee88a3955 Fix score tooltips being displayed when hovering mod status bar (#36332)
- addresses https://github.com/ppy/osu/discussions/34079
- supersedes and closes https://github.com/ppy/osu/pull/34090
2026-01-17 23:15:46 +09:00
Salman Alshamrani
676b7a36da Improve input handling in percentage-based slider bars (#36195)
Reported in
https://github.com/ppy/osu/pull/36193#issuecomment-3703406223.

Preview:


https://github.com/user-attachments/assets/ac2b86cf-ad92-496b-b3dd-19ad47753a9b

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-17 16:39:28 +09:00
Salman Alshamrani
b5a989d31e Fix form dropdown open animation not being smooth (#36358)
Preview:


https://github.com/user-attachments/assets/07cb58b7-5980-4fed-bb4c-2443ba1e9635
2026-01-17 02:54:12 +09:00
Dean Herbert
a6489cd758 Merge pull request #36190 from bdach/add-custom-samples-via-setup
Add way to add/remove custom beatmap samples to setup screen
2026-01-17 01:55:59 +09:00
Krzysztof Gutkowski
952fd0d493 Ensure diffcalc runs after mods get replaced during a ruleset change (#36359) 2026-01-16 16:38:00 +01:00
Denis Titovets
06b89919be Add localisation support for some more notifications (#36353)
Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-16 22:58:20 +09:00
Dean Herbert
e1bde264bc Merge branch 'master' into add-custom-samples-via-setup 2026-01-16 20:11:28 +09:00
De4n
e05b6f44b9 Update editor slider controls to new design (#36346)
(partially) Closes: #36233
Surpasses: #36244 

This PR meant to be one of the last steps that finally make editor use
the new forms. Initially it meant to only change one
SliderWithTextBoxInput in "Effects section" in timing screen, however
soon after it was obvious that there's many other places that still
using it. This currently won't affect
IndeterminateSliderWithTextBoxInput that is being used in hitsounds, for
example, since I think it needs more consideration.
Anyways, with this PR, SliderWithTextBoxInput, will no longer be used at
all, as it's going to be replaced with modern FormSliderBar

Comparison:
|master|this PR|
|:---:|:---:|
|<img width="510" height="316"
alt="532203751-eb965923-d3a8-441d-a7c8-5c364a6328ad"
src="https://github.com/user-attachments/assets/268b45b8-e235-494f-91a5-d00db057dba8"
/>|<img width="540" height="321"
alt="535466527-3a700a8b-bc3c-4610-998f-a4e55ee03eed"
src="https://github.com/user-attachments/assets/20cd4b58-b0bd-49bc-8c48-7de5cf8556b3"
/>|
|<img width="694" height="639"
alt="534509844-f00e4da4-53c4-45e8-80ea-1be62da6c83b"
src="https://github.com/user-attachments/assets/398c4484-a867-4df1-9de3-0940aa748a01"
/>|<img width="720" height="433" alt="изображение"
src="https://github.com/user-attachments/assets/b6359443-a224-4a55-b171-07e8f013cf46"
/>|
|<img width="715" height="353"
alt="534509421-a6ac950f-16e8-4a16-bca6-1a781f82135f"
src="https://github.com/user-attachments/assets/4854312b-772f-4b81-a800-89e58d4c715d"
/>|<img width="710" height="296" alt="изображение"
src="https://github.com/user-attachments/assets/a7fed53e-e006-4285-92c9-bb84cb603f60"
/>|
|<img width="717" height="374"
alt="534509478-80222623-7766-481d-8682-088276d415ee"
src="https://github.com/user-attachments/assets/8143b6dc-4599-45d5-bd3b-f059caf3d93d"
/>|<img width="718" height="328" alt="изображение"
src="https://github.com/user-attachments/assets/bffa04de-983c-45ae-a1ec-373701ea0e49"
/>|
|<img width="702" height="446"
alt="534509935-58954060-7ac1-4392-8754-a58f909e86aa"
src="https://github.com/user-attachments/assets/2bb67a2d-3f57-42a1-96ce-b30b4891e1a4"
/>|<img width="722" height="386" alt="изображение"
src="https://github.com/user-attachments/assets/01b7fff4-7f31-4aac-90c9-353b15f4964e"
/>|
2026-01-16 20:08:52 +09:00
Joseph Madamba
a8ada50549 Fix double-clicking form slider bar not propagating default to other bindables when TransferValueOnCommit is true (#36354)
- Addresses https://github.com/ppy/osu/pull/36346#discussion_r2692322683

The inner slider bar binds its `Current` to
`currentNumberInstantaneous`:


1add946db4/osu.Game/Graphics/UserInterfaceV2/FormSliderBar.cs (L225-L236)

But the current bindable of the form component doesn't update because of
this.


1add946db4/osu.Game/Graphics/UserInterfaceV2/FormSliderBar.cs (L285-L293)

Fixed it by just moving the `ResetToDefault` action up another level.

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-16 19:48:36 +09:00
Bartłomiej Dach
1add946db4 Merge pull request #36350 from peppy/toast-adjust
Fix toasts showing "no key bound" for operations which can't have keys bound
2026-01-15 13:06:33 +01:00
Bartłomiej Dach
a2ca650a9f Merge pull request #36349 from peppy/spectator-connection-disconnect-notify
Fix notification spam on websocket connection handshake failures
2026-01-15 13:06:19 +01:00
Dean Herbert
cd433fea50 Fix weirdly defined constant 2026-01-15 19:01:32 +09:00
Dean Herbert
a6756157d1 Update tablet area selection to match new design 2026-01-15 18:54:01 +09:00
Dean Herbert
367d133d2f Avoid requiring private variables to set ApplyClassicDefault settings 2026-01-15 18:42:57 +09:00
Dean Herbert
1313883394 Scope player handling to specific screens which have issues 2026-01-15 18:09:04 +09:00
Dean Herbert
e8154080b3 Stop websocket handshake failures from being shown to users 2026-01-15 18:09:04 +09:00
Dean Herbert
b4ba327c1c Fix toasts showing "no key bound" for operations which can't have keys bound
Supersedes and closes https://github.com/ppy/osu/pull/35781.
Closes https://github.com/ppy/osu/issues/36294.
2026-01-15 17:52:30 +09:00
Dean Herbert
c646b4e5ec Alert when spectator server disconnects during gameplay
This can cause issues liek loss of replays, so it's worth notifying the
user and keeping things visible.
2026-01-15 17:14:56 +09:00
Dean Herbert
15cb3b7a27 Use same message for multiplayer disconnects to simplify things further 2026-01-15 17:11:44 +09:00
Dean Herbert
0551c75c6b Adjust API disconnection text to be usable in more scenarios 2026-01-15 17:11:42 +09:00
Dean Herbert
2bf0dcf398 Adjust friend notification logic to fix a few flaws (#36348)
Just a couple of things I noticed in passing:

- When changing the configuration setting, things were not reset.
Likewise, if the setting was off the queues would still be added to but
never flushed.
- When the setting is toggled, a stale next notification time was still
present due to the `??=` and lack of resetting. This should no longer be
the case.
2026-01-15 16:31:15 +09:00
De4n
3302e2e180 Use new star rating text gradient for the difficulty name, "mapped by" text and difficulty bars (#36345)
Fixes: #36312

I think that's exactly what needed to be done to fix this issue.

|master|this PR|
|:---:|:---:|
|<img width="943" height="272" alt="изображение"
src="https://github.com/user-attachments/assets/e6fb57bd-8393-4476-ac73-a8b559365e6d"
/>|<img width="950" height="270" alt="изображение"
src="https://github.com/user-attachments/assets/e09de911-0068-4a8b-9abb-f2aa04a87886"
/>|
|<img width="943" height="274" alt="изображение"
src="https://github.com/user-attachments/assets/637a86f5-ad26-441d-8fa2-bdf113bb636d"
/>|<img width="936" height="272" alt="изображение"
src="https://github.com/user-attachments/assets/d72f52a1-6c17-4156-a4eb-cca36e74f644"
/>|
|<img width="940" height="271" alt="изображение"
src="https://github.com/user-attachments/assets/cf6a5f18-34c8-4f51-867a-ba1fc30b64a5"
/>|<img width="941" height="270" alt="изображение"
src="https://github.com/user-attachments/assets/e21cda45-1a69-4623-b9a7-add3eb7c7013"
/>
|<img width="946" height="275" alt="изображение"
src="https://github.com/user-attachments/assets/e29647bb-c4aa-4d03-a46d-3bbcd43181b6"
/>|<img width="932" height="271" alt="изображение"
src="https://github.com/user-attachments/assets/1f777db2-d0f9-4c2a-91fa-e005b9704c9a"
/>

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-15 16:00:27 +09:00
Dean Herbert
79f1d77fed Fix copy paste failure in MultiplayerMatchSettingsOverlay 2026-01-14 20:02:11 +09:00
Dean Herbert
91718447db Merge pull request #36324 from frenzibyte/better-form-button
Update form button UI/UX and support text wrapping
2026-01-14 19:47:50 +09:00
Dean Herbert
3f92b451d9 Use foreach isntead of ForEach 2026-01-14 19:37:51 +09:00
Dean Herbert
ed091dc9cd Adjust toggleable subsection colour to always be bright when enabled 2026-01-14 02:15:10 -05:00
Dean Herbert
029d544720 Adjust switch buttons to make the state more obvious 2026-01-14 02:15:10 -05:00
Salman Alshamrani
876dcd060c Reduce supporter note to informational 2026-01-14 02:15:10 -05:00
Salman Alshamrani
b9a37453f9 Shorten "increase first object visibility" label text 2026-01-14 02:15:10 -05:00
Salman Alshamrani
c5a30d3244 Remove unnecessary classic default specification
Background blur is disabled by default.
2026-01-14 02:15:10 -05:00
Salman Alshamrani
96c414be86 Adjust audio offset controls to match design language 2026-01-14 02:15:10 -05:00
Salman Alshamrani
30a60d83e2 Allow configuring settings note text anchor 2026-01-14 02:15:10 -05:00
Salman Alshamrani
ed760e6389 Update keybind settings to use new revert button 2026-01-14 02:15:10 -05:00
Salman Alshamrani
5d9ea9d699 Rewrite input settings and use new form controls 2026-01-14 02:15:10 -05:00
Salman Alshamrani
874e3adcb7 Update layout settings section to use new controls 2026-01-14 02:15:10 -05:00
Salman Alshamrani
e548cd40dc Update game settings to use new form controls 2026-01-14 02:15:10 -05:00
Salman Alshamrani
7ea1bbf91e Introduce and use constants and classes for new settings overlay 2026-01-14 02:15:07 -05:00
Salman Alshamrani
27abce74ce Allow dynamically configuring dropdown hint text
Used for "confine mouse mode" dropdown tooltip text.
2026-01-14 02:12:53 -05:00
Salman Alshamrani
8a581f5a90 Fix sliders not playing samples on adjust
Should've been true by default, minor mistake from a previous PR.
2026-01-14 02:12:28 -05:00
Salman Alshamrani
3f4d1b798e Update button background colour in update function 2026-01-14 01:34:20 -05:00
Dean Herbert
d1a231cacf Merge pull request #36328 from bdach/hub-connector-fluff
Clean up `HubClientConnector` configuration
2026-01-13 20:17:41 +09:00
Bartłomiej Dach
9c8d6e63a7 Simplify proxy configuration
More clean-up.
2026-01-13 11:16:20 +01:00
Bartłomiej Dach
5abc0f93fe Remove no longer needed header alias for version hash
Clean-up from an old change (see
https://github.com/ppy/osu/pull/28892#discussion_r1681136250).
2026-01-13 11:12:03 +01:00
Bartłomiej Dach
d5aa5b61ad Replace manual specification of Authorization header with SignalR-provided provider property
The property used here is listed in SignalR documentation:

	https://learn.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-10.0#bearer-token-authentication

While in practice this probably has zero bearing on anything,
theoretically the way proposed in this commit is more correct.
As the documentation states, with some transports the token may need to
be renewed if it expires, which providing it via a header as done
previously would not achieve, while going through `API.AccessToken`
every time will perform a token refresh if one is needed.
2026-01-13 11:03:59 +01:00
Dean Herbert
f9e70f06b3 Merge pull request #35117 from smoogipoo/new-playlists-song-select
Use new song select (v2) for playlists
2026-01-13 17:38:03 +09:00
Dean Herbert
363b7cf3cb Merge branch 'master' into new-playlists-song-select 2026-01-13 17:04:42 +09:00
Dean Herbert
eeb4680795 Remove unused button 2026-01-13 16:57:50 +09:00
Salman Alshamrani
f892d5fbaa Improve form dropdown UX (#36325)
Addresses concerns in
https://github.com/ppy/osu/pull/36193#issuecomment-3728177951 (excluding
the last part, that is too involved and I can't imagine any workaround
for it due to how strict the `Dropdown` structure is). Also adds
truncation/padding to header label and search bar.

Preview:


https://github.com/user-attachments/assets/8885cb90-44dc-42ee-af21-cb33f7723e63
2026-01-13 16:20:03 +09:00
Salman Alshamrani
0ba4e9e2a4 Fix mod footer button with unranked badge not resizing on localisation changes (#33810)
- Closes https://github.com/ppy/osu/issues/33789
2026-01-13 16:13:00 +09:00
Dean Herbert
8de5726aa0 Merge pull request #36301 from diquoks/localisation/osu-game-notifications
Localise some more notification/updater strings
2026-01-13 16:11:46 +09:00
Dean Herbert
d3ed93280a Make error message string construction actually understandable 2026-01-13 16:10:57 +09:00
Denis Titovets
37257a7a02 Make edits based on reviews 2026-01-13 07:47:25 +03:00
Salman Alshamrani
df1304af9e Add visual test 2026-01-12 23:38:17 -05:00
Salman Alshamrani
18fd4758d7 Update form button UI/UX and support text wrapping 2026-01-12 23:38:17 -05:00
Dean Herbert
9acc632788 Merge pull request #36319 from Joehuu/fix-plural-skins-keyword
Fix skin section buttons disappearing when searching for plural "skins"
2026-01-13 10:21:52 +09:00
Dean Herbert
eb1417696a Merge pull request #36252 from UltraDrakon/hide-cursor-during-background-reveal
Hide cursor during background reveal in song select
2026-01-13 09:41:03 +09:00
Joseph Madamba
5de23e41cf Fix skin section buttons disappearing when searching for plural "skins" 2026-01-12 14:23:19 -08:00
UltraDrakon
5899800293 Merge branch 'master' into hide-cursor-during-background-reveal 2026-01-12 18:30:35 +01:00
Denis Titovets
b15b4e70a5 Merge branch 'localisation/perform-from-menu-runner-notification' into localisation/osu-game-notifications
# Conflicts:
#	osu.Game/Localisation/NotificationsStrings.cs
2026-01-12 19:01:06 +03:00
Denis Titovets
40d8fb6316 Merge branch 'localisation/update-manager' into localisation/osu-game-notifications
# Conflicts:
#	osu.Game/Localisation/NotificationsStrings.cs
2026-01-12 19:00:19 +03:00
Denis Titovets
a8989eb117 Expand settings in ReplayPlayer by default (#36308)
~i recently saw an suggestion to do this, but don't remember where~

- addresses https://github.com/ppy/osu/discussions/36189

i think it's logical, since the settings have been displayed in a
separate overlay for more than six months, and not on top of the
gameplay itself, and for example, it can be difficult to expand section
on phones

| master | pr |
|-|-|
| <img width="1920" height="1080" alt="osu_2026-01-12_09-40-23"
src="https://github.com/user-attachments/assets/35d15ce6-ce12-4a9a-be4e-d72043dfb91a"
/> | <img width="1920" height="1080" alt="osu_2026-01-12_09-39-40"
src="https://github.com/user-attachments/assets/225d75db-1719-48dc-a65f-16272cca8295"
/> |
2026-01-13 00:03:20 +09:00
Linus Genz
a81a77c60f Fix underline size at song select details panel not matching after changing language (#36303)
Fixes #36274 

**Change:**
Registered a `BindValueChanged` callback on each TabItem’s
`Text.Current` to ensure the underline indicator (strip) updates
whenever the displayed tab text changes and calling `updateDisplay`
accordingly to update the underline.

**Result:**


https://github.com/user-attachments/assets/6fb95a46-c768-46ec-a68a-a5e394e08a78

---------

Signed-off-by: Linus Genz <linuslinuxgenz@gmail.com>
Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-12 23:40:13 +09:00
Dean Herbert
4726489dba Merge pull request #36311 from bdach/freeze-frame-suppresses-skips
Fix Freeze Frame mod suppressing skip if the first object is a spinner
2026-01-12 21:52:55 +09:00
Bartłomiej Dach
38c89a914b Fix Freeze Frame mod suppressing skip if the first object is a spinner
Fixes https://osu.ppy.sh/community/forums/topics/2169899?n=1.

`TimePreempt` doesn't affect the appearance of a spinner, but it *will*
affect the value of `GameplayStartTime`:

	4bf90a5571/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs (L82-L91)

While at parsing it is enforced that every object following a spinner
has `NewCombo` set, it is *not* enforced that every spinner has
`NewCombo` set. See also: https://github.com/ppy/osu/issues/24156.

But that's sort of orthogonal to the entire issue as well because why
touch the preempt of an object that's not visually affected by preempt
to begin with.
2026-01-12 11:11:38 +01:00
Bartłomiej Dach
57f16646a3 Add failing tests 2026-01-12 11:11:11 +01:00
Dean Herbert
9bad2c634b Merge pull request #36309 from bdach/broken-formatting
Fix broken date formatting in some languages on several overlays
2026-01-12 18:32:37 +09:00
Bartłomiej Dach
ae284fcf05 Fix broken date formatting in some languages on several overlays
Fixes https://osu.ppy.sh/community/forums/topics/2169438?n=1.
2026-01-12 09:34:53 +01:00
Denis Titovets
8a21c6814c Localise notification in OsuGame 2026-01-11 16:53:44 +03:00
Denis Titovets
f320592229 Localise notification in PerformFromMenuRunner 2026-01-11 16:17:09 +03:00
Denis Titovets
ee5cf25628 Localise notifications in MobileUpdateNotifier and NoActionUpdateManager 2026-01-11 15:58:59 +03:00
StanR
3e7f0f4c61 Add star rating text gradient (#36292)
Implements https://github.com/ppy/osu-web/pull/12363

There's one less colour in the spectrum than in the [web
code](https://github.com/ppy/osu-web/pull/12363/changes#diff-a9bdefd7233ca98f7f89cd76213aba5d869ae0424c8e79d1e322abd3e43462fbR31)
because the spectrum was actually defined incorrectly and has [one less
domain entry than it
should](https://github.com/ppy/osu-web/pull/12363/changes#diff-a9bdefd7233ca98f7f89cd76213aba5d869ae0424c8e79d1e322abd3e43462fbR29).
I've chose to not add it because of consistency with the web and because
it looked pretty ugly (it was pretty much unreadable)

<img width="1361" height="814" alt="image"
src="https://github.com/user-attachments/assets/5f9d7a93-3e28-4b8c-952c-0abd6f8c2cc3"
/>
<img width="805" height="647" alt="image"
src="https://github.com/user-attachments/assets/b060cba7-3beb-4bb5-8d50-6210e8417715"
/>
2026-01-11 00:30:48 +09:00
Dean Herbert
dda1c7f75b Fix failing test case due to mod overlay being moved to game level 2026-01-10 01:44:07 +09:00
Dean Herbert
7652c91a53 Merge pull request #36242 from frenzibyte/form-controls-text-wrapping
Support text wrapping in form controls
2026-01-09 18:06:24 +09:00
Dean Herbert
1c1a3fbe8d Simplify logic 2026-01-09 18:01:35 +09:00
Bartłomiej Dach
7c1b1f4548 Merge pull request #36249 from peppy/global-rank-shortcut-support
Add support for global rank parsing in /users/ batch lookups
2026-01-09 09:51:00 +01:00
Bartłomiej Dach
22082097f8 Merge pull request #36282 from peppy/online-lookup-cache-exception-safety
Add safeties against exceptions in `OnlineLookupCache`
2026-01-09 09:47:50 +01:00
Bartłomiej Dach
d35658985a Merge pull request #36281 from peppy/fix-button-colour-wrong-layer
Fix now playing overlay buttons not showing toggle colour correctly
2026-01-09 09:28:36 +01:00
Dean Herbert
576be6793b Add proper logging of failed scenario in OnlineLookupCache 2026-01-09 16:52:04 +09:00
Dean Herbert
5e4e28ef00 Fix online lookup cache not recovering from faulted tasks 2026-01-09 16:42:19 +09:00
Dean Herbert
a2d2c3287b Remove unnecessary and incorrect colour application 2026-01-09 16:27:33 +09:00
Dean Herbert
23c68cbfea Add support for global rank parsing in /users/ batch lookups
See https://github.com/ppy/osu-web/pull/12651 for web-side
implementation.
To be used to fix
https://github.com/ppy/osu/pull/33649/changes#diff-32784a778b34c671e1f72c00e1f4161a5e774e849aae5631ee71b31fc32e5d42R218
(have tested this works there).

Use simple set-get rather than transforming to `APIUser.Statistics`
2026-01-09 16:19:52 +09:00
Dean Herbert
3f577aae60 Fix now playing overlay buttons not showing toggle colour correctly
Closes https://github.com/ppy/osu/issues/36280.
2026-01-09 15:18:29 +09:00
Dean Herbert
2963ebae96 Update resources 2026-01-08 02:04:18 +09:00
Dean Herbert
3157e82f51 Update framework 2026-01-08 01:45:02 +09:00
Dean Herbert
b40ffd633f Merge pull request #36263 from bdach/log-version-hash-to-sentry
Log version hash to sentry
2026-01-08 00:05:24 +09:00
Bartłomiej Dach
48de70e719 Log version hash to sentry
This is the counterpart to
https://github.com/ppy/osu-server-spectator/pull/413. The goal is to
log the value which is seemingly failing to work correctly client-side
as well.

The reason for doing that is two-fold:

- To eliminate possibility of freakazoid issues wherein some computers
  miscalculate the version hash somehow
- To eliminate possibility of the version hash somehow getting lost in
  transit (e.g. present client-side but no longer present server-side).
2026-01-07 13:03:20 +01:00
Dean Herbert
4f44d13e67 Merge pull request #36262 from bdach/stupid 2026-01-07 20:55:18 +09:00
Bartłomiej Dach
9b26b83d55 Fix beatmap scope dismiss bar showing on top of filter control dropdowns
closes https://github.com/ppy/osu/issues/36259
2026-01-07 11:13:33 +01:00
Bartłomiej Dach
7f99650a04 Add test covering desired behaviour of dismissing beatmap set scope 2026-01-07 11:08:51 +01:00
Bartłomiej Dach
0e8a294400 Merge pull request #36253 from peppy/fix-replay-overlay-vis
Fix replay settings overlay appearing momentarily during gameplay retry
2026-01-07 10:25:04 +01:00
Bartłomiej Dach
3ae98fd664 Fix broken transition of player loader right side content (#36261)
before:


https://github.com/user-attachments/assets/dd9bfef0-d653-4aa6-b48d-fe01774d3f89

after:


https://github.com/user-attachments/assets/bb3541f9-65f2-4c34-9943-ba2b63b7dbf8

regressed in 2b90cbf59f
2026-01-07 18:21:04 +09:00
Bartłomiej Dach
8c8ba2f3bc Merge pull request #35931 from smoogipoo/mp-require-hold-to-exit
Require hold-to-exit during multiplayer load
2026-01-07 07:10:04 +01:00
Dean Herbert
163ca25907 Fix settings toggle for replay settings overlay not being obeyed in multiplayer spectator
Noticed in passing.
2026-01-06 23:25:22 +09:00
Dean Herbert
85747f8866 Fix replay settings appearing momentarily when replay is not loaded
Closes #36237.
2026-01-06 23:24:54 +09:00
Dean Herbert
d05acc3d4f Fix tray showing first item too far to left 2026-01-06 22:54:27 +09:00
UltraDrakon
8cbcb0e74f Hide cursor during background reveal in song select
- Implement IProvideCursor in SongSelect to hide cursor when background is revealed
- Cursor reappears on mouse movement and hides again after 1 second of inactivity
- Fix MenuCursorContainer to preserve drag rotation state during hide/show cycles
2026-01-06 14:51:07 +01:00
Dean Herbert
d39020038b Merge pull request #36251 from jonasschips/cosmetic/fpscounter
Visual addition of whitespaces to the FPS counter
2026-01-06 22:13:32 +09:00
Jonas Schips
86a3c19547 feat: added whitespaces between "fps"/"ms" and it's value in FPSCounterTooltip.cs 2026-01-06 13:37:10 +01:00
Jonas Schips
53a5157a2f feat: added whitespace between "fps"/"ms" and it's value to prevent clipping 2026-01-06 13:10:34 +01:00
Dan Balasescu
679c6d0229 Remove Masking definition
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-01-06 17:25:08 +09:00
Dan Balasescu
86220622fb Remove HoldForMenuButton player dependency 2026-01-06 17:20:28 +09:00
Bartłomiej Dach
38360fde7b Merge pull request #36235 from smoogipoo/adjust-beatmap-query
Adjust online beatmap query to fix potential crash
2026-01-06 09:01:34 +01:00
Dean Herbert
61d0b5a03c Update resources 2026-01-06 15:01:28 +09:00
Salman Alshamrani
08364a7b97 Support text wrapping in form controls 2026-01-05 16:13:56 -05:00
Salman Alshamrani
465ec88371 Expose switch button width 2026-01-05 16:13:37 -05:00
Salman Alshamrani
4f2dfccb0f Add test cases requiring text wrapping 2026-01-05 16:13:37 -05:00
Bartłomiej Dach
43e5aec16e Merge pull request #36232 from peppy/fix-editor-undo-crash
Fix editor crashing on undoing after hit object placement
2026-01-05 10:28:46 +01:00
Dan Balasescu
59b3afe5aa Hide add button when mod selects are shown
The important one is the required mod selection, whose overlay contents
overlap with the add button. The free mod selection would otherwise be
fine, if not for consistency.
2026-01-05 18:24:50 +09:00
Dan Balasescu
fad53d9134 Hide mods wedge when empty 2026-01-05 18:04:01 +09:00
Dan Balasescu
61c4a3dba0 Fix footer button overlap
The scheduled events don't fire because the content is hidden.
2026-01-05 17:56:45 +09:00
Dan Balasescu
8b49572c44 Fix title overlap
Uses the same method of displaying the mod selection as the old song
select (as an overlay of the entire game).
2026-01-05 17:44:49 +09:00
Dan Balasescu
78a5654e1f Adjust beatmap query to fix potential crash 2026-01-05 17:16:27 +09:00
Dan Balasescu
2b90cbf59f Attempt to fix display issues at high UI scales 2026-01-05 16:46:29 +09:00
pishifat
ea289460b0 remove map from list (#36218) 2026-01-05 16:16:04 +09:00
Denis Titovets
ff3397b6b7 Localise notifications in OnlineStatusNotifier (#36223)
Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-05 16:15:01 +09:00
Denis Titovets
a4fe0c924d Localise DownloadNotification (#36224)
Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-01-05 16:12:20 +09:00
Dean Herbert
33e49442c6 Merge pull request #36225 from diquoks/localisation/legacy-collection-importer
Localise notifications in `LegacyCollectionImporter`
2026-01-05 16:03:28 +09:00
Dean Herbert
d0ac5cdeae Merge pull request #36231 from smoogipoo/adjust-qp-metrics
Adjust quick play player panels for long usernames
2026-01-05 15:57:49 +09:00
Dan Balasescu
23c595a136 Merge branch 'master' into mp-require-hold-to-exit 2026-01-05 15:30:52 +09:00
Dean Herbert
9916e5bb1c Fix editor crashing on undoing after hit object placement
Happens when initial timing is undone.

Regressed in
12170df80a.
Closes https://github.com/ppy/osu/issues/36228.
2026-01-05 15:26:14 +09:00
Dean Herbert
25dab7258c Add test coverage of editor placement scenarios 2026-01-05 15:24:15 +09:00
Dan Balasescu
b7b3e028ab Adjust quick play player panels for long usernames 2026-01-05 15:22:06 +09:00
Dan Balasescu
88f80799c3 Add test 2026-01-05 15:21:49 +09:00
Dean Herbert
5839209d6f Merge pull request #36227 from minetoblend/fix-editor-broken-for-spartans
Fix `OsuAutoGenerator` failing to alternate when objects are exactly 50ms apart
2026-01-05 14:54:50 +09:00
Jul
ff820f730e Fix play button starting wrong beatmap before selection loads (#36104)
* Fix play button starting wrong beatmap before selection loads

When clicking the osu! cookie (play button) before a newly selected beatmap finishes loading, the previous beatmap would be played instead of the currently selected one. 

This was caused by the cookie reading from the global beatmap state which is debounced by 150ms, while the Enter key correctly used the carousel's current selection.

The fix makes the cookie use the same beatmap source as Enter - the carousel's current selection - which is always up-to-date regardless of debounce timing.

Closes #36074

* Use ensureGlobalBeatmapValid() for logo and Enter key actions

* Add test for beatmap selection timing bug

Tests the fix for issue #36074 where clicking the play button immediately after selecting a different difficulty would start the wrong beatmap due to the 150ms selection debounce.
2026-01-05 14:54:25 +09:00
Dan Balasescu
593cc37ea6 Adjust styling of freestyle button 2026-01-05 14:35:34 +09:00
Dan Balasescu
ebf9c19ad3 Revert no longer necessary change
Additionally to fix the options button, I could either cache the
interface in PlaylistsSongSelectV2 or make the interface cache itself. I
went with the latter option.
2026-01-05 14:10:26 +09:00
Dean Herbert
af08416880 Add test coverage 2026-01-05 13:17:40 +09:00
Marvin
3bd2050954 Fix interpolation not being applied when previous frame-up frame is at the same time as current frame 2026-01-05 03:23:01 +01:00
Marvin
351a717795 Alternate buttons in OsuAutoPlay generator even when time difference is exactly zero.
Previously, there if two consecutive hitobjects were 50ms apart both mechanisms to make sure that the input buttons are alternated would fail.
This produced a replay frame which lifts the current button, followed by a frame which presses the same button again, at the same time as it was lifted.
The key-up frame would always get skipped without frame-stability, leading to hitsounds and hit animations not getting played in the editor.
2026-01-05 03:23:01 +01:00
Denis Titovets
00560cbfba Localise notifications in LegacyCollectionImporter 2026-01-04 20:54:50 +03:00
Dean Herbert
b6dc64668e Merge pull request #36198 from diquoks/localisation/friend-presence-notifications
Localise friend presence notifications
2026-01-04 02:22:13 +09:00
Dean Herbert
e0c4592dc7 Merge pull request #36160 from smoogipoo/qp-beatmap-attributes
Add beatmap attributes to quick play panels
2026-01-02 23:05:02 +09:00
Dean Herbert
1fcae16be9 Update framework 2026-01-02 16:39:37 +09:00
Denis Titovets
212973bd63 Localise friend presence notifications 2026-01-01 21:26:48 +03:00
Dean Herbert
5cba990940 Merge pull request #36194 from frenzibyte/fix-casing
Fix casing in random selection algorithm dropdown
2026-01-02 02:58:32 +09:00
Dean Herbert
974d3fa5e1 Merge pull request #36197 from diquoks/quick-fix/incorrect-button-dim-colour
Fix incorrect `OsuAnimatedButton`'s `DimColour` for child classes without override
2026-01-02 02:56:21 +09:00
Denis Titovets
2fc621b4f3 Fix incorrect OsuAnimatedButton's DimColour
for child classes without override
2026-01-01 20:48:38 +03:00
Dean Herbert
ff4c281bd9 Merge pull request #36180 from diquoks/quick-fix/multiple-friends-notifications
Display an old-style notification if multiple users should be displayed
2026-01-02 00:36:15 +09:00
Salman Alshamrani
833617e279 Fix casing in random selection algorithm dropdown 2026-01-01 08:42:41 -05:00
Dean Herbert
e539660b14 Attempt to fix flaky test 2026-01-01 19:41:14 +09:00
Dean Herbert
d204b79342 Merge pull request #36188 from bdach/random-branch-name-i-cant-even-whatever
Fix things breaking when attempting to exit external beatmap edit screen when it's finishing up
2026-01-01 16:38:10 +09:00
Dean Herbert
54f9360814 Merge pull request #36191 from frenzibyte/fix-account-button-spacing
Fix button spacing in account creation overlay
2026-01-01 16:15:15 +09:00
Salman Alshamrani
19cfe9abe6 Fix button spacing in account creation overlay 2025-12-31 11:28:19 -05:00
Dean Herbert
0a2fc12061 Fix/remove tests broken by screen behaviour change 2026-01-01 00:29:04 +09:00
Dean Herbert
e1ce1e3188 Merge branch 'master' into new-playlists-song-select 2026-01-01 00:29:02 +09:00
Dean Herbert
464cc23393 Merge pull request #36175 from bdach/show-all-difficulties-set-panel
Add ability to view other beatmaps in set when difficulties are grouped by set
2025-12-31 23:36:40 +09:00
Dean Herbert
338b987ea9 Merge pull request #36172 from ILW8/feature-upstream/last-year-seed-string
Change last year placing from integer to string in tournament overlay
2025-12-31 22:49:54 +09:00
Bartłomiej Dach
04bd381ee3 Fix number conversion setter hack used by LastYearPlacing 2025-12-31 12:33:31 +00:00
Bartłomiej Dach
affe295f50 Fix missing disposal 2025-12-31 13:03:36 +01:00
Bartłomiej Dach
bd29c46bd7 Fix tests 2025-12-31 12:53:59 +01:00
Bartłomiej Dach
28a6d6211c Manually fire editor save operations on skin change
This is invariably a test fix but also a valid change to make in
isolation.

In short, the problem is thus: Now that the beatmap skin is hooked up to
realm to receive notifications about changed files (which is required
for correctly handling custom samples), tests started failing, because
of the following sequence of events

- Saving a brand new `.osu` to a beatmap set causes
  `RealmBackedResourceStore` to fire subscription callbacks because a
  new file was added to the set
- This fires `RealmBackedResourceStore.CacheInvalidated`
- Which fires `EditorBeatmapSkin.BeatmapSkinChanged`
- Which would previously fire `EditorBeatmap.SaveState()` and as such
  mark the beatmap dirty / modified.

In this scenario this is gratuitous. There's no need to be raising save
states here, a new `.osu` was added to the set that is in a consistent
saved state and nothing actually changed in the beatmap.

However it does not appear sane to attempt to circumvent this with
conditional guards or something, because in cases where files are
added/removed from the set, *there isn't really any reason to take save
states anyway*. The change handler only deals with the `.osu`, any
modifications to any of the other files cannot be undone anyway.

Therefore, only keep the state save to the one change to beatmap skin
that *can* actually be sanely undone which is changing combo colours.
2025-12-31 12:14:32 +01:00
Bartłomiej Dach
334a54e6f7 Add way to add/remove custom beatmap samples to setup screen
Among others, this features a scary-looking change wherein
`WorkingBeatmap` now exposes a `RealmAccess` via
`IStorageResourceProvider`. This is necessary to make
`RealmBackedResourceStore` actually start firing callbacks when the
edited beatmap's skin is modified by adding new samples to it.
2025-12-31 12:14:28 +01:00
Bartłomiej Dach
a6545bea68 Remove dim effect from disabled spread displays on song select panels 2025-12-31 10:05:59 +01:00
Bartłomiej Dach
7e823af70b Hide back button when finishing external edit 2025-12-31 09:26:08 +01:00
Bartłomiej Dach
9f40d630dc Do not allow multiple concurrent finishes of external beatmap edit 2025-12-31 09:26:00 +01:00
Bartłomiej Dach
1cf14952de Privatise setter of weirdly exposed field 2025-12-31 09:25:42 +01:00
Bartłomiej Dach
2d119f11ec Merge pull request #36177 from peppy/debounce-seeks
Fix editor seeks not being debounced enough
2025-12-31 08:15:35 +01:00
Denis Titovets
dad138223b Small refactoring 2025-12-30 19:36:43 +03:00
Denis Titovets
a23024d80e Display an old-style notification if multiple users should be displayed 2025-12-30 18:54:28 +03:00
Dean Herbert
9f57be7410 Merge pull request #36176 from bdach/scoped-beatmap-set-display-click-anywhere
Allow clicking anywhere on the scoped beatmap set indicator to dismiss it
2025-12-30 23:23:13 +09:00
Dean Herbert
853836a48b Fix editor seeks not being debounced enough
Could lead to huge slowdowns when running multi-threaded and performing
a long drag.
2025-12-30 23:17:47 +09:00
Bartłomiej Dach
24a0de1020 Allow clicking anywhere on the scoped beatmap set indicator to dismiss it 2025-12-30 13:40:27 +01:00
Bartłomiej Dach
ebb898f67c Add test case 2025-12-30 12:40:06 +01:00
Bartłomiej Dach
e2ed5208fe Bring back ruleset grouping & overflow handling to spread display 2025-12-30 12:39:50 +01:00
Bartłomiej Dach
e07b828f30 Add support for showing which beatmaps in a set are currently filtered out 2025-12-30 12:39:32 +01:00
Bartłomiej Dach
e2a245b049 Add minimal spread display control for beatmap set panels 2025-12-30 12:39:18 +01:00
Bartłomiej Dach
57cbe20c12 Merge pull request #36162 from peppy/update-framework
Update framework
2025-12-30 08:59:18 +01:00
Bartłomiej Dach
646e6de5df Merge pull request #36113 from diquoks/localisation/settings
Localise various strings in settings
2025-12-30 07:35:22 +01:00
ILW8
191ec072a8 Add conversion from 0 last year placing value to new default "N/A" 2025-12-30 02:48:41 +00:00
ILW8
1cff386b3a Adjust seed and last year placing textbox positioning in team editor 2025-12-30 02:48:40 +00:00
ILW8
71be574c2b Update seeding screen tests to include last year placing 2025-12-30 01:38:39 +00:00
ILW8
6e41332ea3 Change last year placing from integer to string 2025-12-30 01:37:44 +00:00
Dean Herbert
3c084c60aa Fix iOS compilation 2025-12-30 01:27:08 +09:00
Bartłomiej Dach
3b9b030aad Merge pull request #36161 from peppy/editor-no-smooth-seeking
Change editor to not seek smoothly when performing distant seeks
2025-12-29 12:43:45 +01:00
Dean Herbert
d421678d34 Update framework 2025-12-29 20:18:18 +09:00
Denis Titovets
056d832371 Move "Random" string to UserInterfaceStrings 2025-12-29 14:12:02 +03:00
Bartłomiej Dach
4e83814d5a Merge pull request #36114 from diquoks/localisation/play-v2
Localise various strings on `Play` screen (again)
2025-12-29 11:57:33 +01:00
Dan Balasescu
8ff2329e22 Fix tests 2025-12-29 19:13:39 +09:00
Bartłomiej Dach
6bf25d700c Merge pull request #36159 from peppy/fix-now-playing-overlay-weird
Fix a couple of edge cases when interacting with the now playing overlay using keyboard control
2025-12-29 10:22:43 +01:00
Bartłomiej Dach
5163b8f5f3 Merge pull request #36158 from peppy/reduce-audio-debounce-time
Reduce audio seek debounce time downwards
2025-12-29 10:08:50 +01:00
Dan Balasescu
2e324fe856 Show vote count in tag tooltip 2025-12-29 17:47:35 +09:00
Dean Herbert
8347f83f9c Change editor to not seek smoothly when performing distant seeks
This reverts to the way stable does things. Smooth seeking is nice and
all, but slows things down and doesn't give the instant reponse that
mappers are used to.

This should fix some performance issues regarding seeking as it no
longer tries to render large portions of the map during the seek
operation.

Note that I've also forced the summary timeline to always non-smooth
seek. It was bugging out in weird ways when doing smooth seeks and I
don't want to attempt to fix it.
2025-12-29 17:44:03 +09:00
Dan Balasescu
e34d266987 Fix code style 2025-12-29 17:37:57 +09:00
Dan Balasescu
a6e1713514 Fix panel depth 2025-12-29 17:29:21 +09:00
Dan Balasescu
10ebb5286f Adjust metrics 2025-12-29 17:29:21 +09:00
Dan Balasescu
69fee16eee Add top tag and difficulty attributes 2025-12-29 16:20:14 +09:00
Dean Herbert
f3fa1122c2 End christmas 2025-12-29 16:07:14 +09:00
Dean Herbert
0f018988b5 Fix double seek when using keyboard with now playing overlay seek bar 2025-12-29 16:04:24 +09:00
Dean Herbert
4a60d7fe71 Fix now playing overlay responding to key events when seek bar is not visually focused 2025-12-29 16:04:08 +09:00
Dean Herbert
69250b3260 Reduce audio seek debounce time downwards
I found this way too high in the editor, not giving enough feedback when
seeking.

To recap, this was put in place to avoid glitchy sounding audio. Such
glitchiness only occurs with *very* fast seeks. This is still well
within sane range.
2025-12-29 16:03:20 +09:00
Dan Balasescu
60d9c358b8 Move top user tags enumeration to helper 2025-12-29 15:43:43 +09:00
Dean Herbert
ef3338ba93 Merge pull request #36140 from nbvdkamp/add-fps-settings-keywords
Add keywords to FPS related settings
2025-12-27 23:11:58 +09:00
Nathan van der Kamp
99b00ab72f Add keywords to FPS related settings 2025-12-27 00:29:25 +01:00
Dean Herbert
56ef5eae14 Revert "Merge pull request #36102 from bdach/move-check-to-better-place"
This reverts commit 2cb2167765, reversing
changes made to 0bcb3c5839.
2025-12-26 22:36:16 +09:00
Dean Herbert
2cb2167765 Merge pull request #36102 from bdach/move-check-to-better-place
Perform online ID checks during import in more proper sequence
2025-12-26 22:35:02 +09:00
Dean Herbert
206578bf10 Always flash button when adding a new item to playlist 2025-12-25 21:39:17 +09:00
Dean Herbert
36de88f399 Merge branch 'master' into new-playlists-song-select 2025-12-25 20:26:35 +09:00
Dean Herbert
0bcb3c5839 Merge pull request #36103 from bdach/form-sample-set
Implement form control for adding/removing custom samples in editor
2025-12-25 15:11:33 +09:00
Dean Herbert
2acc2a84db Merge pull request #36116 from frenzibyte/new-settings/form-visuals
Prepare form controls for use in settings
2025-12-25 03:16:12 +09:00
Dean Herbert
64d16776be Merge pull request #36118 from bdach/zip-magic 2025-12-25 02:29:18 +09:00
Dean Herbert
2d06c2b1a6 Merge pull request #36121 from smoogipoo/mp-fix-availability-tracker
Fix potentially incorrect online play beatmap availability
2025-12-24 20:32:46 +09:00
Dan Balasescu
81f03957d8 Reduce code duplication
Co-authored-by: Dean Herbert <pe@ppy.sh>
2025-12-24 19:30:04 +09:00
Dan Balasescu
ecaf3e05d4 Fix tests 2025-12-24 16:53:08 +09:00
Salman Alshamrani
2d85fe8133 Fix tournament screens not having colour provider cached 2025-12-24 02:22:59 -05:00
Dan Balasescu
0af07b97c5 Fix potentially incorrect online play beatmap availability 2025-12-24 15:08:37 +09:00
Dean Herbert
03f44705b3 Adjust naming 2025-12-24 14:57:17 +09:00
Salman Alshamrani
033a73e969 Update switch button visuals 2025-12-23 20:18:59 -05:00
Dean Herbert
1340e18d93 Merge pull request #36101 from bdach/guest-difficulty-export
Add explicit menu item for exporting guest difficulties from editor
2025-12-24 00:45:19 +09:00
Denis Titovets
43e217120d Fix offset not changing using current culture 2025-12-23 14:51:31 +03:00
Denis Titovets
dc53198577 Make edits based on reviews 2025-12-23 14:36:12 +03:00
Salman Alshamrani
95cf050298 Make setter protected to fix build error 2025-12-23 06:31:26 -05:00
Denis Titovets
0bfff2bf88 Make edits based on reviews 2025-12-23 14:27:34 +03:00
Salman Alshamrani
fa32be37d6 Expose constant for max decimal digits display 2025-12-23 06:14:48 -05:00
Salman Alshamrani
e4d7bc3896 Seal tooltip text overrides 2025-12-23 06:11:05 -05:00
Salman Alshamrani
520baf6c50 Add explanatory note 2025-12-23 06:11:05 -05:00
Salman Alshamrani
a1d4d44151 Revert unintended change 2025-12-23 06:11:05 -05:00
Salman Alshamrani
a3a5b2ca92 Fix tests not having colour providers 2025-12-23 05:58:57 -05:00
Salman Alshamrani
cb32d2da3e Make sound playback consistent across all disabled controls 2025-12-23 05:56:17 -05:00
Salman Alshamrani
4ee7e6f787 Add label and tooltip formatting to form sliders 2025-12-23 05:56:17 -05:00
Salman Alshamrani
c2c1fa4d4c Add right margin to form dropdown chevron 2025-12-23 05:56:17 -05:00
Salman Alshamrani
339aad42a7 Use switch button for form checkbox controls 2025-12-23 05:56:17 -05:00
Salman Alshamrani
a2872ee870 Update "disabled" visual feedback of form controls 2025-12-23 05:56:17 -05:00
Salman Alshamrani
c6a8d9a150 Add extra form controls in test scene 2025-12-23 05:56:17 -05:00
Dean Herbert
6eec2b0ff8 Merge pull request #36081 from bdach/esdfiopj
Fix cursor scale affecting trail spacing
2025-12-23 19:48:34 +09:00
Dean Herbert
0999e3f048 Merge pull request #36047 from bdach/reveal-other-difficulties-thing
Add ability to view other beatmaps in set when difficulties are split apart
2025-12-23 19:43:47 +09:00
Bartłomiej Dach
71386fe465 Merge pull request #36056 from peppy/fix-stacking-woes
Fix osu! stacking not matching stable in very specific edge cases
2025-12-23 08:45:40 +01:00
Bartłomiej Dach
f58e4e4862 Use sane initial value for cursor scale to avoid infinite loops 2025-12-23 08:43:07 +01:00
Bartłomiej Dach
0bebabba94 Replace spread operator usage with manual linq
`dotnet format` expects me to put a space between the spread `..` and
the expression after which is UTTERLY STUPID AND UGLY AND WRONG AND
CANNOT BE `.editorconfig`'d BECAUSE [INSERT EXCESSIVELY LONG BLEEP].

God I hate when good features are kneecapped by this sort of stupidity.
2025-12-23 08:35:20 +01:00
Bartłomiej Dach
95233fc638 Fix replay files potentially getting misclassified as zip archives
Resolves https://github.com/ppy/osu/discussions/36107.

The replay linked in the aforementioned discussion happens to contain
the magic sequence for ZIP headers in the binary stream (50 4b 05 06)
which led to it getting classified as a ZIP with no entries and
completely bogus everything in the header at

	c8b18acd4d/osu.Game/Database/ImportTask.cs (L51-L56)

and then finally dying of

	2025-12-23 07:26:45 [error]: [?????] Model creation of replay-osu_2040232_4828629841.osr failed.
	2025-12-23 07:26:45 [error]: System.InvalidOperationException: Sequence contains no matching element
	2025-12-23 07:26:45 [error]: at System.Linq.ThrowHelper.ThrowNoMatchException()
	2025-12-23 07:26:45 [error]: at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
	2025-12-23 07:26:45 [error]: at osu.Game.Scoring.ScoreImporter.CreateModel(ArchiveReader archive, ImportParameters parameters)
	2025-12-23 07:26:45 [error]: at osu.Game.Database.RealmArchiveModelImporter`1.importFromArchive(ArchiveReader archive, ImportParameters parameters, CancellationToken cancellationToken)

at

	554961036e/osu.Game/Scoring/ScoreImporter.cs (L46)
2025-12-23 08:23:23 +01:00
Denis Titovets
277e00c74e Localise various strings on Play screen (again) 2025-12-23 03:21:08 +03:00
Denis Titovets
a25f1cde25 Localise various strings in settings 2025-12-23 02:36:54 +03:00
Dean Herbert
2ed37ecbbc Merge branch 'master' into esdfiopj 2025-12-23 02:33:08 +09:00
Dean Herbert
554961036e Merge pull request #36080 from bdach/form-slider-bar-disabled
Fix disabled form slider bars being half-baked
2025-12-23 02:26:34 +09:00
Dean Herbert
dbcc7cc09d Merge branch 'master' into form-slider-bar-disabled 2025-12-22 23:44:33 +09:00
Dean Herbert
d9dad4c3a8 Merge pull request #36055 from frenzibyte/new-settings/item
Implement new settings item component
2025-12-22 22:55:53 +09:00
Dean Herbert
0787345a84 Adjust colour of inactive slider bar 2025-12-22 22:06:39 +09:00
Bartłomiej Dach
9d07ad2761 Implement form control for adding/removing custom samples in editor
The test scene doesn't exercise the custom sample playback, but I hope I
can be forgiven for this as setting up a custom editor beatmap just for
this to work is rather cumbersome.
2025-12-22 13:48:31 +01:00
Bartłomiej Dach
1ab922af12 Fix test 2025-12-22 12:48:53 +01:00
Bartłomiej Dach
44df9047ae Only perform replace-on-import based on online beatmap set ID after it's validated
Even without the ID resetting logic before `Populate()` getting broken
and annotated with a TODO, this was kinda stupid. Why was purging logic
allowed to run *using a not-yet-completely-validated online ID of the
set*?

This is the other part of hopefully fixing scenarios like
https://osu.ppy.sh/community/forums/topics/2162457?n=8 (hopefully with
no babies poured out in the mean time, but only time will tell).
2025-12-22 12:27:29 +01:00
Bartłomiej Dach
17143ca0a8 Move online ID validation check into its proper location
The end of `Populate()` is too early to do any validation of online IDs,
as population happens in `PostImport()` via `ProcessBeatmap`.

Additionally, this modifies the check to also include the set's ID. This
is one part of curtailing issues like
https://osu.ppy.sh/community/forums/topics/2162457?n=8 - the featured
artist template beatmap in question has a single difficulty with a bogus
positive beatmap set ID and a beatmap ID of 0, and my opinion is that
this sort of situation should for all intents and purposes cause the
beatmap set's ID to be reset.
2025-12-22 12:22:04 +01:00
Bartłomiej Dach
3712093158 Add explicit menu item for exporting guest difficulties from editor
A few facts of life:

- Guest difficulties are at this point a staple of mapping.

- People are very much used to flinging `.osu`s around (because there's
  no better alternative).

- Currently there are two ways to get an `.osu` out of lazer. You can:

  - Export the beatmap as "compatibility" to an `.osz`, then
    transmogrify the `.osz` to a `.zip`, then extract the `.zip`, then
    pluck out the `.osu`. This is the "correct" way to make sure stable
    works, but is also stupidly arcane.

  - Use "edit externally" to mount the beatmap files to disk, then
    copy-paste out the `.osu`. This is the *wrong* way to make sure
    stable works, because the mounting process exposes the raw "for
    editing" format with features stable doesn't support, but it the
    actual easy one.

- Reports about guest difficulties exported from lazer "working wrong on
  stable" are prevalent. Probably mostly because of the preceding point.

What this PR does is introduce a *third* method to export an `.osu`,
which is designed to be both the easiest one yet *and* correct. I am
hoping this will curb the complaints until support for direct submission
of guest difficulties is added - which I still hope to see, but it will
be a significant effort *client-side* (the server side has been ready
for years now).

And yes, you will notice that much of the code added in
`LegacyBeatmapExporter` related to manipulation of the path is
copy-pasted from `LegacyExporter`. I don't care enough to invent
protected / abstract / whatever else OOP faff for something that may not
survive review and is mostly a weird semi-temporary wart.
2025-12-22 11:36:23 +01:00
Bartłomiej Dach
df524d68fd Move disable to better place 2025-12-22 10:04:29 +01:00
Bartłomiej Dach
daaea093f0 Add another failing test 2025-12-22 10:04:18 +01:00
Dean Herbert
469aa7b303 Merge pull request #36021 from tsunyoku/rank-mania-cover
Set `Ranked` to `true` for `ManiaModCover`
2025-12-22 13:45:21 +09:00
Bartłomiej Dach
e094eefafb Fix cursor scale affecting trail spacing
Closes https://github.com/ppy/osu/issues/36061.

Regressed in https://github.com/ppy/osu/pull/35802.

It's either this or revert of aforementioned pull. I dunno.
2025-12-19 14:27:55 +01:00
Bartłomiej Dach
4cce6aa123 Address review concerns 2025-12-19 13:59:26 +01:00
Bartłomiej Dach
bba4329ab5 Remove now-redundant tests
They all pass along with the last stacking threshold fix, so I see no
reason to keep them in.
2025-12-19 13:16:14 +01:00
Bartłomiej Dach
25ba3f2dc6 Fix yet another incorrect threshold check in stacking code 2025-12-19 13:16:12 +01:00
Bartłomiej Dach
ecc51d4701 Fix disabled form slider bars being half-baked
In order of severity:

- You could actually click on the textbox portion of a disabled textbox,
  focus it, select text, input stuff, and commit, which would die
  on the spot.

- The slider part had no visual indication that it's not interactable
  anymore.
2025-12-19 12:17:46 +01:00
Bartłomiej Dach
32454caaa9 Add failing test 2025-12-19 12:17:06 +01:00
Bartłomiej Dach
0f53886784 Fix stack threshold being calculated in a different way than stable 2025-12-19 10:19:20 +01:00
Bartłomiej Dach
f598d8b108 Add extended conversion mapping coverage for more failing cases
Some are not immediately relevant to the stacking issue because they
fail both before and after it, just less so after the stacking issue
(half-)fix, and as such have been commented out for the time being.
2025-12-19 10:19:20 +01:00
Salman Alshamrani
f273163e58 Improve revert button animation 2025-12-19 02:27:04 -05:00
Bartłomiej Dach
6de1f0cd4d Merge pull request #36060 from peppy/collection-dialog-improve
Improve manage collections dialog usability
2025-12-19 07:53:45 +01:00
Salman Alshamrani
c475b4bc4b Add explanatory note for ClearTransforms usage 2025-12-18 20:04:02 -05:00
Salman Alshamrani
276757315f Simplify classic default flow 2025-12-18 20:03:38 -05:00
Salman Alshamrani
a82d0c3b51 Rename property to have consistent name 2025-12-18 20:01:36 -05:00
Salman Alshamrani
4fee1547e3 Use menu item labels as filter terms instead 2025-12-18 19:48:42 -05:00
Salman Alshamrani
a4215e0442 Add tooltip to revert-to-default button 2025-12-18 18:56:18 -05:00
Bartłomiej Dach
577cf7d1e7 Remove invalid xmldoc reference 2025-12-18 14:49:30 +01:00
Dean Herbert
09178b5dc4 Add helper method and update some other similar preempt calculations 2025-12-18 22:28:50 +09:00
Dean Herbert
16c4967ee4 Fix added item not scrolling into view immediately 2025-12-18 22:03:19 +09:00
Dean Herbert
e526de7f40 Move "Create new collection" out of scroll content 2025-12-18 22:03:19 +09:00
Dean Herbert
93a64dad89 Adjust corner radius and design slightly 2025-12-18 21:39:10 +09:00
Dean Herbert
897cb2c1a9 Merge pull request #35430 from bdach/custom-sample-set-selection
Add sample set displays & selection controls to editor
2025-12-18 21:01:19 +09:00
Dean Herbert
de0c191c47 Update resources 2025-12-18 20:53:42 +09:00
Salman Alshamrani
61874e59e0 Extend classic default test coverage 2025-12-18 06:17:48 -05:00
Dean Herbert
13aeed15f9 Remove button sound from sample toggle buttons
The new ones added in this change don't play the UI sounds, likely
because they make it nigh impossible to actually hear what the gameplay
samples will sound like.

This removes the same sounds from the existing buttons to match.
2025-12-18 20:17:46 +09:00
Salman Alshamrani
094860bfea Define delegate for applying classic defaults 2025-12-18 06:17:07 -05:00
Dean Herbert
44f535dcef Fix osu! stacking not matching stable in very specific edge case
Closes https://github.com/ppy/osu/issues/36052.

Not much more to say here. Until now the `PreEmpt` typing discrepancy
has likely gone unnoticed since it's usually only used in visual usages.
2025-12-18 20:08:56 +09:00
Salman Alshamrani
f5bd888078 Remove Value from {Is,Set}ValueDefault 2025-12-18 05:50:35 -05:00
Salman Alshamrani
90d7615432 Limit form dropdown height by default 2025-12-18 05:19:54 -05:00
Salman Alshamrani
7a32e0eebf Add test coverage 2025-12-18 05:19:54 -05:00
Salman Alshamrani
78043fa782 Implement new settings item component 2025-12-18 05:19:54 -05:00
Salman Alshamrani
729cd722bd Expose common interface for form controls 2025-12-18 05:15:01 -05:00
Salman Alshamrani
8da1fde981 Add osu!-style undo icon 2025-12-18 04:08:16 -05:00
Dean Herbert
1de97712f1 Merge pull request #36025 from smoogipoo/qp-ui-scale
Remove UI scaling in quick play
2025-12-18 16:01:39 +09:00
Dean Herbert
83ddcf7b02 Fix github side inspection 2025-12-18 16:00:23 +09:00
Dan Balasescu
2e7edf8c1f Also apply to queue screen 2025-12-18 14:07:58 +09:00
Dean Herbert
61ecd18d24 Merry christmas 2025-12-18 02:20:13 +09:00
Bartłomiej Dach
9e67cf503b Merge pull request #36043 from peppy/more-stable-editor-seeking
Adjust editor seeking to be fairer when track is playing
2025-12-17 13:57:47 +01:00
Bartłomiej Dach
62fd61def4 Merge pull request #36042 from peppy/remove-beat-sync-break-overlay
Remove beat sync from skip / break overlay
2025-12-17 13:34:04 +01:00
Bartłomiej Dach
c120f0ebab Fix license header 2025-12-17 13:20:51 +01:00
Bartłomiej Dach
5bf6a75b50 Add ability to view other beatmaps in set when difficulties are split apart
First part of https://github.com/ppy/osu/issues/36039, see also
https://github.com/ppy/osu/discussions/33784.

The goal is to add this back to the set panels too, but that one is more
complicated than this if you can believe it (because it requires being
able to tell which other difficulties of the set are filtered out to
fade them out). I also foresee the display logic to vary significantly
there.

Of note, for this to work in beatmaps-split-apart mode, this requires a
change of behaviour in the filtering logic. Old song select when given a
"selected beatmap set" would *include* that in results regardless of the
filter, but that doesn't work for beatmaps-split-apart for reasons that
are hopefully obvious, so this changes the behaviour to *entirely
bypass* the filter and just show the set. Unsure how angry will people
be with that.

Also of note, when in the scoped mode, altering any filter criteria will
dismiss the scope.
2025-12-17 12:28:20 +01:00
Dean Herbert
b71a26fcec Adjust tray to feel better 2025-12-17 20:19:19 +09:00
Dean Herbert
5f9639fc3f Fix inspections 2025-12-17 19:32:07 +09:00
Dean Herbert
61bf68f336 Merge branch 'master' into custom-sample-set-selection 2025-12-17 19:30:24 +09:00
Dean Herbert
f581f85eb2 Adjust editor seeking to be fairer when track is playing
The previous multiplier was supposed to account for seeking backwards
being "slower" because the track is playing forwards, but it really
didn't work amazingly.

Rather than trying to pull off some magic, let's just ensure that seeks
in both directions feel correct, even if that means that time gradually
moves forwards.

Closes https://github.com/ppy/osu/issues/35998 (mostly).

Of note, this still doesn't match stable completely. I attempted to
implement the full stable seeking algorithm but it's objectively worse
in other scenarios, so I'd rather just tweak what we have until the
majority of users are happy.
2025-12-17 18:50:14 +09:00
Dean Herbert
b07cd2daa4 Remove beat sync from skip / break overlay
This didn't end up feeling as good as I hoped. Will revise at a later
stage, adding beat sync in another way that isn't jank transforms on the
progress bars.

Also closes https://github.com/ppy/osu/issues/35972.
2025-12-17 16:38:46 +09:00
AV
3b635f6919 Prevent mod track adjustments from modifying BGM speed in queue (#36027)
* Fix(Matchmaking): Prevent mod track adjustments from applying BGM speed in queue

* replaced modification of MusicController directly with a property change.

* formatted
2025-12-17 14:40:08 +09:00
Dean Herbert
07817dce70 Expose notification main content for external use 2025-12-17 14:28:08 +09:00
Dan Balasescu
67e0348fa8 Merge branch 'master' into new-playlists-song-select 2025-12-17 13:33:34 +09:00
Dean Herbert
734c6f933d Merge pull request #36020 from bdach/fail-indicator-right-sound
Fix replay fail indicator not using fail sample from beatmap skin
2025-12-17 01:15:22 +09:00
Dean Herbert
ac213c90cb Merge pull request #36023 from bdach/report-message-pm
Adjust message on successful report to match bancho
2025-12-16 23:52:31 +09:00
Bartłomiej Dach
74ca87c252 Merge pull request #36009 from frenzibyte/fix-skip-button
Fix skip overlay potentially not allowing skipping
2025-12-16 14:58:43 +01:00
Dan Balasescu
190b5535d7 Remove UI scaling in quick play 2025-12-16 21:21:52 +09:00
Bartłomiej Dach
032912e62b Adjust message on successful report to match bancho
Addresses https://github.com/ppy/osu/discussions/36004.

Not adding localisation because the previous implementation was
`.ToString()`ing anyway.

Would have made the abuse e-mail a link but `mailto:` doesn't work with
`MessageFormatter` and I don't want to go into that right now.

The message *almost* matches stable. The "almost" is because it doesn't
mention the `/ignore` chat command. I was just going to implement the
command, but I went to check what it does, and backed away slowly
because it has like weird scoping to chat, highlights, and PMs, so
`nope.avi`.
2025-12-16 11:20:54 +01:00
James Wilson
83f9eba1d1 Set Ranked to true for ManiaModCover 2025-12-16 09:28:30 +00:00
Bartłomiej Dach
1e79c56240 Fix replay fail indicator not using fail sample from beatmap skin
Closes https://github.com/ppy/osu/issues/36003.

The duplicated `RulesetSkinProvidingContainer` is unfortunate but it's
either this or I start doing proxy shenanigans.
2025-12-16 09:48:10 +01: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
Dean Herbert
82256ae2de Merge pull request #34807 from mcendu/legacy-pp-counter
Add "legacy" pp counter
2025-12-15 20:24:04 +09:00
Dean Herbert
1142be45ec Update resources 2025-12-15 19:22:11 +09:00
Dean Herbert
dcb6d71287 Adjust constant and documentation slightly 2025-12-15 19:07:46 +09:00
Salman Alshamrani
881a35b382 Fix skip overlay potentially not allowing skipping 2025-12-15 03:54:09 -05:00
Dean Herbert
89d8b402af Merge branch 'master' into legacy-pp-counter 2025-12-15 16:55:51 +09:00
Dean Herbert
1d351002df Merge pull request #36005 from smoogipoo/update-packages
Update localisation analyser packages
2025-12-15 16:15:37 +09: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
Dean Herbert
2606f3a0b5 Merge pull request #35980 from smoogipoo/qp-ux-fixes
Various minor quick play UX fixes
2025-12-12 19:20:17 +09:00
Dan Balasescu
1c463aa060 Automatically accept invitation in queue screen 2025-12-12 18:26:52 +09:00
Dan Balasescu
7853abe8aa Move to queue screen when clicking notification 2025-12-12 18:13:00 +09:00
Dan Balasescu
1aff418981 Reword waiting text 2025-12-12 17:57:50 +09:00
Dean Herbert
62e92bb242 Merge pull request #35971 from smoogipoo/fix-mp-screen-leave
Forcefully leave room on multiplayer exit
2025-12-12 17:06:20 +09:00
Dan Balasescu
79151ae5b4 Remove mention of exception that doesn't exist 2025-12-12 15:46:00 +09: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
Dan Balasescu
c17db2cdd0 Forcefully leave room on multiplayer exit 2025-12-11 20:07:44 +09:00
Dan Balasescu
bbdd70c843 Always perform leave room sequence 2025-12-11 20:07:36 +09:00
Bartłomiej Dach
4250a54245 Merge pull request #35969 from peppy/delay-loading-animation
Slightly delay song select leaderboard's loading placeholder to avoid flashing during local score retrieval
2025-12-11 11:54:27 +01:00
Bartłomiej Dach
40fdb8662e Merge pull request #35966 from peppy/fix-muting-after-gameplay-with-bad-network
Fix audio track potentially muting after gameplay with bad network
2025-12-11 10:57:45 +01:00
Dean Herbert
6ce8b0a4bc Slightly delay song select leaderboard's loading placeholder to avoid flashing during local score retrieval
Closes #35893.
2025-12-11 18:54:38 +09:00
Dean Herbert
b30047def6 Remove audio adjustments immediately on gameplay hotkey overlays
Closes #22164.
2025-12-11 17:57:07 +09:00
Bartłomiej Dach
0ffb86262f Merge pull request #35965 from peppy/debounce-seek-only-when-playing
Fix editor not seeking smoothly when paused
2025-12-11 08:54:36 +01:00
Dean Herbert
f71eb4b980 Debounce track seeks only when track is playing
This fixes the editor no longer seeking smoothly when paused.

Closes https://github.com/ppy/osu/issues/35963.
2025-12-11 16:00:13 +09:00
Dan Balasescu
1faf02e860 Update localisation analyser packages 2025-12-11 13:53:09 +09:00
Dean Herbert
d700375e55 Merge pull request #35843 from SollyBunny/master
Make tracked leaderboard score yellow again
2025-12-11 13:50:59 +09:00
Bartłomiej Dach
095a67c24e Fix dragging volume meter to adjust volume closing overlays if mouse is released outside of overlay content (#35940)
* Add failing test

* Fix dragging volume meter to adjust volume closing overlays if mouse is released outside of overlay content

Fixes https://osu.ppy.sh/community/forums/topics/2159553.
2025-12-11 13:47:08 +09:00
Bartłomiej Dach
86054497d0 Disable save replay on fail overlay when spectating (#35942)
"Closes" https://github.com/ppy/osu/issues/35920.

The button can't easily work anyway since it's not guaranteed that the
spectating user has all of the frames of the replay (think entering
spectate midway through a play).

This matches the results screen in spectator too.
2025-12-11 13:42:15 +09:00
Bartłomiej Dach
c4f7dee82b Fix skin editor sometimes dropping anchor/origin specification on paste (#35957)
* Add failing test for copy->paste not being idempotent

* Ensure all elements on default skins use fixed anchors

`UsesFixedAnchor` defaults to false, i.e. closest anchors. Combined with
manual anchor / origin specs on some drawables, this would get default
skins into impossible states wherein a drawable would use "closest
anchor" but also explicitly specify anchor / origin that aren't closest,
which horribly fails on attempting to copy and paste.

Frankly shocked this has gone unnoticed for this long, and I regret not
vetoing this "feature" more every time I see its tentacles spread to
produce breakage of levels yet unseen.

Does this commit contain major levels of suck? For sure. Do I have any
better ideas that wouldn't consist of a multi-day rewrite or deletion of
this "feature"? No.

* Fix skin editor always applying closest anchor / origin on paste regardless of whether the component uses fixed anchor

Self-explanatory. Should close https://github.com/ppy/osu/issues/29111
along with previous commit.
2025-12-11 13:40:48 +09:00
Bartłomiej Dach
22825f6509 Merge pull request #35958 from bdach/fix-storyboard-samples-not-playing-in-editor
Fix storyboard samples not playing in editor
2025-12-10 14:33:30 +01:00
Bartłomiej Dach
691e8bcd05 Fix storyboard samples not playing in editor
Closes https://github.com/ppy/osu/issues/35954.
2025-12-10 11:20:50 +01:00
Bartłomiej Dach
e68bab4f4b Merge pull request #35802 from Xiragi/gameplay-cursor-size-change
Fix cursor trail detaching from cursor when adjusting cursor scale
2025-12-10 07:34:08 +01:00
Bartłomiej Dach
9430a62af4 Merge pull request #35925 from rrex971/storyboard-alpha-overshoot-handling
Adjust alpha handling for values exceeding 1 for storyboard sprite transforms to match stable behavior.
2025-12-10 07:26:50 +01: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
bdac75e542 Merge pull request #31141 from DanielPower/screen-scaling-tablet-output
Scale tablet output size when UI Scaling mode is "Everything"
2025-12-10 01:40:46 +09:00
Dean Herbert
5c2df50714 Add test coverage of weird storyboard sprite behaviour 2025-12-09 19:53:02 +09:00
Bartłomiej Dach
887d280bfa Merge branch 'master' into gameplay-cursor-size-change 2025-12-09 11:51:06 +01: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
Dean Herbert
84db289779 Use modulus instead of previous solution to match stable more closely 2025-12-09 18:57:49 +09:00
Dean Herbert
4c0522b795 Update comment and fix formatting 2025-12-09 18:00:32 +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
Bartłomiej Dach
07ea9fe2a4 Merge branch 'master' into screen-scaling-tablet-output 2025-12-09 08:05:20 +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
4b0017dfea Require hold-to-exit during multiplayer load 2025-12-08 16:33:55 +09:00
rrex971
f73307876e Also apply alpha logic to StoryboardAnimation sprites too. 2025-12-08 02:19:29 +05:30
rrex971
4e4aa44a02 Override sprite update method to handle alpha values > 1 like stable.
If alpha exceeds 1 during a sprite's alpha transform like in a FadeTo(), it will set it to 0 mimicking stable's behavior.
2025-12-08 02:17:35 +05:30
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
Chirag Mahesh
a6c001244f Redundant string interpolation 2025-12-06 11:18:18 +00: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
Chirag Mahesh
107098314a Move and refactor TestSceneGameplayCursorSizeChange into Ruleset Osu Tests 2025-12-05 17:23:31 +00:00
Chirag Mahesh
d1d76a76ba Refactor trail scale update logic into a dedicated method 2025-12-05 17:23:29 +00: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
Solly
2a7e71d7fd Merge branch 'master' into master 2025-12-03 09:15:21 +00: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
SollyBunny
0b4f96efc8 Make tracked leaderboard score yellow again 2025-11-29 03:23:13 +00: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
Chirag Mahesh
78c6973298 move cursorScale persistance into OsuCursor and use skinnableCursorScale 2025-11-27 16:39:51 +00:00
Chirag Mahesh
d8d7c80832 Persist cursorScale on skin refresh 2025-11-27 16:09:50 +00:00
Chirag Mahesh
ae33690632 Implement CursorTrail Scaling
- Add CursorScale property to CursorTrail and adjust for scaling
2025-11-27 16:09:50 +00:00
Chirag Mahesh
9e2ea63e70 Revert Changes to Trail Position Calculation
- Revert changes to CursorTrail.cs made during 79bfe7880a
2025-11-27 16:09:49 +00: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
Chirag Mahesh
79bfe7880a Move LocalSpacePosition calculation until the time of render
Would address #35734
2025-11-25 07:37:23 +00: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
80fbcd5fbd Move application of scaling to tablet output area to scaling container
It's the safest place for it to be there, really.
2025-11-18 14:49:01 +01:00
Bartłomiej Dach
9c2319b989 Use existing bindables instead of refetching 2025-11-18 14:40:47 +01:00
Bartłomiej Dach
a040143825 Merge branch 'master' into screen-scaling-tablet-output 2025-11-18 14:24:03 +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
Dan Balasescu
bb017ade64 Add simple tray 2025-11-18 17:26:34 +09:00
Dan Balasescu
549cc08bfe Remove add button from playlist popup 2025-11-18 16:21:11 +09:00
Dan Balasescu
96dd95940f Add simple "Add to playlist" button in the footer 2025-11-18 16:21:08 +09:00
Dan Balasescu
a30f08be80 Merge branch 'master' into new-playlists-song-select 2025-11-18 14:08:12 +09: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
Bartłomiej Dach
8755a01622 Fix playing sample multiple times 2025-10-31 08:55:55 +01:00
Bartłomiej Dach
901044d690 Remove stuff that was not even supposed to exist 2025-10-31 08:49:26 +01: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
90d1725603 Fix code quality
God does `dotnet format` make the `..` spread syntax just absolutely
unusable with its stupid inspections.
2025-10-24 13:49:55 +02: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
78eaad13ae Fix tests 2025-10-24 12:09:38 +02:00
Bartłomiej Dach
511921c1f7 Inherit sample set info from previous object on placement 2025-10-24 12:09:30 +02:00
Bartłomiej Dach
e2681c4163 Add sample set selection controls to sample popovers
- Below 20 custom sample sets, they are shown as ternary buttons.
- Above 20 custom sample sets, they are shown in a dropdown (yes there
  are actual cases of this as I've been informed by the NAT; one example
  being https://osu.ppy.sh/beatmapsets/1018061#osu/2197383)

As a bonus, to make determining what the heck is actually changing when
adjusting these controls, the full set of applicable sounds now plays on
adding/removing additions, changing their banks, as well as changing the
custom set (if any).

For now there are no user-facing controls to add the samples to the map
yourself, you have to know how to name the `.wav`s and edit-externally
them in yourself. *For now.*
2025-10-24 12:09:27 +02:00
Bartłomiej Dach
1f2f86b016 Make bank selection controls dropdowns instead of text boxes
Longstanding complaint. Text boxes make no sense if anything that isn't
the three legacy values gets deleted on save anyway.
2025-10-24 11:52:45 +02:00
Bartłomiej Dach
fa7bd482d2 Show sample suffix on timeline pieces 2025-10-24 11:52:45 +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
Dan Balasescu
c8762762f9 Fix CI inspections 2025-10-17 09:19:27 +09:00
Dan Balasescu
9333ef361b Remove old implementation 2025-10-17 09:18:05 +09:00
Dan Balasescu
1cf9c04756 Fix playlist with >1 item getting cleared 2025-10-17 09:18:05 +09:00
Dan Balasescu
67849ca418 Adjust button styling 2025-10-17 09:18:05 +09:00
Dan Balasescu
0777bdbfc5 Add screen title 2025-10-17 09:18:05 +09:00
Dan Balasescu
798f6bdcc7 Fix padding not considered in sizing 2025-10-17 09:18:05 +09:00
Dan Balasescu
f38162c550 Fix padding as subscreen 2025-10-17 09:18:05 +09:00
Dan Balasescu
b663fe17ab Fix tests 2025-10-17 09:18:04 +09:00
Dan Balasescu
3c1d45b896 Integrate v2 playlists song select with game 2025-10-17 09:16:47 +09:00
Dan Balasescu
259bc53699 Add initial playlist button 2025-10-17 09:16:46 +09:00
Dan Balasescu
87834d1693 Add overall mods/freemods/freestyle hookups 2025-10-17 09:16:46 +09:00
Dan Balasescu
f1539167eb Add initial freestyle button 2025-10-17 09:16:46 +09:00
Dan Balasescu
ff6f797a3e Add initial freemods button 2025-10-17 09:16:46 +09:00
Dan Balasescu
bfa45a23ce Add initial screen + test structure 2025-10-17 09:16:46 +09: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
Dan Balasescu
c80fe7ab82 Use new implementation in ScreenTestScene 2025-10-16 20:37:24 +09:00
Dan Balasescu
d85c2ee623 Isolate footer behaviour to ScreenStackFooter, support subscreens 2025-10-16 20:37:24 +09:00
Dan Balasescu
b4b26e3a1d Remove song select dependency from FooterButtonOptions 2025-10-16 20:28:26 +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
Bartłomiej Dach
1867aad1a6 Merge branch 'master' into screen-scaling-tablet-output 2025-10-02 08:14:15 +02: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
Du Yijie
b1bc5cae87 Merge branch 'master' into legacy-pp-counter 2025-09-15 14:41:45 +08: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
Daniel Power
038bf3fdda "Conform to aspect ratio" uses scaled area 2025-08-27 20:11:28 -02:30
Daniel Power
61c3aad537 Fix conflict 2025-08-27 20:00:56 -02:30
Daniel Power
3aad0868af Remove duplicated declarations 2025-08-27 19:57:58 -02:30
Daniel Power
973c4c8319 Merge branch 'master' of github.com:ppy/osu into screen-scaling-tablet-output 2025-08-27 19:46:18 -02:30
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
Du Yijie
ac21f8b960 Implement "legacy" pp counter
There is no pp counter in osu!(stable). However, a "legacy" pp counter
allows skinners to more easily fit a pp counter into their skin's theme.
2025-08-27 11:07:53 +08: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
490137405f added installer build script, adapted autoupdates (not functional yet) 2025-08-22 22:26:17 +03:00
f3c6f53f70 added version to 'experimental version' banner 2025-08-22 20:19:18 +03:00
8cb5c682b4 make seasonal bg config strings localisable 2025-08-22 19:07:15 +03:00
c3d79295d3 made seasonal background notifications transient 2025-08-22 16:07:28 +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
Daniel Power
0b3b6468a5 Reflect tablet output area changes in osu-framework 2025-08-16 23:02:28 -02:30
Daniel Power
7d1c54f045 Merge branch 'master' of github.com:ppy/osu into screen-scaling-tablet-output 2025-08-16 22:53:41 -02:30
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
Daniel Power
fd504e5641 Minor cleanup 2024-12-16 23:17:22 -03:30
Daniel Power
93ed0483b6 Fix TestSceneTabletSettings 2024-12-16 22:59:04 -03:30
Daniel Power
4dd0672aa5 Address screen scale positioning 2024-12-16 21:04:08 -03:30
Daniel Power
66eff14d2b Initial proof of concept for tablet output scaling 2024-12-16 01:17:35 -03:30
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
1471 changed files with 57755 additions and 23036 deletions

View File

@@ -21,7 +21,7 @@
] ]
}, },
"ppy.localisationanalyser.tools": { "ppy.localisationanalyser.tools": {
"version": "2024.802.0", "version": "2025.1208.0",
"commands": [ "commands": [
"localisation" "localisation"
] ]

View File

@@ -19,6 +19,11 @@ indent_style = space
indent_size = 4 indent_size = 4
trim_trailing_whitespace = true 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 #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. 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: contact_links:
- name: Help - name: Help
url: https://github.com/ppy/osu/discussions/categories/q-a url: https://t.me/jvnkosu_chat
about: osu! not working or performing as you'd expect? Not sure it's a bug? Check the Q&A section! about: Your jvnkosu! is not working right? Please contact us using our Telegram chat
- 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.

View File

@@ -1,8 +1,10 @@
name: Update osu-web mod definitions name: Update osu-web mod definitions (DO NOT USE YET!!!!!)
on: on:
push: workflow_dispatch:
tags: # push:
- '*' # tags:
# - '*'
permissions: permissions:
contents: read # to fetch code (actions/checkout) 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 name: Continuous Integration
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} 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') }} key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
- name: Dotnet code style - 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 - name: CodeFileSanity
run: | run: |
@@ -148,9 +154,7 @@ jobs:
# https://github.com/dotnet/macios/issues/19157 # https://github.com/dotnet/macios/issues/19157
# https://github.com/actions/runner-images/issues/12758 # https://github.com/actions/runner-images/issues/12758
- name: Use Xcode 16.4 - name: Use Xcode 16.4
run: | run: sudo xcode-select -switch /Applications/Xcode_16.4.app
sudo xcode-select -switch /Applications/Xcode_16.4.app
xcodebuild -downloadPlatform iOS
- name: Build - name: Build
run: dotnet build -c Debug osu.iOS.slnf run: dotnet build -c Debug osu.iOS.slnf

View File

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

View File

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

1
.gitignore vendored
View File

@@ -19,6 +19,7 @@ bld/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
[Ll]og/ [Ll]og/
[Pp]ub/
# Visual Studio 2015 cache/options directory # Visual Studio 2015 cache/options directory
.vs/ .vs/

36
.vscode/launch.json vendored
View File

@@ -7,9 +7,9 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll" "${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build osu! (Debug)", "preLaunchTask": "Build osu! (Debug)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -19,9 +19,9 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll" "${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build osu! (Release)", "preLaunchTask": "Build osu! (Release)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -31,9 +31,9 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll" "${workspaceFolder}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build tests (Debug)", "preLaunchTask": "Build tests (Debug)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -43,9 +43,9 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll" "${workspaceFolder}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build tests (Release)", "preLaunchTask": "Build tests (Release)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -55,10 +55,10 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll", "${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build osu! (Debug)", "preLaunchTask": "Build osu! (Debug)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -68,10 +68,10 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll", "${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build osu! (Release)", "preLaunchTask": "Build osu! (Release)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -81,10 +81,10 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll", "${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build tournament tests (Debug)", "preLaunchTask": "Build tournament tests (Debug)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -94,10 +94,10 @@
"request": "launch", "request": "launch",
"program": "dotnet", "program": "dotnet",
"args": [ "args": [
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll", "${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
"--tournament" "--tournament"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build tournament tests (Release)", "preLaunchTask": "Build tournament tests (Release)",
"console": "internalConsole" "console": "internalConsole"
}, },
@@ -105,12 +105,12 @@
"name": "Benchmark", "name": "Benchmark",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll", "program": "${workspaceFolder}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll",
"args": [ "args": [
"--filter", "--filter",
"*" "*"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"preLaunchTask": "Build benchmarks", "preLaunchTask": "Build benchmarks",
"console": "internalConsole" "console": "internalConsole"
} }

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

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

View File

@@ -55,9 +55,7 @@ When in doubt, it's probably best to start with a discussion first. We will esca
While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change. While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change.
The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. We also have a [`good first issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label, although from experience it is not used very often, as it is relatively rare that we can spot an issue that will definitively be a good first issue for a new contributor regardless of their programming experience. The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! Figma master library](https://www.figma.com/file/VIkXMYNPMtQem2RJg9k2iQ/Master-Library). If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! Figma master library](https://www.figma.com/file/VIkXMYNPMtQem2RJg9k2iQ/Master-Library).
@@ -73,6 +71,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: 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 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 avoid pushing untested or incomplete code.
- Please do not force-push or rebase unless we ask you to. - 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. - 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> <PackageProjectUrl>https://github.com/ppy/osu</PackageProjectUrl>
<RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl> <RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl>
<PackageReleaseNotes>Automated release.</PackageReleaseNotes> <PackageReleaseNotes>Automated release.</PackageReleaseNotes>
<Company>ppy Pty Ltd</Company> <Company>ppy Pty Ltd, jvnkosu! team</Company>
<Copyright>Copyright (c) 2025 ppy Pty Ltd</Copyright> <Copyright>Copyright (c) 2025 ppy Pty Ltd</Copyright>
<PackageTags>osu game</PackageTags> <PackageTags>osu game</PackageTags>
</PropertyGroup> </PropertyGroup>

19
MakeInstaller.ps1 Normal file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env powershell
param (
[string]$Version,
[string]$BuildConfig = "Release"
)
if ($Version -eq "") {
Write-Host "Usage: .\MakeInstaller.ps1 <VERSION_NUMBER> [-BuildConfig <BUILD_CONFIG>]"
Write-Host "Example: .\MakeInstaller.ps1 2025.823.0 -BuildConfig Debug"
exit
}
$tmpPub = ".\pub"
if (-not (Test-Path -Path $tmpPub)) {
New-Item -ItemType Directory -path $tmpPub
}
dotnet publish -c $BuildConfig osu.Desktop --self-contained -r win-x64 -o $tmpPub -verbosity:m /p:Version=$Version
vpk pack --packId jvnkosu.Client --packTitle "jvnkosu!lazer" --packVersion $Version --packDir ./pub --mainExe="osu!.exe"

149
README.md
View File

@@ -1,147 +1,40 @@
<p align="center"> # jvnkosu! client
<img width="500" alt="osu! logo" src="assets/lazer.png">
</p>
# 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) ## Disclaimer
[![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! *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). 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.
- 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! 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:
```
If you are just looking to give the game a whirl, you can grab the latest release for your platform: git clone https://gitea.jvnko.boats/jvnkosu/client
### 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 To **run** the project, switch to project's directory and run the following:
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 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). To **compile**:
```
If the build fails, try to restore NuGet packages with `dotnet restore`. dotnet build osu.Desktop
### 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: 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 ### See the [original readme](README.original.md) for more info.
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.

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

View File

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

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?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" /> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
<application android:allowBackup="true" <application android:allowBackup="true"
android:supportsRtl="true" android:supportsRtl="true"

View File

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

View File

@@ -118,7 +118,7 @@ namespace osu.Desktop
if (IsPackageManaged) if (IsPackageManaged)
return new NoActionUpdateManager(); return new NoActionUpdateManager();
return new VelopackUpdateManager(); return new VelopackUpdateManager(); // yay
} }
public override bool RestartAppWhenExited() public override bool RestartAppWhenExited()
@@ -148,7 +148,13 @@ namespace osu.Desktop
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico"); var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
if (iconStream != null) if (iconStream != null)
host.Window.SetIconFromStream(iconStream); try
{
host.Window.SetIconFromStream(iconStream);
}
catch
{
}
host.Window.Title = Name; 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. // 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/ // 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 unsafe
{ {
@@ -53,13 +53,26 @@ namespace osu.Desktop
// We could also better detect compatibility mode if required: // 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 // 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, SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
"Your operating system is too old to run osu!"u8, "Your operating system is too old to run this game!"u8,
"This version of osu! requires at least Windows 8.1 to run.\n"u8 "This version of the game requires at least Windows 8.1 to run reliably.\n"u8
+ "Please upgrade your operating system or consider using an older version of osu!.\n\n"u8 + "You may try to run it on Windows 8 or older, but it's not guaranteed to actually work.\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); + "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; 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. // NVIDIA profiles are based on the executable name of a process.
@@ -208,9 +221,10 @@ namespace osu.Desktop
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
private static void configureWindows(VelopackApp app) private static void configureWindows(VelopackApp app)
{ {
app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations()); // we do not want associations here, as that breaks official lazer's associations
app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations()); // app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations()); // app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
// app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
} }
} }
} }

View File

@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Localisation;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
@@ -32,7 +33,7 @@ namespace osu.Desktop.Security
{ {
public ElevatedPrivilegesNotification() public ElevatedPrivilegesNotification()
{ {
Text = $"Running osu! as {(RuntimeInfo.IsUnix ? "root" : "administrator")} does not improve performance, may break integrations and poses a security risk. Please run the game as a normal user."; Text = NotificationsStrings.ElevatedPrivileges(RuntimeInfo.IsUnix ? "root" : "Administrator");
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@@ -55,7 +55,7 @@ namespace osu.Desktop.Updater
try 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 Velopack.UpdateManager updateManager = new Velopack.UpdateManager(updateSource, new UpdateOptions
{ {
AllowVersionDowngrade = true AllowVersionDowngrade = true

View File

@@ -53,8 +53,8 @@ namespace osu.Desktop.Windows
private static readonly UriAssociation[] uri_associations = private static readonly UriAssociation[] uri_associations =
{ {
new UriAssociation(@"osu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer), new UriAssociation(@"jvnkosu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
new UriAssociation(@"osump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer), new UriAssociation(@"jvnkosump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
}; };
/// <summary> /// <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> <TargetFramework>net8.0</TargetFramework>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <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> <AssemblyName>osu!</AssemblyName>
<AssemblyTitle>osu!(lazer)</AssemblyTitle> <AssemblyTitle>jvnkosu!</AssemblyTitle>
<Title>osu!</Title> <Title>jvnkosu!</Title>
<Product>osu!(lazer)</Product> <Product>jvnkosu!</Product>
<ApplicationIcon>lazer.ico</ApplicationIcon> <ApplicationIcon>lazer.ico</ApplicationIcon>
<Version>0.0.0</Version> <Version>0.0.0</Version>
<FileVersion>0.0.0</FileVersion> <FileVersion>0.0.0</FileVersion>

View File

@@ -3,16 +3,19 @@
<metadata> <metadata>
<id>osulazer</id> <id>osulazer</id>
<version>0.0.0</version> <version>0.0.0</version>
<title>osu!</title> <title>jvnkosu!</title>
<authors>ppy Pty Ltd</authors> <authors>ppy Pty Ltd., jvnkosu! team</authors>
<owners>Dean Herbert</owners> <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> <iconUrl>https://github.com/ppy/osu/blob/master/assets/lazer-nuget.png?raw=true</iconUrl>
<icon>icon.png</icon> <icon>icon.png</icon>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <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> <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> <language>en-AU</language>
</metadata> </metadata>
<files> <files>

View File

@@ -5,7 +5,7 @@ using BenchmarkDotNet.Attributes;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel; using osu.Game.Tests.NonVisual.Filtering;
namespace osu.Game.Benchmarks namespace osu.Game.Benchmarks
{ {
@@ -42,7 +42,7 @@ namespace osu.Game.Benchmarks
Status = BeatmapOnlineStatus.Loved Status = BeatmapOnlineStatus.Loved
}; };
private CarouselBeatmap carouselBeatmap = null!; private FilterMatchingTest.CarouselBeatmap carouselBeatmap = null!;
private FilterCriteria criteria1 = null!; private FilterCriteria criteria1 = null!;
private FilterCriteria criteria2 = null!; private FilterCriteria criteria2 = null!;
private FilterCriteria criteria3 = null!; private FilterCriteria criteria3 = null!;
@@ -55,7 +55,7 @@ namespace osu.Game.Benchmarks
var beatmap = getExampleBeatmap(); var beatmap = getExampleBeatmap();
beatmap.OnlineID = 20201010; beatmap.OnlineID = 20201010;
beatmap.BeatmapSet = new BeatmapSetInfo { OnlineID = 1535 }; beatmap.BeatmapSet = new BeatmapSetInfo { OnlineID = 1535 };
carouselBeatmap = new CarouselBeatmap(beatmap); carouselBeatmap = new FilterMatchingTest.CarouselBeatmap(beatmap);
criteria1 = new FilterCriteria(); criteria1 = new FilterCriteria();
criteria2 = new FilterCriteria criteria2 = new FilterCriteria
{ {

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();
}
}
}
}

View File

@@ -35,8 +35,6 @@
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
</array> </array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true/>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>

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] [Test]
public void TestTinyDropletMissPreservesCatcherState() public void TestTinyDropletMissChangesCatcherState()
{ {
AddStep("catch hyper kiai fruit", () => attemptCatch(new TestKiaiFruit 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("catch tiny droplet", () => attemptCatch(new TinyDroplet()));
AddStep("miss tiny droplet", () => attemptCatch(new TinyDroplet { X = 100 })); AddStep("miss tiny droplet", () => attemptCatch(new TinyDroplet { X = 100 }));
// catcher state and hyper dash state is preserved // catcher state is changed but hyper dash state is preserved
checkState(CatcherAnimationState.Kiai); checkState(CatcherAnimationState.Fail);
checkHyperDash(true); checkHyperDash(true);
} }

View File

@@ -176,15 +176,20 @@ namespace osu.Game.Rulesets.Catch
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch }; public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
protected override IEnumerable<HitResult> GetValidHitResults() public override IEnumerable<HitResult> GetValidHitResults()
{ {
return new[] return new[]
{ {
HitResult.Great, HitResult.Great,
HitResult.Miss,
HitResult.LargeTickHit, HitResult.LargeTickHit,
HitResult.LargeTickMiss,
HitResult.SmallTickHit, HitResult.SmallTickHit,
HitResult.SmallTickMiss,
HitResult.LargeBonus, HitResult.LargeBonus,
HitResult.IgnoreHit,
HitResult.IgnoreMiss,
}; };
} }
@@ -300,7 +305,7 @@ namespace osu.Game.Rulesets.Catch
Description = "Affects how early fruits fade in on the screen.", Description = "Affects how early fruits fade in on the screen.",
AdditionalMetrics = AdditionalMetrics =
[ [
new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms")) new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRangeInt(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))
] ]
}; };
yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10) yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10)

View File

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

View File

@@ -3,13 +3,13 @@
using System; using System;
using System.Linq; using System.Linq;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Scoring.Legacy; using osu.Game.Scoring.Legacy;
using osu.Game.Utils;
namespace osu.Game.Rulesets.Catch.Difficulty namespace osu.Game.Rulesets.Catch.Difficulty
{ {
@@ -51,15 +51,13 @@ namespace osu.Game.Rulesets.Catch.Difficulty
// Combo scaling // Combo scaling
if (catchAttributes.MaxCombo > 0) 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(); var difficulty = score.BeatmapInfo!.Difficulty.Clone();
score.Mods.OfType<IApplicableToDifficulty>().ForEach(m => m.ApplyToDifficulty(difficulty)); score.Mods.OfType<IApplicableToDifficulty>().ForEach(m => m.ApplyToDifficulty(difficulty));
var track = new TrackVirtual(10000); double clockRate = ModUtils.CalculateRateWithMods(score.Mods);
score.Mods.OfType<IApplicableToTrack>().ForEach(m => m.ApplyToTrack(track));
double clockRate = track.Rate;
// this is the same as osu!, so there's potential to share the implementation... maybe // 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; 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 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 BaseObject => (PalpableCatchHitObject)base.BaseObject;
public new PalpableCatchHitObject LastObject => (PalpableCatchHitObject)base.LastObject; public new PalpableCatchHitObject LastObject => (PalpableCatchHitObject)base.LastObject;
/// <summary>
/// Normalized position of <see cref="BaseObject"/>.
/// </summary>
public readonly float NormalizedPosition; public readonly float NormalizedPosition;
/// <summary>
/// Normalized position of <see cref="LastObject"/>.
/// </summary>
public readonly float LastNormalizedPosition; 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> /// <summary>
/// Milliseconds elapsed since the start time of the previous <see cref="CatchDifficultyHitObject"/>, with a minimum of 40ms. /// Milliseconds elapsed since the start time of the previous <see cref="CatchDifficultyHitObject"/>, with a minimum of 40ms.
/// </summary> /// </summary>
@@ -29,13 +63,35 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
: base(hitObject, lastObject, clockRate, objects, index) : base(hitObject, lastObject, clockRate, objects, index)
{ {
// We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps. // 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; NormalizedPosition = BaseObject.EffectiveX * scalingFactor;
LastNormalizedPosition = LastObject.EffectiveX * scalingFactor; LastNormalizedPosition = LastObject.EffectiveX * scalingFactor;
// Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure // Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure
StrainTime = Math.Max(40, DeltaTime); 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. // 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. // See the LICENCE file in the repository root for full licence text.
using System; using osu.Game.Rulesets.Catch.Difficulty.Evaluators;
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@@ -11,10 +10,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
{ {
public class Movement : StrainDecaySkill 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 SkillMultiplier => 1;
protected override double StrainDecayBase => 0.2; protected override double StrainDecayBase => 0.2;
@@ -24,12 +19,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
protected readonly float HalfCatcherWidth; protected readonly float HalfCatcherWidth;
private float? lastPlayerPosition;
private float lastDistanceMoved;
private float lastExactDistanceMoved;
private double lastStrainTime;
private bool isInBuzzSection;
/// <summary> /// <summary>
/// The speed multiplier applied to the player's catcher. /// The speed multiplier applied to the player's catcher.
/// </summary> /// </summary>
@@ -49,80 +38,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
protected override double StrainValueOf(DifficultyHitObject current) protected override double StrainValueOf(DifficultyHitObject current)
{ {
var catchCurrent = (CatchDifficultyHitObject)current; return MovementEvaluator.EvaluateDifficultyOf(current, catcherSpeedMultiplier);
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;
} }
} }
} }

View File

@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private double placementStartTime; private double placementStartTime;
private double placementEndTime; 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() public BananaShowerPlacementBlueprint()
{ {

View File

@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private InputManager inputManager = null!; 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() public JuiceStreamPlacementBlueprint()
{ {

View File

@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@@ -224,7 +225,8 @@ namespace osu.Game.Rulesets.Catch.Edit
#region Clipboard handling #region Clipboard handling
public override string ConvertSelectionToString() 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 ... // 1,2,3,4 ...
private static readonly Regex selection_regex = new Regex(@"^\d+(,\d+)*$", RegexOptions.Compiled); 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; 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 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); protected override Flashlight CreateFlashlight() => new CatchFlashlight(this, playfield);

View File

@@ -3,6 +3,7 @@
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
@@ -16,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Mods
public override string Acronym => "FF"; public override string Acronym => "FF";
public override LocalisableString Description => "The fruits are... floating?"; public override LocalisableString Description => "The fruits are... floating?";
public override double ScoreMultiplier => 1; public override double ScoreMultiplier => 1;
public override IconUsage? Icon => FontAwesome.Solid.Cloud; public override IconUsage? Icon => OsuIcon.ModFloatingFruits;
public void ApplyToDrawableRuleset(DrawableRuleset<CatchHitObject> drawableRuleset) 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.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Mods; 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 LocalisableString Description => "Dashing by default, slow down!";
public override ModType Type => ModType.Fun; public override ModType Type => ModType.Fun;
public override double ScoreMultiplier => 1; 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) }; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax) };
private DrawableCatchRuleset drawableRuleset = null!; private DrawableCatchRuleset drawableRuleset = null!;

View File

@@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@@ -53,13 +54,25 @@ namespace osu.Game.Rulesets.Catch.Objects
public override IEnumerable<string> LookupNames => lookup_names; public override IEnumerable<string> LookupNames => lookup_names;
public BananaHitSampleInfo(int volume = 100) public BananaHitSampleInfo()
: base(string.Empty, volume: volume) : 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) public BananaHitSampleInfo(HitSampleInfo info)
=> new BananaHitSampleInfo(newVolume.GetOr(Volume)); : 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) public bool Equals(BananaHitSampleInfo? other)
=> other != null; => other != null;

View File

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

View File

@@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{ {
base.ApplyDefaultsToSelf(controlPointInfo, difficulty); base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_RANGE); TimePreempt = IBeatmapDifficultyInfo.DifficultyRangeInt(difficulty.ApproachRate, PREEMPT_RANGE);
Scale = LegacyRulesetExtensions.CalculateScaleFromCircleSize(difficulty.CircleSize); Scale = LegacyRulesetExtensions.CalculateScaleFromCircleSize(difficulty.CircleSize);
} }

View File

@@ -72,6 +72,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
leaderboard.Origin = Anchor.CentreLeft; leaderboard.Origin = Anchor.CentreLeft;
leaderboard.X = 10; leaderboard.X = 10;
} }
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
}) })
{ {
Children = new Drawable[] Children = new Drawable[]

View File

@@ -224,7 +224,20 @@ namespace osu.Game.Rulesets.Catch.UI
addLighting(result, drawableObject.AccentColour.Value, positionInStack.X); 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 (hitObject is TinyDroplet) return;
// if a hyper fruit was already handled this frame, just go where it says to go. // 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 else
SetHyperDashState(); 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) public void OnRevertResult(JudgementResult result)

View File

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

View File

@@ -35,8 +35,6 @@
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
</array> </array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true/>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>

View File

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

View File

@@ -18,15 +18,11 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
public void TestNormalSelection() public void TestNormalSelection()
{ {
addStepClickLink("00:05:920 (5920|3,6623|3,6857|2,7326|1)"); addStepClickLink("00:05:920 (5920|3,6623|3,6857|2,7326|1)");
AddAssert("selected group", () => checkSnapAndSelectColumn(5_920, new List<(int, int)> AddAssert("selected group", () => checkSnapAndSelectColumn(5_920, [(5_920, 3), (6_623, 3), (6_857, 2), (7_326, 1)]));
{ (5_920, 3), (6_623, 3), (6_857, 2), (7_326, 1) }
));
addReset(); addReset();
addStepClickLink("00:42:716 (42716|3,43420|2,44123|0,44357|1,45295|1)"); addStepClickLink("00:42:716 (42716|3,43420|2,44123|0,44357|1,45295|1)");
AddAssert("selected ungrouped", () => checkSnapAndSelectColumn(42_716, new List<(int, int)> AddAssert("selected ungrouped", () => checkSnapAndSelectColumn(42_716, [(42_716, 3), (43_420, 2), (44_123, 0), (44_357, 1), (45_295, 1)]));
{ (42_716, 3), (43_420, 2), (44_123, 0), (44_357, 1), (45_295, 1) }
));
addReset(); addReset();
AddStep("add notes to row", () => AddStep("add notes to row", () =>
@@ -41,15 +37,20 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
EditorBeatmap.AddRange(new[] { second, third, forth }); EditorBeatmap.AddRange(new[] { second, third, forth });
}); });
addStepClickLink("00:11:545 (11545|0,11545|1,11545|2,11545|3)"); addStepClickLink("00:11:545 (11545|0,11545|1,11545|2,11545|3)");
AddAssert("selected in row", () => checkSnapAndSelectColumn(11_545, new List<(int, int)> AddAssert("selected in row", () => checkSnapAndSelectColumn(11_545, [(11_545, 0), (11_545, 1), (11_545, 2), (11_545, 3)]));
{ (11_545, 0), (11_545, 1), (11_545, 2), (11_545, 3) }
));
addReset(); addReset();
addStepClickLink("01:36:623 (96623|1,97560|1,97677|1,97795|1,98966|1)"); 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)> AddAssert("selected in column", () => checkSnapAndSelectColumn(96_623, [(96_623, 1), (97_560, 1), (97_677, 1), (97_795, 1), (98_966, 1)]));
{ (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] [Test]
@@ -75,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
private void addReset() => addStepClickLink("00:00:000", "reset", false); 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 bool checkColumns = columnPairs != null
? EditorBeatmap.SelectedHitObjects.All(x => columnPairs.Any(col => isNoteAt(x, col.Item1, col.Item2))) ? 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-samples")]
[TestCase("mania-slider")] // e.g. second and fourth notes of https://osu.ppy.sh/beatmapsets/73883#mania/216407 [TestCase("mania-slider")] // e.g. second and fourth notes of https://osu.ppy.sh/beatmapsets/73883#mania/216407
[TestCase("slider-convert-samples")] [TestCase("slider-convert-samples")]
[TestCase("spinner-convert-samples")]
public void Test(string name) => base.Test(name); public void Test(string name) => base.Test(name);
protected override IEnumerable<SampleConvertValue> CreateConvertValue(HitObject hitObject) protected override IEnumerable<SampleConvertValue> CreateConvertValue(HitObject hitObject)

View File

@@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Tests
} }
[TestCase] [TestCase]
public void TestFilterIntersection() public void TestKeysFilterIntersection()
{ {
var criteria = new ManiaFilterCriteria(); var criteria = new ManiaFilterCriteria();
criteria.TryParseCustomKeywordCriteria("keys", Operator.Greater, "4"); criteria.TryParseCustomKeywordCriteria("keys", Operator.Greater, "4");
@@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Mania.Tests
} }
[TestCase] [TestCase]
public void TestInvalidFilters() public void TestInvalidKeysFilters()
{ {
var criteria = new ManiaFilterCriteria(); 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.NotEqual, "4,some text"));
Assert.False(criteria.TryParseCustomKeywordCriteria("keys", Operator.GreaterOrEqual, "4,5,6")); 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); AssertBeatmapLookup(expected_sample);
AssertNoLookup(unwanted_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, Duration = endTime - HitObject.StartTime,
Column = column, Column = column,
Samples = HitObject.Samples, Samples = HitObject.Samples,
NodeSamples = (HitObject as IHasRepeats)?.NodeSamples NodeSamples =
[
HitObject.Samples.Where(s => s.Name == HitSampleInfo.HIT_NORMAL).ToList(),
HitObject.Samples
]
}; };
} }
else 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) protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
{ {
var sortedObjects = beatmap.HitObjects.ToArray(); 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))); 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> 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++) 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; return objects;
} }

View File

@@ -12,9 +12,59 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Preprocessing
{ {
public new ManiaHitObject BaseObject => (ManiaHitObject)base.BaseObject; 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) : 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. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using osu.Framework.Utils;
using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills; 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.Mania.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mods; 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 individual_decay_base = 0.125;
private const double overall_decay_base = 0.30; private const double overall_decay_base = 0.30;
private const double release_threshold = 30;
protected override double SkillMultiplier => 1; protected override double SkillMultiplier => 1;
protected override double StrainDecayBase => 1; protected override double StrainDecayBase => 1;
private readonly double[] startTimes;
private readonly double[] endTimes;
private readonly double[] individualStrains; private readonly double[] individualStrains;
private double highestIndividualStrain;
private double individualStrain;
private double overallStrain; private double overallStrain;
public Strain(Mod[] mods, int totalColumns) public Strain(Mod[] mods, int totalColumns)
: base(mods) : base(mods)
{ {
startTimes = new double[totalColumns];
endTimes = new double[totalColumns];
individualStrains = new double[totalColumns]; individualStrains = new double[totalColumns];
overallStrain = 1; overallStrain = 1;
} }
@@ -39,65 +32,24 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Skills
protected override double StrainValueOf(DifficultyHitObject current) protected override double StrainValueOf(DifficultyHitObject current)
{ {
var maniaCurrent = (ManiaDifficultyHitObject)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 individualStrains[maniaCurrent.Column] = applyDecay(individualStrains[maniaCurrent.Column], maniaCurrent.ColumnStrainTime, individual_decay_base);
double holdFactor = 1.0; // Factor to all additional strains in case something else is held individualStrains[maniaCurrent.Column] += IndividualStrainEvaluator.EvaluateDifficultyOf(current);
double holdAddition = 0; // Addition to the current note in case it's a hold and has to be released awkwardly
for (int i = 0; i < endTimes.Length; ++i) // 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.
// The current note is overlapped if a previous note or end is overlapping the current note body highestIndividualStrain = maniaCurrent.DeltaTime <= 1 ? Math.Max(highestIndividualStrain, individualStrains[maniaCurrent.Column]) : individualStrains[maniaCurrent.Column];
isOverlapping |= Precision.DefinitelyBigger(endTimes[i], startTime, 1) &&
Precision.DefinitelyBigger(endTime, endTimes[i], 1) &&
Precision.DefinitelyBigger(startTime, startTimes[i], 1);
// We give a slight bonus to everything if something is held meanwhile overallStrain = applyDecay(overallStrain, maniaCurrent.DeltaTime, overall_decay_base);
if (Precision.DefinitelyBigger(endTimes[i], endTime, 1) && overallStrain += OverallStrainEvaluator.EvaluateDifficultyOf(current);
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;
// By subtracting CurrentStrain, this skill effectively only considers the maximum strain of any one hitobject within each strain section. // 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) protected override double CalculateInitialStrain(double offset, DifficultyHitObject current) =>
=> applyDecay(individualStrain, offset - current.Previous(0).StartTime, individual_decay_base) applyDecay(highestIndividualStrain, offset - current.Previous(0).StartTime, individual_decay_base)
+ applyDecay(overallStrain, offset - current.Previous(0).StartTime, overall_decay_base); + applyDecay(overallStrain, offset - current.Previous(0).StartTime, overall_decay_base);
private double applyDecay(double value, double deltaTime, double decayBase) private double applyDecay(double value, double deltaTime, double decayBase)
=> value * Math.Pow(decayBase, deltaTime / 1000); => value * Math.Pow(decayBase, deltaTime / 1000);

View File

@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
[Resolved] [Resolved]
private IScrollingInfo scrollingInfo { get; set; } = null!; 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() public HoldNotePlacementBlueprint()
: base(new HoldNote()) : base(new HoldNote())

View File

@@ -1,10 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Utils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
@@ -54,7 +56,8 @@ namespace osu.Game.Rulesets.Mania.Edit
}; };
public override string ConvertSelectionToString() 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 ... // 123|0,456|1,789|2 ...
private static readonly Regex selection_regex = new Regex(@"^\d+\|\d+(,\d+\|\d+)*$", RegexOptions.Compiled); 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) if (split.Length != 2)
continue; 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; 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) if (current == null)
continue; continue;

View File

@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Bindables; using osu.Framework.Bindables;
@@ -19,12 +20,16 @@ namespace osu.Game.Rulesets.Mania
public class ManiaFilterCriteria : IRulesetFilterCriteria public class ManiaFilterCriteria : IRulesetFilterCriteria
{ {
private readonly HashSet<int> includedKeyCounts = Enumerable.Range(1, LegacyBeatmapDecoder.MAX_MANIA_KEY_COUNT).ToHashSet(); 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) public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria)
{ {
int keyCount = ManiaBeatmapConverter.GetColumnCount(LegacyBeatmapConversionDifficultyInfo.FromBeatmapInfo(beatmapInfo), criteria.Mods); 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) public bool TryParseCustomKeywordCriteria(string key, Operator op, string strValues)
@@ -84,6 +89,10 @@ namespace osu.Game.Rulesets.Mania
return false; return false;
} }
} }
case "ln":
case "lns":
return FilterQueryParser.TryUpdateCriteriaRange(ref longNotePercentage, op, strValues);
} }
return false; return false;
@@ -103,5 +112,18 @@ namespace osu.Game.Rulesets.Mania
return false; 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); return new ManiaArgonSkinTransformer(skin, beatmap);
case DefaultLegacySkin: case DefaultLegacySkin:
case RetroSkin:
return new ManiaClassicSkinTransformer(skin, beatmap); return new ManiaClassicSkinTransformer(skin, beatmap);
case LegacySkin: case LegacySkin:
@@ -382,7 +383,7 @@ namespace osu.Game.Rulesets.Mania
return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderDescending().First(v => variant >= v); return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderDescending().First(v => variant >= v);
} }
protected override IEnumerable<HitResult> GetValidHitResults() public override IEnumerable<HitResult> GetValidHitResults()
{ {
return new[] return new[]
{ {
@@ -391,9 +392,11 @@ namespace osu.Game.Rulesets.Mania
HitResult.Good, HitResult.Good,
HitResult.Ok, HitResult.Ok,
HitResult.Meh, HitResult.Meh,
HitResult.Miss,
// HitResult.SmallBonus is used for awarding perfect bonus score but is not included here as HitResult.IgnoreHit,
// it would be a bit redundant to show this to the user. HitResult.ComboBreak,
HitResult.IgnoreMiss,
}; };
} }

View File

@@ -7,7 +7,7 @@ using osu.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.Configuration;
@@ -31,47 +31,45 @@ namespace osu.Game.Rulesets.Mania
Children = new Drawable[] Children = new Drawable[]
{ {
new SettingsEnumDropdown<ManiaScrollingDirection> new SettingsItemV2(new FormEnumDropdown<ManiaScrollingDirection>
{ {
LabelText = RulesetSettingsStrings.ScrollingDirection, Caption = RulesetSettingsStrings.ScrollingDirection,
Current = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection) Current = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection)
}, }),
new SettingsSlider<double, ManiaScrollSlider> new SettingsItemV2(new FormSliderBar<double>
{ {
LabelText = RulesetSettingsStrings.ScrollSpeed, Caption = RulesetSettingsStrings.ScrollSpeed,
Current = config.GetBindable<double>(ManiaRulesetSetting.ScrollSpeed), Current = config.GetBindable<double>(ManiaRulesetSetting.ScrollSpeed),
KeyboardStep = 1 KeyboardStep = 1,
}, LabelFormat = v => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(v), v),
new SettingsCheckbox }),
new SettingsItemV2(new FormCheckBox
{
Caption = RulesetSettingsStrings.TimingBasedColouring,
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
})
{ {
Keywords = new[] { "color" }, Keywords = new[] { "color" },
LabelText = RulesetSettingsStrings.TimingBasedColouring,
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
}, },
}; };
Add(new SettingsCheckbox Add(new SettingsItemV2(new FormCheckBox
{ {
LabelText = RulesetSettingsStrings.TouchOverlay, Caption = RulesetSettingsStrings.TouchOverlay,
Current = config.GetBindable<bool>(ManiaRulesetSetting.TouchOverlay) Current = config.GetBindable<bool>(ManiaRulesetSetting.TouchOverlay)
}); }));
if (RuntimeInfo.IsMobile) if (RuntimeInfo.IsMobile)
{ {
Add(new SettingsEnumDropdown<ManiaMobileLayout> Add(new SettingsItemV2(new FormEnumDropdown<ManiaMobileLayout>
{ {
LabelText = RulesetSettingsStrings.MobileLayout, Caption = RulesetSettingsStrings.MobileLayout,
Current = config.GetBindable<ManiaMobileLayout>(ManiaRulesetSetting.MobileLayout), Current = config.GetBindable<ManiaMobileLayout>(ManiaRulesetSetting.MobileLayout),
#pragma warning disable CS0618 // Type or member is obsolete #pragma warning disable CS0618 // Type or member is obsolete
Items = Enum.GetValues<ManiaMobileLayout>().Where(l => l != ManiaMobileLayout.LandscapeWithOverlay), Items = Enum.GetValues<ManiaMobileLayout>().Where(l => l != ManiaMobileLayout.LandscapeWithOverlay),
#pragma warning restore CS0618 // Type or member is obsolete #pragma warning restore CS0618 // Type or member is obsolete
}); }));
} }
} }
private partial class ManiaScrollSlider : RoundedSliderBar<double>
{
public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(Current.Value), Current.Value);
}
} }
} }

View File

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

View File

@@ -4,6 +4,7 @@
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods; 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 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; public override ModType Type => ModType.Conversion;

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