New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ability to create new difficulties from within the editor #14799
Conversation
Upon investigating the issue mentioned above (with difficulties getting truncated) I've decided to bundle the fix for that here, as the fix is short and the issue is nigh untestable anyway (and I've tried, believe me). Sometimes after launch EF - or more concretely, |
I'm actively wrangling with moving that stuff to realm, so should be fine to continue working around issues with local hacks as required. |
@@ -118,6 +118,7 @@ public TextContainer() | |||
{ | |||
NormalText = new OsuSpriteText | |||
{ | |||
AlwaysPresent = true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This definitely requires an inline comment explaining why it's required.
osu.Game/Beatmaps/BeatmapMetadata.cs
Outdated
@@ -128,5 +129,7 @@ public bool Equals(BeatmapMetadata other) | |||
&& AudioFile == other.AudioFile | |||
&& BackgroundFile == other.BackgroundFile; | |||
} | |||
|
|||
public BeatmapMetadata DeepClone() => (BeatmapMetadata)MemberwiseClone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is what we want. It means that individual difficulties can have differing artist/titles, which while technically is supported by stable and by the lazer database structure, is usually not what a mapper wants:
20210920.171322.dotnet.mp4
A good initial starting point might be to drop this and just have all difficulties share metadata until we have a better UX flow for exceptional cases in place.
It looks like on this branch, difficulty name changes no longer save: 20210920.171624.dotnet.mp4I can't immediately see why this is happening, you might have more insight into this? |
No idea off the top of my head. May be more EF chicanery. Will verify. |
Fired some commits re: the red review above. 61e2617 should also fix the difficulty names not saving, although I'm not very confident of that fix as database stuff seems quite brittle to the touch the longer I stare at it in the context of this pull (see my discord messages from earlier today for context). |
@@ -519,7 +544,7 @@ public override bool OnExiting(IScreen next) | |||
// To update the game-wide beatmap with any changes, perform a re-fetch on exit. | |||
// This is required as the editor makes its local changes via EditorBeatmap | |||
// (which are not propagated outwards to a potentially cached WorkingBeatmap). | |||
var refetchedBeatmap = beatmapManager.GetWorkingBeatmap(Beatmap.Value.BeatmapInfo); | |||
var refetchedBeatmap = beatmapManager.GetWorkingBeatmap(editorBeatmap.BeatmapInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason this is changed is that GetWorkingBeatmap()
silently stores back the provided BeatmapInfo
to the WorkingBeatmap
. And because the beatmapset is refetched anew from the db context in BDL, the old code would pass a stale BeatmapInfo
reference to the working beatmap, leading to things like the difficulty name updating on the carousel in song select but not the beatmap wedge on the left.
playableBeatmap.BeatmapInfo = refetchedBeatmapSet.Beatmaps.Single(b => b.ID == playableBeatmap.BeatmapInfo.ID); | ||
playableBeatmap.BeatmapInfo.Metadata ??= refetchedBeatmapSet.Metadata; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is now assigning to BeatmapInfo
rather than just BeatmapInfo.BeatmapSet
as the old code used to do, as per the comment above. As it turns out those two references could differ before, which is why the difficulty name changes didn't save.
As for the metadata shuffling, I needed to do this to prevent crashes in LegacyBeatmapEncoder
, which would sometimes access EditorBeatmap.BeatmapInfo.Metadata
(e.g. when trying to encode path to the background file) which isn't guaranteed to be present. This is a carbon copy of similar workarounds in BeatmapManager.GetWorkingBeatmap()
and BeatmapCarousel.createCarouselSet()
.
/// <param name="beatmapSkin">The skin specific to the beatmap being added.</param> | ||
/// <returns>The usable <see cref="WorkingBeatmap"/> corresponding to <paramref name="beatmap"/> and associated with the supplied <paramref name="beatmapSet"/>.</returns> | ||
/// <exception cref="InvalidOperationException">If <paramref name="beatmapSet"/> does not exist in the database.</exception> | ||
public virtual WorkingBeatmap AddToExistingSet(BeatmapSetInfo beatmapSet, IBeatmap beatmap, ISkin beatmapSkin = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am suddenly regretting not merging this PR before my recent changes..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll close and rebase on top whatever the new structure ends up being. No worry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either way works. Was more of a joke than a serious issue (unlike the other comment further down).
I really want to get this in, and the code looks mostly fine, but I am still unfortunately able to break this in serious ways: 20211001.185226.dotnet.mp4I can still get beatmaps into a state they disappear from my client permanently. Even after a restart they are gone. |
As an aside, I was also looking at getting the song setup screen to appear (and focus the difficulty name entry field) when creating a new difficulty, which seems to work quite well using the existing |
upon seeing that i'm leaning to closing this and reopening wholesale after realm. i have a distinct feeling that even if i fix whatever fresh hell is causing this there will be another terminal breakage somewhere else. the way EF is set up is way too sensitive what with random attached or non attached model references being passed around (which was part of why i was arguing at length about that in discord today, until you explained what the plan for editor was which i can now agree with). |
Bit unfortunate. I think it's fine to leave this dangling and push forward as progress is made over the next few weeks (keeping it roughly in sync). |
I've attempted to come back to this today but too many things changed to make that feasible, so I will close this for now. However, I have rewritten this under realm, and an early version is available for preview at https://github.com/bdach/osu/tree/new-difficulty-creation-v2. I won't be PRing it yet, because I need to figure out a few kinks (highlights: bdach@007e886, bdach@fe2b5f5), and I'd also like to split off a few incidental fixes and general changes out of there too (bdach@b2ae987, bdach@b482de0, maybe bdach@4e8ba02 too). I'll try to get the individual pieces together over the coming days. |
Closes #12035.
UX likely is not final, but it's functional for now.
2021-09-18.20-42-12.mp4
The general flow is mostly a logical continuation of the preceding changes. By far the most finicky part here is the database stuff - there's a new
BeatmapManager
method here to facilitate appending a difficulty to an existing set, and some added safety checks inSave()
to ensure uniquity of difficulty names - without them two or more difficulties could point at one.osu
file and throw exceptions. With the changes here, an error notification will show instead:I am aware of one more remaining problem - after a restart, if you go to edit an existing map with multiple difficulties, and save one of them, the rest will get truncated, but I'd prefer to tackle that one separately as this diff is a bit on the larger side already.