fix(make_game): a launcher's build keeps the folder's language, and a first one takes the system's (#2184) #2284
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!2284
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/launcher-build-language"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A game built through RecompLauncher is always in English, and a language the player set in
language.txtgoes back to English the next time the launcher builds the folder (#2184).Why
The launcher builds with
--cli --prepare --game <copy>(recomplauncher.json): no window, and no--language.make_game.pytooken-USfor that and wrote it tolanguage.txtat the end of every build. Only--updateread the folder's own language first.So the one way a launcher's player has to change the language, the code in
language.txt(the file says so itself, and the readme's "wrong language" row), lasted until the next build. Anything else that writes the player's choice to that file is undone the same way; the "Game language" row of #1864 would be.The change
With no
--language, a build now takes, in this order:language.txt;--prepareand no folder yet: the game language closest to the system's (on LinuxLANGUAGE's first entry unless the locale is C, elseLC_ALL,LC_MESSAGES,LANG, as gettext reads them; on Windows the display language, the first ofGetUserPreferredUILanguages, as the builder'sCurrentUICulture), by the rule the Windows builder's window uses for its first choice (the exact one, then the family;es-MXis Spanish (Latin America),zh-TWChinese (Traditional));en-US, as before.A
--languagegiven is still the one built, so both builder windows, which always pass theirs, are unchanged.--updatekeeps the folder's as before. A plain command line build without--languageis still English into a new folder; into a folder built before it now keeps that folder's language rather than turning it English.Tested
python -I -B tests/test_make_game_prepare.py: 17 pass, 8 of them new. One runsmainitself up to its first step with--prepareover a folder whoselanguage.txtsaysru: onmainit fails with'en-US' != 'ru', here it isru. The others cover the order above, the system names (de_DE.UTF-8,pt_PT,es_MX,zh_TW,zh-Hant-HK,C, ...) and which of the three variables is read.python -I -B tests/run_all.py: nothing new fails.python -I -B tests\test_make_game_prepare.py, 16 pass and the Linux environment one skips. On that PC the display language is en-US and the regional format en-CA;system_language()readsen-US, whereGetUserDefaultLocaleName(the rule before review) readen-CA.Not tested: a whole build through RecompLauncher (no launcher here), and a Windows locale the game has a language for.
Part of #2184
yes that would be awesome if we could get this merged
Good fix, and the order is right: an explicit
--languagewins, an update keeps the folder's language, then the folder's own language, then the system's (only with--prepare), then en-US. Movinga.languageto afteroutis resolved means the plain command-line build and the update path now share one rule. Both builder windows always pass--language, and their update paths rely on the folder's language. I checkedMainWindow.xaml.cs:752,window.py:1342andbuilder/linux/hookshot_builder.py:1043.tests/test_make_game_prepare.pyand the othermake_gamechecks pass here, the branch merges cleanly with main, and theappimagefailure is a Launchpad timeout, not this PR.should fix
nx2/make_game.py:1126readsGetUserDefaultLocaleName. That returns the user's regional-format locale (Settings → Region → Format), not the display language. The Windows builder picks its first language fromCultureInfo.CurrentUICulture(builder/HookshotBuilder/Strings.cs:165), which is the UI language. The two often differ. Someone with English Windows and German or Polish regional formats would get a German or Polish game from the launcher, and the opposite also happens. That breaks the "by the rule the Windows builder's window uses" claim. Reading the UI language instead would match the builder, for example:(
GetUserPreferredUILanguagesis the closer match to .NET if you want the first entry of the list.)minor On Linux, gettext puts
LANGUAGEahead ofLC_ALL/LC_MESSAGES/LANGfor message catalogs. Some desktops, including GNOME's language setting, set it, e.g.LANGUAGE=de:en. If you want to match what the desktop shows, check its first entry before the others (and still ignore it when the locale isC, as gettext does). Fine to leave out if you'd rather stay with the three.minor CONTRIBUTING's build table (line 151) and the readme (lines 512–513) still show
--language en-USin every example, which is fine, but nothing documents the new behaviour without--language. One sentence in the readme near line 215 ("The game is in the wrong language") would help: rebuilding now keeps the language set inlanguage.txt.The precedence (
--language, the folder's language on update, the system's with--prepare, then en-US) is right, and all 17 tests pass.The open point is still open:
nx2/make_game.py:1126usesGetUserDefaultLocaleName, which is the regional-format locale. The Windows builder usesCurrentUICulture, so English Windows with German regional formats gets a German game.GetUserDefaultUILanguage(orGetUserPreferredUILanguages) matches the builder.Also worth a line in the docs: a plain CLI build into an existing folder now keeps that folder's language instead of resetting to English.
Thanks, all three done in
9071c78:system_languagenow reads the display language, the first ofGetUserPreferredUILanguages(MUI_LANGUAGE_NAME), elseLCIDToLocaleName(GetUserDefaultUILanguage()), so it follows the same setting as the builder'sCurrentUICulture. On a Windows 11 PC whose display language is English (United States) and regional format English (Canada), it readsen-US(PowerShell'sGet-UICulturesays en-US,Get-Cultureen-CA, andGetUserDefaultLocaleNamereturned en-CA).LANGUAGE's first entry comes first, unless the locale fromLC_ALL/LC_MESSAGES/LANGis C or POSIX, as gettext does. The test has five more cases for it.language.txt.tests/test_make_game_prepare.pypasses on Linux (17) and on that Windows PC (16, 1 Linux-only skip).9071c78addresses all three points from my last review.GetUserPreferredUILanguages(MUI_LANGUAGE_NAME), elseLCIDToLocaleName(GetUserDefaultUILanguage())(windows_ui_languageinnx2/make_game.py). That's the setting behind the builder'sCurrentUICulture, and your check with an en-US display language and en-CA regional format was the case that mattered.LANGUAGE's first entry now comes ahead ofLC_ALL/LC_MESSAGES/LANG. It's ignored when the locale is C, POSIX or unset, as gettext does.language.txt.tests/test_make_game_prepare.pypasses here (17 tests), the branch merges cleanly with current main, and CI is green on the new head. Nothing is left open from my side.github-sync referenced this pull request2026-11-12 06:22:54 +00:00