Localization for Hong Kong on iOS not going to traditional chinese

Hi there,

In 4.12 as part of the release notes it says:

New: Improved the culture fallback detection for Chinese (or any cultures that use scripts).
If given a culture without a script code, we now try and work out what script should use based upon the available cultures.
For example, if we were given “zh-CN”, we would detect “Hans” (from “zh-Hans-CN”) and then process “zh-Hans-CN”, “zh-CN”, “zh-Hans”, and “zh” in order until we find one with matching translations.
This allows you to use “zh-Hans” and “zh-Hant” for Chinese translations without running into issues on platforms that don’t provide the script code.

We are noticing that on iOS, if we change the language to Chinese, Traditional (Hong Kong), that on load up the game actually tries to load the localization for zh-HK-AU (we are in australia) and then fails and falls back to zh-Hans.

Shouldn’t this be falling back to zh-Hant?

Pre 4.12 when the auto fall back was not occurring, we were able to just add zh-HK localization, but now this does not work (presumably because instead of falling from zh-HK-AU to zh-HK, it does the script fallback instead and finds that.

How do we fix this?
We are releasing asap and this could be a blocker for us.

Hmm, “zh-HK-AU” isn’t a culture that’s know to ICU (it internally loads “zh-HK”), and since there’s both a “zh-Hans-HK” and “zh-Hant-HK” it will build the following list to test (in order, see FICUInternationalization::GetPrioritizedCultureNames):

  • zh-Hans-HK
  • zh-Hant-HK
  • zh-HK
  • zh-Hans
  • zh-Hant
  • zh

So it should still be falling back to “zh-HK” assuming you don’t have translations for “zh-Hans-HK” or “zh-Hant-HK”. What cultures do you have translations for? I suspect it may have previously been falling back to “zh”.

(I forget whether this is in 4.12 or 4.13). You could try adding an explicit culture re-mapping. Add the following to your DefaultGame.ini:

[Internationalization]
+CultureMappings=zh-HK-AU;zh-Hant

You’ll also need to remove the if (AllAvailableCulturesMap.Contains(SourceCulture) && AllAvailableCulturesMap.Contains(DestCulture)) check in FICUInternationalization::ConditionalInitializeCultureMappings since “zh-HK-AU” isn’t know to ICU so it won’t let you add that as a culture re-mapping (I should probably remove that check since platforms often use unknown cultures that need to be re-mapped).

Honestly, iOS is partly at fault here. If you’ve specified Traditional Chinese then the culture code used should include the script type of “Hant”. “zh-HK-AU” is both ambiguous and non-existent according to the CLDR.

That said, since Hong Kong and Macau primarily use Traditional Chinese, we should probably add some special case logic to weight traditional above simplified for “HK” and “MO” (Taiwan also uses Traditional Chinese, but there’s no “zh-Hans-TW” so it’s not ambiguous like “zh-HK” and “zh-MO”).

Go to FICUInternationalization::GetPrioritizedCultureNames and replace the sort call after the comment // Sort the cultures by their priority with this:

// Sort the cultures by their priority
// Special case handling for the ambiguity of Hong Kong and Macau supporting both Traditional and Simplified Chinese (prefer Traditional)
const bool bPreferTraditionalChinese = GivenCultureData.CountryCode == TEXT("HK") || GivenCultureData.CountryCode == TEXT("MO");
PrioritizedCultureData.Sort([bPreferTraditionalChinese](const FICUCultureData& DataOne, const FICUCultureData& DataTwo) -> bool
{
	const int32 DataOneSortWeight = (DataOne.CountryCode.IsEmpty() ? 0 : 4) + (DataOne.ScriptCode.IsEmpty() ? 0 : 2) + (bPreferTraditionalChinese && DataOne.ScriptCode == TEXT("Hant") ? 1 : 0);
	const int32 DataTwoSortWeight = (DataTwo.CountryCode.IsEmpty() ? 0 : 4) + (DataTwo.ScriptCode.IsEmpty() ? 0 : 2) + (bPreferTraditionalChinese && DataTwo.ScriptCode == TEXT("Hant") ? 1 : 0);
	return DataOneSortWeight >= DataTwoSortWeight;
});

That will special case the “HK” and “MO” cultures to order their ambiguous scripts like so:

  • zh-Hant-HK
  • zh-Hans-HK
  • zh-HK
  • zh-Hant
  • zh-Hans
  • zh

Thanks Jamie, agreed on the fact that iOS should instead be giving us zh-Hant-HK!

I had a local fix which was way more hacky then what you proposed, but somewhat similar.

I will use what you provided as it catches a few more cases. Appreciate it.