Skip to content

Change last year placing from integer to string in tournament overlay#36172

Merged
peppy merged 5 commits intoppy:masterfrom
ILW8:feature-upstream/last-year-seed-string
Dec 31, 2025
Merged

Change last year placing from integer to string in tournament overlay#36172
peppy merged 5 commits intoppy:masterfrom
ILW8:feature-upstream/last-year-seed-string

Conversation

@ILW8
Copy link
Copy Markdown
Contributor

@ILW8 ILW8 commented Dec 30, 2025

This PR changes the "Last year's placing" field from an integer to a string, matching what is currently used for the "Seed" field. This also slightly adjusts the textboxes in the team editor screen to better fit the textbox which replaced the last year placing slider.

Tournaments often show teams' last year placing as a range instead of a simple number as a result of bracket elimination. For example, in OWC2025, Japan was eliminated in the lower bracket round 2 along with 8 other teams, which gives them a placement of 17th-24th.

Team editor screen:

Before image
After image

Seeding screen:

With seed and placement No seed nor placing
image image

Comment on lines +65 to +68
if (value is long oldValue && oldValue == 0)
LastYearPlacing.Value = LastYearPlacing.Default;
else
LastYearPlacing.Value = value.ToString() ?? LastYearPlacing.Default;
Copy link
Copy Markdown
Collaborator

@bdach bdach Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would much rather do something like

diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs
index ab353d771a..4368c2fda8 100644
--- a/osu.Game.Tournament/Models/TournamentTeam.cs
+++ b/osu.Game.Tournament/Models/TournamentTeam.cs
@@ -2,6 +2,7 @@
 // See the LICENCE file in the repository root for full licence text.
 
 using System;
+using System.Diagnostics;
 using System.Linq;
 using Newtonsoft.Json;
 using osu.Framework.Bindables;
@@ -49,25 +50,9 @@ public double AverageRank
 
         public Bindable<string> Seed = new Bindable<string>(string.Empty);
 
-        [JsonIgnore]
-        public Bindable<string> LastYearPlacing = new Bindable<string>("N/A");
-
-        /// <summary>
-        /// Previously, a value of 0 was meant to indicate "no placement last year".
-        /// This will convert the number 0 from an old bracket.json file back to the "N/A" string (new default).
-        /// </summary>
-        [JsonProperty("LastYearPlacing")]
-        private object lastYearPlacing
-        {
-            get => LastYearPlacing.Value;
-            set
-            {
-                if (value is long oldValue && oldValue == 0)
-                    LastYearPlacing.Value = LastYearPlacing.Default;
-                else
-                    LastYearPlacing.Value = value.ToString() ?? LastYearPlacing.Default;
-            }
-        }
+        [JsonProperty]
+        [JsonConverter(typeof(LastYearPlacingConverter))]
+        public Bindable<string> LastYearPlacing = new Bindable<string>(@"N/A");
 
         [JsonProperty]
         public BindableList<TournamentUser> Players { get; } = new BindableList<TournamentUser>();
@@ -90,5 +75,37 @@ public TournamentTeam()
         }
 
         public override string ToString() => FullName.Value ?? Acronym.Value;
+
+        public class LastYearPlacingConverter : JsonConverter
+        {
+            public override bool CanConvert(Type objectType) => objectType == typeof(Bindable<string>);
+
+            public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
+                => serializer.Serialize(writer, ((Bindable<string>)value!).Value);
+
+            public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
+            {
+                var lastYearPlacing = existingValue as Bindable<string>;
+                Debug.Assert(lastYearPlacing != null);
+
+                switch (reader.TokenType)
+                {
+                    case JsonToken.String:
+                        lastYearPlacing.Value = (string?)reader.Value ?? lastYearPlacing.Default;
+                        break;
+
+                    case JsonToken.Integer:
+                        long value = (long)reader.Value!;
+                        lastYearPlacing.Value = value > 0 ? $@"#{value}" : lastYearPlacing.Default;
+                        break;
+
+                    default:
+                        reader.Read();
+                        break;
+                }
+
+                return lastYearPlacing;
+            }
+        }
     }
 }

than do this. I have much unresolved trauma from doing "setter tricks" like this that later just absolutely die on something very stupid and require even stupider things to unknot.

Copy link
Copy Markdown
Contributor Author

@ILW8 ILW8 Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, in the first place I was debating whether to include the conversion at all since seeding is usually a one-off thing for a tournament anyway.

I've applied this patch, but I'm tempted to just remove the conversion completely at this point.

@peppy peppy self-requested a review December 31, 2025 13:44
@peppy peppy merged commit 338b987 into ppy:master Dec 31, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants