Kinda self explanatory, adds a second client configurations so its
easier to test multiplayer-specific things when using VSCode
For people that don't know how to use this, basically just run the first
debug like normal, then swap to the second client option and run that.
You can also do it in reverse. Visual guide here:
https://github.com/user-attachments/assets/1dab50eb-3bd2-422d-a776-852ac4454213
Example:
https://github.com/ppy/osu/actions/runs/23900675414/job/69696255970?pr=37178#step:5:38
Regressed in https://github.com/ppy/osu/pull/37172, cc @LiquidPL
Would fail in multiple tests. I'm not going to spend time figuring out
exactly why, I'm just going to guess that not all tests bother to set up
the relevant playlist items for the cards or whatever.
Some of the failing tests are flaky but not because the `item` here
isn't sometimes null in those cases. It's always null, but the callbacks
are probably scheduled or whatever and therefore have a chance to never
run. Also some of the failures appear to cascade / spill from other
tests as well.
Exposed by CI failures
([example](https://github.com/ppy/osu/actions/runs/23888446400#user-content-r0s0)).
The race occurs when a consumer calls `GetBindableDifficulty()` for the
first time and then a cache invalidation is triggered. The sequence of
events triggering the failure is as follows:
1. Consumer calls `GetBindableDifficulty()` to get a difficulty bindable
for a given beatmap tracking the game-global ruleset / mods. This
triggers difficulty calculation A.
2. In the meantime, another process requests a cache invalidation for
the same beatmap as the one supplied by the consumer in step (1). This
incurs a cache purge and triggers difficulty calculation B, but never
cancels difficulty calculation A.
3. Difficulty calculation B concludes and writes the correct, latest
difficulty value to the bindable.
4. Difficulty calculation A concludes and writes an incorrect, stale
difficulty value to the bindable.
See below for patch that reproduces this behaviour on my machine 100%
reliably:
```diff
diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs
index https://github.com/ppy/osu/commit/d6b40639161e26af223f03761b3826b0cd7f4a87..c9604e0e58 100644
--- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs
+++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs
@@ -252,17 +252,17 @@ private void updateBindable(BindableStarDifficulty bindable, IRulesetInfo? rules
GetDifficultyAsync(bindable.BeatmapInfo, rulesetInfo, mods, cancellationToken, computationDelay)
.ContinueWith(task =>
{
+ StarDifficulty? starDifficulty = task.GetResultSafely();
+
// We're on a threadpool thread, but we should exit back to the update thread so consumers can safely handle value-changed events.
- Schedule(() =>
+ Scheduler.AddDelayed(() =>
{
if (cancellationToken.IsCancellationRequested)
return;
- StarDifficulty? starDifficulty = task.GetResultSafely();
-
if (starDifficulty != null)
bindable.Value = starDifficulty.Value;
- });
+ }, starDifficulty?.Stars > 0 ? 400 : 0);
}, cancellationToken);
}
```
The goal of the patch is to reorder the write to the bindable in order
to trigger the scenario described above.
Due to the invasiveness of the patch it is not suitable to add as a
test, and chances are that the schedule delay may need to be tweaked if
anyone else wants to check that patch.
Anyway, the solution here is to use the same pattern of creating a
linked cancellation token even on the first retrieval of a bindable
difficulty, and registering it in the list of cancellation tokens that
already existed to service the ruleset- / mod-tracking flow.
Some extra rearranging in
https://github.com/ppy/osu/commit/9184299239a8b5e82957d46db33f1d26bab238fd
is needed to ensure the linked tokens created to do this don't stay
behind after they are no longer needed for anything.
- Last part of / closes
https://github.com/ppy/osu-server-spectator/issues/406.
- Remaining work on slots will be tracked in
https://github.com/ppy/osu-server-spectator/issues/405.
This PR is a corollary of
https://github.com/ppy/osu-server-spectator/pull/453 and all of the
dispensations referee users in a multiplayer have received therein. The
goal here is to allow access to all relevant room management functions
even if the referee in question isn't host, as well as to disallow
access to all non-relevant functions to do with the actual match
gameplay.
I'm not going to lie, this logic *is* ugly. I would argue that it
already *was* ugly on `master` and my goal was to operate with as light
a touch as possible myself. But you could see this as copping out and
that I should try to refactor some of this. I will try - but only after
someone else's seen the initial approach and deemed it unsuitable.
The logic in `MatchStartControl` is awful - there are so many moving
pieces of state that dictate what can happen when with all the buttons,
and yes, I am making it worse here.
This time there is some test coverage. Not everything is covered, but
the coverage should be on par in all components and pieces of relevant
logic I touched that already had tests covering them. On that note,
please forgive the diffstat size, but the tests *are* most of that size.
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
## [Adjust CI test reporting to upstream action
changes](https://github.com/ppy/osu/commit/f736337b1acf311bf48fb8c39cae67c3f172608d)
It's been semi-broken since I bumped it a few weeks ago. Paper trail for
this is at https://github.com/dorny/test-reporter/issues/750, but to
TL;DR it: `dorny/test-reporter@>=v2.0.0` migrated from [creating new
check runs via the GitHub
API](https://docs.github.com/en/rest/checks/runs) to [job
summaries](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands#adding-a-job-summary)
by default.
The main difference is that compared to check runs, job summaries do not
*appear to* require extra `GITHUB_TOKEN` permissions, but in exchange
are limited to the job that called it. This broke visibility of the test
reports because due to `GITHUB_TOKEN` permissions foibles the test
reporter was running in a separate workflow.
I see migrating as a plus here, since:
- The visibility of results is comparable-to-better (example available
for preview at https://github.com/bdach/osu/actions/runs/23892493152)
- No longer required to have a completely separate workflow for test
result reporting
- No longer required to give `checks: write` permissions to the action
(I'd hope, we'll see, untested on a public repository with PRs involved)
One downside is there'll be no in-code annotations for failing tests
anymore but that's whatever IMO. Half the time they weren't even very
helpful, test results pretty much require maintainer interpretation
anyway.
This needs to be applied to a few other repos but I'm starting here
because this is the one where the traffic is highest and therefore
unbreaking the report is of most value (and also the one where I'll see
if it works with public PRs the fastest).
Side note, I was hoping to remove the artifact upload/download games by
just attaching the summary inside each individual test job in the
matrix, but [it looks like
crap](https://github.com/bdach/osu-framework/actions/runs/23888384309)
because only the first three summaries are loaded by default, so if
there are more, you have to click each remaining one to see its output.
Wow. Awesome.
Also updates the action to `v3.0.0` to resolve node deprecation
warnings.
## [Update inspectcode version to resolve deprecation
warnings](https://github.com/ppy/osu/commit/496cf6890ecb6571e6361731d46f53cceb7cb584)
More node deprecation warning fixes.
Mod that colours HitObjects based on the musical division they are on,
now in osu!catch
https://github.com/user-attachments/assets/2dda493d-dc8b-4ea4-ba47-7d04e2062b42
For now *bananas are not coloured by the mod and keep their yellow
colour*, since I think its better for the sake of readabilty (also it
just looks kinda ugly?). Do leave your thoughts on that.
Droplets are always coloured to `LightGreen`, setting their colour to
closest timeline ticks is wrong and looks incorrect since droplets
aren't generated with them in mind.
---------
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
Co-authored-by: Shavix <54279284+Shavixinio@users.noreply.github.com>
Intended to add toggle but forgot.
This also fixes https://github.com/ppy/osu/issues/37012 via a convoluted
refactor of a lot of stuff. The basic overview is:
- Moved all replay overlay concerns out of `HUDOverlay`. We can display
this above everything confidently (i think).
- Split out `ReplayOverlay` and `ReplaySettingsOverlay` so the base
class can handle the visibility, hotkeys and everything that should be
shared with *all* replay overlay components going forward. `Ctrl+H` is
supposed to hide any of these kinds of details, and I'm sure we'll add
more in the future.
- Reorganised some things in `Player` so the new structure would work.
Mainly the overlays which add a black layer during fade out.
Adds the ability to drag and reorder cards. Card order is preserved
between rounds and is synchronized between both players (each player can
see the other player drag around and reorder their cards).
To make this possible I had to rewrite the card layout algorithm to be
stateless (e0a46fefaf), there wasn't
really a way around that since I needed a way to calculate a layout
position based on a card's index. Should hopefully be a lot easier to
read now though.
Some noteworthy stuff:
- I didn't really know what the best place to store the card order is,
so I put it on `RankedPlayCardWithPlaylistItem` since that one will stay
the same instance per round.
- To prevent the opponent's cards from dragged into the middle of the
playfield, only the x axis of the drag gets synchronized for the
`OpponentHandOfCards` with a fixed y value.
- I adjusted the replay recorder/player parameters a little. With the
drag events happening every frame the replay recorder record new frames
every 25ms and end up dropping half the replay frames per flush
interval, so I increased the sample interval to 50ms so the buffer size
matches the sample rate exactly (50ms -> 20 samples per flush every
1000ms).
I also increased the buffer size in the replay player a bit so slight
fluctuations in latency won't make it start to drop frames.
https://github.com/user-attachments/assets/b810cb85-db02-4edf-a63e-bfc96cf59665https://github.com/user-attachments/assets/4d2f884d-fcce-4948-9659-fbb314634cb8
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
The fix is just disabling the animation. It works I guess.
---
- Closes https://github.com/ppy/osu/issues/37042
Currently in Mania, you can change the scroll speed for a brief period
during the beginning of a song. However this scroll speed change occurs
over a short period of time, which causes a bunch of extra hit object
updates, causing major fps and latency drops.
This fix simply replaces the dampening with an immediate scroll speed
update. Since the scroll speed can only be updated for a short time at
the beginning of the song, providing immediate visual feedback on the
scroll speed makes sense to me. However another potential solution would
be to filter the TimeRange Value updates to keep the gradual scroll
speed visual change, while greatly reducing the number of updates to the
hit objects currently on screen.
If there is any feedback I would greatly appreciate it as this is my
first issue here. I had ran both inspectCode.ps1 and the code formatter
before creating the merge request. Thank you.
Before fix:
https://github.com/user-attachments/assets/55e30894-7341-414a-af2e-2ec051c3a252
After fix:
https://github.com/user-attachments/assets/c085d33f-c0ae-45dd-8131-e79a5682b9ca
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
In discussions, we've come to the conclusion to attempt to use a
chat-bubble system to minimise the effective area of the chat. In
particular, the results screen doesn't give us enough space to display
the full chat box without overlapping the main screen content.
This PR both adds the chat to the results screen, and reworks it to use
such a bubble system (not sure what to call it, IM style?).
https://github.com/user-attachments/assets/a8a88c51-8a9d-4a03-92b6-621112a15a41
- New messages are previewed for 3 seconds.
- When focusing and unfocusing the textbox, the history moves into
expanded state (show the most recent 10 messages) or collapsed state
(fade messages out ASAP).
This is a bit of an initial implementation to get a feel of how it
behaves, and there's more that can be done such as adding colours,
improving the transforms, perhaps adding it to the intro screen
(post-animation) but the structure's a bit weird atm.
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
This was mentioned in vivi's feedback. Basically now the card backside
is always loaded and there, rather than faffing with switching the
content around.
> Cards have a stale grey background when they are spawning in before
they get changed into the cards they’re supposed to be. This can be
changed to the backside of the card or maybe a bright white card. Makes
it look less placeholdery.
Keeping it simple for now. Can probably hide it when not in use in the
future.
Man this "storyboard replaces background" baloney has taken hours of
bugfixing alone. So many forehead indentations from stepping onto this
stupid rake.
This still fails in one more case: when you download a no-video variant
of a beatmap that has video, but then edit it, all of the flags on
storyboard will claim that the beatmap has a storyboard that replaces a
background, but the video asset is missing, so the background will still
be black. There's currently no way to check for this and the simplest
way to address this as far as I can see would be reverting
https://github.com/ppy/osu/pull/37038 and going with the non-refactor
route to fix https://github.com/ppy/osu/issues/36875 instead. The
alternative is adding all sorts of weird jingles and checks in the
storyboard machinery that can be used to be able to tell that a video
was supposed to be present in the storyboard but is missing.
Also when entering editor on a map that has background video and
storyboard enabled the background will be black until you hit play.
Something to do with `Video` idiosyncrasies for sure.
Closes https://github.com/ppy/osu/issues/37104 maybe? Kind of?
Partially? I don't know. This is all very low effort because I'm not
confident about digging this ditch any deeper, but just PRing a direct
revert would feel pretty offensive I guess?
- Simplifies track handling by not attaching to the global beatmap, not
looping, and moving into `GameplayWarmupScreen` where the beatmap is
set.
- The main idea here is that the transition period until gameplay is so
short (~10 seconds) that we don't need to account for the track ever
looping in the first place.
- Fixes the track not playing from its preview point (feedback item
mentioned in some meeting a while back).
This is definitely going to conflict with @nekodex 's work, sorry about
that. It's a bit of a much-of-a-muchness change (imo) if the conclusion
is to wait for ongoing work first.
Updates can fail on macOS when osu! is run outside /Applications or
~/Applications, but users currently get no actionable guidance.
Add a startup notification that warns when the install location is
outside those directories, and skip this check for package-managed
installs where in-app updates are not used.
Resolves#36662.
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
Addresses https://github.com/ppy/osu/discussions/37090.
Filename and format almost match stable with the exception of:
- adding `chat-` prefix to export filename to distinguish from
everything else in the `exports` folder
- adding date to message timestamps as stable writes time only
Specifically the one used on the daily challenge screen. Was bugging me
that playlists/multi have that old yellow header design used, so I've
changed it. Will probably come in handy once the footer/leaderboard
changes are in.
Also localized the headers while at it.
Multiplayer:

Playlists:

The only thing I'm wondering about is whether the detail thing
(participant count/playlist length) should be using the highlight colour
here. The old design had them be yellow, but I feel like the pink on
this one stands out too much.
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
## Changes
- Extract / Move l10n initialisation methods
- Add analyser support for tournament project
For the tournament client, it's a bit different around l10n
initialisation compared with the main client. `TournamentGame` needs to
show warning boxes for bracket errors and window size warnings, and we
may make l10n support ready in advance.
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
Closes https://github.com/ppy/osu/issues/37006 visually.
Note that this adds a brief fade in on entering `PlayerLoader` from
`OnlinePlayScreen`s due to actually loading the background at this
point. I think this is fine.
TL;DR the clock was being set too late, causing more transforms to be
created than necessary.
This solves the issue by way of a refactor (sorry). Overall this should
simplify handling of things as more of the logic is shared with the
known good-state `BeatmapBackgroundWithStoryboard`.
I did try without a refactor (just delaying the creation until the clock
arrives) but this version made more sense because background generally
expect to do their main load in BDL to aid in smooth transitions. And we
can't get the clock by there. (although arguably we could just use a
similar method to `BeatmapBackgroundWithStoryboard` and forego using the
editor clock).
Of note, I removed the black background overdraw hack. There are edge
cases where it will lead to weird transitions, but these are far and few
between. Basically you need a storyboard which sets the flag to hide the
beatmap background and has transparency in it. This is no longer as
flagrantly bad as things used to be (which led to the inline fix) as far
as I can tell, but feel free to prove me wrong. If this is a blocker
I'll probably just add a permanent black box (which does fix this).
Closes#36875.
The compatibility export was creating .osu files with CRLF line endings
on Windows and LF line endings on Linux/macOS, because StreamWriter
defaults to Environment.NewLine.
This caused the server to detect spurious file changes when a mapper
alternated between platforms, leading to unnecessary wipes of local
scores and noise in the beatmap update history.
Fix by explicitly setting NewLine = "\r\n" on the StreamWriter, ensuring
CRLF is always used regardless of platform.
Closes#36846
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
Fixes https://github.com/ppy/osu/issues/29223
This fixes several issues around hold note dimming.
Notice in the following video:
- The tail piece of the first note not getting dimmed.
- The body of the second note not responding to dimming at all.
https://github.com/user-attachments/assets/8e51053d-8d88-4e48-909b-79218d65917b
Then, notice in the following video:
- The body piece of the second note is dimmed from the very beginning.
https://github.com/user-attachments/assets/a514c630-5c72-4ba5-96d5-472bae1058b3
This requires a specific setup whereby the hold note and its components
must be reused from the pool. In particular:
1. The hold note must be long. So long that by the time the tail becomes
on screen, the body will already have dimmed.
2. The hold note must be re-used from the pool. We can induce this by
setting the pool sizes to 1 in
[`Column.cs`](https://github.com/ppy/osu/blob/780ce2666099c22d1e0673cafab544418b5d14b0/osu.Game.Rulesets.Mania/UI/Column.cs#L121-L123).
3. The second hold note should be placed far enough in the timeline that
the first hold note dies by the time it becomes visible.
4. Scroll speed should be adjusted to fit the above constraints.
I haven't done a full deep dive into exactly _why_ this is happening, so
the fix here is hand-wavy. That said, just by looking at the old code in
`LegacyBodyPiece` you'll get a feeling that something's bound to go
wrong;
- It never resets the `missingFadeTime` state.
- It never resets the colours back to `Color4.White`.
- It applies transforms onto external components.
- It jumps through hoops to figure out how to set `missingFadeTime`.
My hope is that these changes first bring some sanity in the process,
and if it breaks again I'll consider doing a more proper root cause
(I've had this issue in the back of my mind for about 1 year).
With this PR, they now behave as expected:
https://github.com/user-attachments/assets/140b37c5-cf84-44ba-b797-86ac6d8130c8https://github.com/user-attachments/assets/6f2342a4-6a9a-4941-a55a-24a357f27c25
Fixes#36645
The IsolatedPhrase match mode in FilterCriteria used \s (whitespace) as
word boundaries, meaning a search term had to be surrounded by spaces
(or start/end of string) to match.
This caused songs with titles like
'Music Theme "Some Artist"' to not appear when searching for "Some
Artist", since the phrase was bounded by quote characters rather than
spaces.
This change extends the boundary pattern to also accept Unicode
punctuation (\p{P}) alongside whitespace, so terms surrounded by quotes,
commas are correctly matched as isolated phrases.
Tests have been added to cover searching for terms adjacent to
punctuation boundaries
(TestCriteriaMatchingTermsAdjacentToPunctuation).
Tests cover the example mentioned above.
Code inspector with no errors and tests passing.
Initially reported on
[discord](https://discord.com/channels/188630481301012481/1097318920991559880/1481649645167054878).
`return` instead of `continue` led to the loop exiting too early if
there was an `EffectControlPoint` in the list before a
`TimingControlPoint`.
Behaviour can be reproduced with topdiff on this
[mapset](https://osu.ppy.sh/beatmapsets/1884175#osu/4027941). When
opened, all timing points on kiai start don't show up in the timeline.
If you disable/enable the effects section on one of those timing points
the order changes and it becomes visible again.
Right click is a very obfuscated UX which most users won't find. This
makes more sense to the average user (probably).
Caveat: clicking away actually sends clicks to underlying UI. This is
not the case in macOS or windows (locally, same app; globally it still
sends clicks to other windows).
Coming from https://github.com/ppy/osu/discussions/36926.
---------
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
1% is not precise enough to push accuracy to high enough levels.
Increasing the precision of the mod will make it more useful for a
larger amount of players who want to push their accuracy to their
absolute limits. This does come with the caveat that it's impossible to
achieve over 99.9% accuracy on many short maps, but I don't think it
really matters if high enough settings act like the Perfect mod on short
enough maps.
Co-authored-by: evill <jlkdsf;ajfklsjd@123.n>
https://github.com/user-attachments/assets/042311f1-b8c3-479b-a173-13b93fe2c5cc
- `/roll` command is now supported in multiplayer chat for all players
(don't need to be a referee).
- Referees are shown in the room with a special status.
- Tournament mode rooms can be locked, which prevents users from
changing team (and slot, whenever those get brought back). When the room
is locked, the user team indicator shows a padlock icon on top to
indicate the lock state.
---
- Related: https://github.com/ppy/osu-server-spectator/issues/406
Grab-bag because I really don't think splitting this into 3 PRs is very
helpful.
I was going to add an animation for rolling but I had a go on Friday and
my attempt got more or less the same reception as a wet fart so I'm not
trying again. Someone else can if so inclined. I have completely lost
trust in my design senses.
Contrary to stable the roll results are completely ephemeral and go away
when the room is re-entered. This could be both considered good and bad.
Not for me to say.