Skip to content

Fix missing and malformed translations across all languages - #11913

Open
leriomaggio wants to merge 5 commits into
Card-Forge:masterfrom
leriomaggio:fix/missing-translations
Open

leriomaggio wants to merge 5 commits into
Card-Forge:masterfrom
leriomaggio:fix/missing-translations

Conversation

@leriomaggio

@leriomaggio leriomaggio commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Switching Forge to any non-English language currently floods the log with stack traces, and several strings cannot render as written. This fixes the translation data and the logging that buried the problem.

Issue

Twenty-three keys existed in en-US.properties and were missing in other languages, so every lookup threw MissingResourceException. ko-KR was also missing lblAllowedAdditionalColors, and zh-CN advReputation. The English fallback kept the UI correct, so the visible damage was log noise: a full stack trace per lookup, per screen that asked for the key.

Separately, Localizer runs every value through MessageFormat, where a lone apostrophe opens a quoted section. 810 values across all ten files were affected. Most simply lost the apostrophe, so Italian showed labilità and leffetto. In 76 of them a {0} fell inside the quoted section and was never substituted, so dialogs printed the literal placeholder where a card name, deck name or host address belonged. An Italian player overwriting a deck saw {0} è già esistente rather than the deck's name.

Changes in this PR

  1. Add the missing translation keys to every language file. Translated for de, es, fr, it, pt and ru. ja, ko and zh get the English string, matching what the neighbouring keys in that block already hold, so the exception is gone and a translator can fill them in later.
  2. Translate the network draft and limited strings into Italian. 44 keys that were present in it-IT but holding English: the draft setup dialogs, the draft overlay, and the draft log.
  3. Escape apostrophes across all translation files. Doubles every lone apostrophe, en-US included since it is the bundle every locale falls back to. Pairs that were already escaped are untouched.
  4. Repair three malformed entries, and quiet the Localizer.: Localizer now reports each bad key once per language on a single line instead of a stack trace per lookup, and distinguishes a missing key from a malformed pattern.
  5. EDIT: Italian translation is now full and complete.

Notes

Every value in all ten files was loaded and rendered through MessageFormat. Before this branch, 78 values either threw or left a placeholder unsubstituted. Now none do, and every language file covers every en-US key.

For the apostrophe commit specifically, each file was compared against its previous version with apostrophes stripped from both. They are byte-identical, with unchanged line counts, so nothing was reflowed, reordered or retranslated.

Notes for reviewers

The Italian is mine and I am a native speaker. The de, es, fr, pt and ru strings in commit 1 follow each file's existing vocabulary, but native corrections are very welcome.

Twenty-three keys reached en-US without ever being copied into the other
nine language files. Switching to any non-English locale threw
MissingResourceException on every lookup and dumped a stack trace, once
per screen that asked for them. ko-KR was also missing
lblAllowedAdditionalColors, and zh-CN advReputation.

Most of the keys belong to the networked draft and limited lobby.
These 44 keys were in it-IT already, but holding the English string: the
networked draft setup dialogs, the draft overlay, and the draft log. The
Italian follows the terms the file already uses elsewhere, busta for a
booster and scelta for a pick, and keeps Draft, Sealed, Limited, Host and
pool untranslated the way Italian players say them.
Values only. No keys added, removed or reordered.
Doubles every lone apostrophe in all ten files, en-US included, since it
is the bundle every other locale falls back to. Pairs that were already
escaped are left as they are. Values only: no keys added, removed or
reordered, and no text changed beyond the apostrophes.
A sweep of every value through MessageFormat found three that could not
work as written:

fr-FR lblGuideTipsSet had its line-continuation backslash mid-sentence
instead of at the end of the line, so the string was truncated and its
last line was parsed as a key of its own.

ko-KR lblContainsXCopiesCard used {X}, which is not a valid argument
index, so the lookup threw and Korean users silently got the English
string.

de-DE lblLogPlayerChosenModeForCard opened its first placeholder with a
square bracket, [0}, so the game log showed that instead of the player
name.

Also stop Localizer printing a stack trace for every lookup of a bad key.
Report each problem once per language instead, separating a missing key
from a malformed message pattern, and clear the silent flag at the start
of getMessage: it was reset only on the success path, so an early return
left it set and muted every later warning.
441 values in it-IT still held the English text: preferences, the yield
and auto-pass settings, the game log, dice and contraption prompts, the
sleeve selector, network setup, and the Adventure mode summaries.

Card types now use the official Italian terms, Artefatto, Incantesimo,
Istantaneo, Stregoneria, Leggendario, Neve. Format and mode names,
creature types and words Italian shares with English are deliberately
left as they are, as are the comparison operators and the deck-import
syntax examples.

Values only. No keys added, removed or reordered, and the placeholder
arity of every line matches en-US.
@leriomaggio
leriomaggio force-pushed the fix/missing-translations branch from 6c355b2 to 3bc78b2 Compare September 15, 2026 06:07
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.

1 participant