Skip to content

Add LocalisableString.Concat() and LocalisableString.Join() - #6838

Merged
smoogipoo merged 1 commit into
ppy:masterfrom
bdach:localisable-conveniences
Oct 16, 2026
Merged

smoogipoo merged 1 commit into
ppy:masterfrom
bdach:localisable-conveniences

Conversation

@bdach

@bdach bdach commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

Doing things with localisables of dynamic content that require concatenating or joining-with-separator is currently tedious. The only way this sort of thing can be currently achieved is to basically nest Format() or Interpolate() calls like a matrioshka.

To a degree this is also a performance concern, though in measurements via the added benchmark, neither is the old version that slow, nor is the new version that much faster - probably mostly because underneath it's still a string.Format() call. Definitely seems much gentler on memory overhead, though:

Method Mean Error StdDev Gen0 Allocated
BenchmarkConcatenationViaNestingToString 4.583 us 0.0873 us 0.0774 us 1.7242 14.12 KB
BenchmarkConcatenationViaConcatToString 3.641 us 0.0286 us 0.0268 us 0.2594 2.14 KB

Doing things with localisables of dynamic content that require
concatenating or joining-with-separator is currently tedious. The only
way this sort of thing can be currently achieved is to basically nest
`Format()` or `Interpolate()` calls like a matrioshka.

To a degree this is also a performance concern, though in measurements
via the added benchmark, neither is the old version *that* slow, nor is
the new version *that* much faster - probably mostly because underneath
it's still a `string.Format()` call. Definitely seems much gentler on
memory overhead, though:

| Method                                   | Mean     | Error     | StdDev    | Gen0   | Allocated |
|----------------------------------------- |---------:|----------:|----------:|-------:|----------:|
| BenchmarkConcatenationViaNestingToString | 4.583 us | 0.0873 us | 0.0774 us | 1.7242 |  14.12 KB |
| BenchmarkConcatenationViaConcatToString  | 3.641 us | 0.0286 us | 0.0268 us | 0.2594 |   2.14 KB |
@bdach bdach self-assigned this Oct 16, 2026
@smoogipoo
smoogipoo merged commit 06e28ec into ppy:master Oct 16, 2026
12 of 14 checks passed
@bdach
bdach deleted the localisable-conveniences branch October 16, 2026 09:48
diquoks added a commit to diquoks/osu that referenced this pull request Oct 19, 2026
peppy added a commit to ppy/osu that referenced this pull request Oct 19, 2026
- [x] Depends on framework package containing
ppy/osu-framework#6838

Like ["beatmap attribute
text"](https://github.com/ppy/osu/blob/576dbb2a19b43f556c6ef82b14e90ebad15fea3d/osu.Game/Skinning/Components/BeatmapAttributeText.cs#L29),
but for scores.

This'll come in handy to implement the text in the top left corner of
the legacy results screen design. And in general for people to make
everything custom for themselves (to the degree that the text components
allow).

Supported placeholders:

- `Username`
- `TotalScore`
- `MaxCombo`
- `Accuracy`
- `Date`
- `PP` (where populated, which it won't be on local scores, but I'll
worry about that later - the grid component also has this issue and I
intend to not have both of them calculate pp locally twice *somehow*)
- `Rank`
- `Mods`
- Statistics via `{HitResult}Label`, `{HitResult}`, and `{HitResult}Max`

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
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.

2 participants