Repository navigation
feat: Language, the player's language as a BCP 47 tag - #18
Merged
Merged
Conversation
g.Language() string answers "pt-BR", "zh-CN", "en-US" (or "" when unknown) so a game can pick its translation while building scenes. - Windows: the user's display language (GetUserPreferredUILanguages via golang.org/x/sys/windows, no cgo), falling back to GetUserDefaultLocaleName. - macOS: the first of AppleLanguages (defaults read -g), then the environment. - Linux and other Unix: LC_ALL, LC_MESSAGES, LANG, with GNU's LANGUAGE list first as gettext does; encoding and modifier stripped, C and POSIX mean unknown. - Browser: navigator.language. Agent and test runs (the agentOrTestRun set: Headless, Autopilot, COLLIDER_AGENT=mcp, go test) get "", so games fall back to their default language and agents see the same text everywhere. COLLIDER_LANG overrides the answer in every run, to try or test a translation; like LANG it only picks among the game's own strings, so DisallowAgents keeps it. Contract item 10. The dialog example speaks English or Portuguese through it (and its typewriter now counts runes, not bytes). CI also vets and builds for Windows, which now has a platform file of its own.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
g.Language() string: the player's language as a BCP 47 tag ("pt-BR","zh-CN","en-US","de"), or""when unknown. Games call it while building scenes to pick a translation.GetUserPreferredUILanguages(MUI_LANGUAGE_NAME)(the display language) viagolang.org/x/sys/windows, no cgo; fallbackGetUserDefaultLocaleNamedefaults read -g AppleLanguages(Finder-launched apps get noLANG), then the environmentLC_ALL,LC_MESSAGES,LANG;pt_BR.UTF-8@eurobecomespt-BR,C/POSIXare""; GNULANGUAGEwins over a real locale, as for gettextnavigator.languageEvery answer is normalized the same way (
_to-, language lower case, script title case, region upper case). The system is asked once per process.Design choices
g.agentOrTestRun(), which gates saves and audio), and it lives on the Game (Headless, Autopilot, DisallowAgents).Newis the first line of every game, so the method is available before any scene exists."". That covers Headless and Autopilot once called,COLLIDER_AGENT=mcp, andgo test. The game falls back to its default language, and agents and CI read the same strings on every machine.mcp-windowis a person's window, so it gets the real language, the same way it gets real audio and saves. Contract item 10.COLLIDER_LANGoverrides it everywhere, agent runs included (COLLIDER_LANG=zh-CN go run ., or an MCP agent testing the Chinese UI).Cforces"". It stays active afterDisallowAgents: that lock stops outside control and file writes, while this only picks among the game's own strings, which a player can already do withLANGor the OS setting. It also lets testers check a translation on a release build.Languagematches what games ask for ("which language?"). It returns a tag rather than a parsed struct so the API stays one string. The doc comment explains how to match it leniently (primary subtag, and region or script where it matters, for example zh-CN vs zh-TW).Proof
language_test.go: normalization table, the Unix env rules (priority, C/POSIX, LANGUAGE), AppleLanguages parsing, the agent/test/mcp/mcp-window/DisallowAgents matrix, the override, and the real platform call on the test machine (en-UShere).language_windows_test.gocovers the locale fallback.examples/dialogspeaks English or Portuguese (COLLIDER_LANG=pt-BR go run .). Its typewriter now slices runes, not bytes, so accented letters never split.language_windows.go), cross-compiled like the wasm step.