Skip to content

feat(core): add support for formattable variant prefixes #626

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

Open
wants to merge 18 commits into
base: release/v2.12.0
Choose a base branch
from

Conversation

appac
Copy link

@appac appac commented Apr 6, 2025

Changes

  • Updates Wilds monster BuildName method to support format/template strings from localization files

The intention with this change is to allow the localization file to dictate the formatting for monster variant prefixes, as detailed in #623.

This is my first time working with C# so please do point out if I'm doing anything crazy.

Implementation Details

The changes here update BuildName such that:

  • If a variant prefix can be resolved
    • If the variant prefix contains a format token ({0}), use AppendFormat to build the name string based on the localized string template.
    • Otherwise build it as before, with simple <variant><name> formatting, using the English variant text.
  • If a variant prefix cannot be resolved
    • Build the name string with no variant prefix - name only.

With these changes updating a respective localization file to include, for example:

    <Monsters>
        <Variants>
            <Variant Id="TEMPERED"
                     String="{0} (歴戦の個体)" />
            <Variant Id="ARCH_TEMPERED"
                     String="歴戦王{0}" />
            <Variant Id="FRENZIED"
                     String="狂竜化{0}" />
         </Variants>
      <!-- ... -->
      </Monsters>

Should then allow monster names to be rendered with whatever variant prefix formatting makes the most sense for that locale.

Screenshots

  1. Monster names with variants, if no variant data exists in localization file.
    localised-prefix-without-variants

  2. Monster names with variants, if variant data does exist in localization file.
    localised-prefix-with-variants

@Kobi-Blade
Copy link
Contributor

I would suggest something like this, but @Haato3o will have a better idea of how he wants to do this.

    var prefixes = new List<string>();

    if (variant.HasFlag(VariantType.Tempered))
    {
        prefixes.Add(localizationRepository.FindStringBy("//Strings/Monsters/Variants/Variant[@Id='TEMPERED']"));
    }

    if (variant.HasFlag(VariantType.ArchTempered))
    {
        prefixes.Add(localizationRepository.FindStringBy("//Strings/Monsters/Variants/Variant[@Id='ARCH_TEMPERED']"));
    }

    if (variant.HasFlag(VariantType.Frenzy))
    {
        prefixes.Add(localizationRepository.FindStringBy("//Strings/Monsters/Variants/Variant[@Id='FRENZIED']"));
    }

    string namePath = $"//Strings/Monsters/Wilds/Monster[@Id='{id}']";
    string name = localizationRepository.TryFindStringBy(namePath) ?? $"Unknown [id: {id}]";

    string prefix = string.Join(" ", prefixes);
    return prefix.Contains("{0}")
        ? string.Format(prefix, name)
        : $"{prefix} {name}".Trim();

@appac
Copy link
Author

appac commented Apr 8, 2025

I did originally think we'd need to support multiple prefixes, but couldn't find anything to confirm if it's possible to have, say, "Tempered Frenzied {{monster}}".

If that is the case though, I do like your suggestion.

Edit: Gave this some more thought, and I think building a list would require a little extra work to handle in the context of ordering things correctly based on language.

If we assume the localization text looks like this:

   <Monsters>
        <Variants>
            <Variant Id="TEMPERED"
                     String="{0} (歴戦の個体)" />
            <Variant Id="ARCH_TEMPERED"
                     String="歴戦王{0}" />
            <Variant Id="FRENZIED"
                     String="狂竜化{0}" />
         </Variants>
      <!-- ... -->
      </Monsters>

We'd build a list of multiple prefixes that's basically ["{0} (歴戦の個体)", "狂竜化{0}"] Which, joined and formatted, would lead to MONSTER (歴戦の個体) 狂竜化 MONSTER.

@Kobi-Blade
Copy link
Contributor

Kobi-Blade commented Apr 8, 2025

I did originally think we'd need to support multiple prefixes, but couldn't find anything to confirm if it's possible to have, say, "Tempered Frenzied {{monster}}".

If that is the case though, I do like your suggestion.

Edit: Gave this some more thought, and I think building a list would require a little extra work to handle in the context of ordering things correctly based on language.

If we assume the localization text looks like this:

   <Monsters>
        <Variants>
            <Variant Id="TEMPERED"
                     String="{0} (歴戦の個体)" />
            <Variant Id="ARCH_TEMPERED"
                     String="歴戦王{0}" />
            <Variant Id="FRENZIED"
                     String="狂竜化{0}" />
         </Variants>
      <!-- ... -->
      </Monsters>

We'd build a list of multiple prefixes that's basically ["{0} (歴戦の個体)", "狂竜化{0}"] Which, joined and formatted, would lead to MONSTER (歴戦の個体) 狂竜化 MONSTER.

That just a basic example, you can try making it so if the variants contains a {0} placeholder for the monster name, format can be used to replace it with the monster name.

Similar to what you did in original PR.

@Haato3o
Copy link
Member

Haato3o commented Apr 8, 2025

I think since there are two PRs for the same thing, we should keep the discussion in the issue that suggested this (#623)

@appac
Copy link
Author

appac commented Apr 14, 2025

Updated the implementation here to support format strings from the localization files - I couldn't wrap my head around the custom formatter, but did manage to get something that I think works well using Regex. Unsure if that's a dealbreaker in this case.

More details below; I'm traveling this week so likely won't get a chance to work on this again until next weekend.


The changes are similar to what was mentioned in the issue; We resolve a "format string" that dictates the order of the variant, sub variant, and name of the monster, plus padding between the elements, where:

0 - Name
1 - Variant
2 - Sub-variant

Note: We can change the indexing here easily, so if the preference is for another setup, I can do that.

So {1:1}{2:1}{0} would result in "Tempered Alpha Doshaguma". The changes here also treat Frenzied as a sub-variant, so the same format string could support "Tempered Frenzied Doshaguma" if that was ever needed.

For resolving the format string, we basically just join the variant and subvariants with an _ - a tempered alpha monster for example would result in a TEMPERED_ALPHA format lookup ID.

In terms of the localization files, you'd set this up with:

    <Monsters>
        <Variants>
          <Variant Id="TEMPERED"
                   String="(歴戦の個体)" />
          <Variant Id="ARCH_TEMPERED"
                   String="歴戦王" />
          <Variant Id="FRENZIED"
                   String="狂竜化" />
          <Variant Id="ALPHA"
                    String="α" />
        </Variants>
        <Formatting>
          <Format Id="TEMPERED"
                   String="{0:1}{1}" />
          <Format Id="ARCH_TEMPERED"
                   String="{1}{0}" />
          <Format Id="FRENZIED"
                   String="{2}{0}" />
          <Format Id="ALPHA"
                   String="{2}{0}" />
          <Format Id="TEMPERED_ALPHA"
                   String="{2}{0:1}{1}" />
        </Formatting>
    <!-- ... -->
    <Monsters>

Screenshots

With variant translations and formatting set up in localization files - tested with ja-jp.
WithTranslationsFormatting

No variant translations or formatting set up in localization files - falling back to en-us.
NoTranslationsNoFormatting

Simple Alpha example - tested by harcoding ALPHA as a subvariant.
AlphaExample

@Haato3o
Copy link
Member

Haato3o commented Apr 15, 2025

Why would we need each combination of formattings? This doesn't seem like something that would scale well if they add more sub-variants 🤔

@Lucarine
Copy link

Hi, I was interested in this topic and wanted to weigh in an opinion on how this feature could be approached.

Rather than impose a combination of formatting, you could treat each variant/sub-variant etc. as a tag, and in the localization xml you would give each tag attributes declaring whether it's a prefix or suffix and an order of priority (e.g. should it always be added first etc.)

So the file itself can look something like the below:

    <Monsters>
        <Variants>
          <Variant Id="TEMPERED"
                   String="(歴戦の個体)" 
                   Affixation="Suffix" 
                   Order="0"/>
          <Variant Id="ARCH_TEMPERED"
                   String="歴戦王"
                   Affixation="Prefix"
                   Order="2" />
          <Variant Id="FRENZIED"
                   String="狂竜化"
                    Affixation="Prefix"
                    Order="1"/>
          <Variant Id="ALPHA"
                    String="α"
                    Affixation="Prefix"
                    Order="0" />
        </Variants>
    <!-- ... -->
    <Monsters>

As far as I can tell, the problem seems to be of two kinds:

  1. Should the "variant name" come before or after the name of the monster
  2. Should there be at least 2 variant names that appear before/after the monster name, which "variant name" should appear first?

Doing it in the above way means in the c# code we can build the prefix and suffix separately and then just attach it to the monster name

@appac
Copy link
Author

appac commented May 1, 2025

Why would we need each combination of formattings? This doesn't seem like something that would scale well if they add more sub-variants 🤔

I think I've misunderstood the suggestion made in the issue. I took it to mean that we'd want a format string for any possible variant or combination of variants, to determine the order of things in different localisations.

@Lucarine please do feel free to open up a PR if you'd like, I've gotten crazy busy at work so no issues if someone wants to take over implementing a solution to this so I'm not holding it up with my slow contributions 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants