Generated accessors
Generated classes often encode valid paths and return resource references, not final strings. Follow the expected conversion or backport function used by current call sites.
Vehicle icon names and fallback forms
The vehicle icon helpers accept different input forms
for different resource trees. Ordinary, small and contour helpers normalize the full descriptor
name by replacing colons and hyphens with underscores. The descriptor-taking shop helpers first
select the name after the colon, then normalize it. For the synthetic name
nation:Tank-1, those keys are nation_Tank_1 and Tank_1.
Pass the raw descriptor name to its matching helper; a pre-normalized ordinary key loses the
separator required by the shop conversion.
| Helper | Returned form | Python fallback branch |
|---|---|---|
getIconPath / getIconResource | Image path / resource ID | Failed existence check returns '' / None |
getSmallIconPath / getContourIconPath | Image path | Failed existence check selects that tree's noImage |
getIconShopPath | Image path | Falsy requested path selects the size-specific empty_tank |
getIconShopResource | Resource ID | Falsy requested ID selects the size-specific empty_tank |
The lower-level getShopVehicleIconPath(size, name) already takes a shop name;
it does not perform the descriptor's colon split and returns an empty path after a failed
existence check. Choose the wrapper and output form expected by the consumer. A nonempty
fallback path or ID does not establish that the requested variant was selected or rendered.
These are current Python helper and caller contracts. Resource accessors, installed asset catalogs, image decoding and actual rendering were not exercised.
Fallback pattern
This mod-owned adapter takes a numeric resource ID, such as the result of a generated
string accessor, and an explicit fallback. Expected absent or nonpositive input returns the
fallback quietly. It uses the current backport.text
interface rather than assuming every resource object has one validity method.
import logging
from gui.impl import backport
_LOGGER = logging.getLogger(__name__)
def _localized_text(res_id, fallback, **kwargs):
if res_id is None or res_id <= 0:
return fallback
try:
value = backport.text(res_id, **kwargs)
except Exception:
_LOGGER.exception('Could not resolve localized text for resource %r.', res_id)
return fallback
return value or fallback
Fallback on empty text is this adapter's policy, not a universal missing-catalog guarantee.
The stock wrapper catches formatting TypeError/ValueError on its
argument-bearing paths and returns empty text; those errors do not reach the adapter's
exception handler. Unexpected failures that do escape retain a
traceback-bearing log
before returning the fallback. The adapter needs no optional reporting package.
Controlled resolver and in-memory logging checks cover these fallback and diagnostic branches. Native translation, generated accessors, language catalogs and actual automatic reporting were not exercised.
Formatting boundaries
Prefer one localized resource with named placeholders when word order matters. The Scaleform text-style wrappers can translate a recognized key string, but pass no formatting arguments to that translation. Resolve a parameterized label before styling it: substitution in a surrounding template does not fill placeholders inside an inserted value. XML template loading translates its own source markers at a separate stage.
The Python template formatter inserts context values
directly with % ctx. Literal-text escaping belongs to the producer; intentional
styled fragments use the same insertion path. Styling and template substitution do not establish
that literal text was escaped or that a renderer accepted the resulting markup.
When both contexts are dictionaries, template-owned entries overwrite conflicting caller values and mutate the supplied dictionary. Use a separate dictionary when its original values must survive. Caught formatting errors return the unformatted template after logging, so a nonempty result is not a successful substitution receipt. Missing collection keys instead create cached placeholders that return the key itself and ignore the supplied message context; nonempty output does not establish that the requested style exists. These latest-source contracts were checked with synthetic templates and translation/logging substitutes; catalogs, actual template assets, native APIs and rendering were not exercised.
Choose text cleanup by its input representation
The stripAllTags helper removes descriptor placeholders such as {colorTagOpen} and {colorTagClose}; its name does not mean every markup representation. For synthetic input {colorTagOpen}<b>A & B</b>{colorTagClose}, it leaves <b>A & B</b>. The separate stripHTMLTags applies an angle-tag regular expression, while html.escape encodes literal markup characters. These operations have different outputs and are not interchangeable plain-text conversion.
A concrete reward-view producer sends its chosen title to setName, then separately applies placeholder removal to its tooltip title and description. That establishes the Python payload transformation, not how a frontend renders arbitrary text. Preserve the source representation and intended output boundary instead of choosing a helper by its broad name.
Selected readable helpers were checked with synthetic marker, angle-tag and ampersand text. Original modules, translation catalogs, real view/model construction and rendering were not exercised; no malformed-input or live UI defect was established.
Mod-owned localization contract
When custom text has no native resource, keep language selection and translation in one owned boundary instead of mixing translated strings through calculations and DOM code.
- Publish stable translation keys, named format arguments, and the value from
helpers.getClientLanguage()in the view payload. - Load the localization module before the renderer. Let it own locale normalization, dictionaries, placeholder formatting, and fallback.
- Resolve labels, notes, units, tooltip text, and custom group names at the final presentation boundary. Leave strings already localized by native helpers unchanged.
- Normalize regional spellings and aliases first, then fall back from the regional locale to its base language and finally to English.
- Fall back key by key inside a known but incomplete locale; one missing translation must not expose raw keys throughout the view.
- Keep a non-executable translator template with the complete English key set. Validate key parity and preserve every named placeholder when adding a locale.
Browser resources
Gameface assets must be registered under a unique namespace and removed by the same owner. On
WG 2.4.1, use a uniquely named per-mod gui/gen_resources declaration and an owned
R.mods... subtree. On the historical WG path, prefer a per-feature map entry over
modifying a shared resource map globally.
Common mistakes
- Editing generated resource files instead of the source resource.
- Assuming a resource exists in every realm, mode, or client build.
- Displaying an internal key directly to users without a fallback.
- Using one language's concatenation order for every localization.
- Confusing persistent registration with view lifetime; declarations remain mounted while callbacks, models, DOM nodes, and windows still require explicit teardown.
Verification trail
Find the generated accessor, inspect current call sites, confirm the resolver and formatting path, then test at least one missing-resource and one alternate-language case.