Skip to content

Translations

Skin-scoped translation templates and locales live in the game service’s own database. The platform keeps only the tables needed for translator orchestration (translator assignments and magic tokens).

This follows the data-ownership model: translation content is service-owned (a skin is the service’s domain), while translator assignments are platform-owned (an admin / operational process).

The default key set for a skin. When an admin chooses “Reset,” this set is re-seeded. It is an array of JSON objects:

FieldRequiredDescription
key✓Translation key (e.g. "ui.betButton")
defaultValue✓The English (or base-locale) default text
description✗A note to the translator (context)
maxLength✗UI constraint (character limit)
[
{ "key": "ui.betButton", "defaultValue": "Bet", "description": "Main bet button label", "maxLength": 12 },
{ "key": "ui.cashout", "defaultValue": "Cash Out", "maxLength": 14 },
{ "key": "msg.insufficientFunds", "defaultValue": "Insufficient balance" },
{ "key": "result.youWon", "defaultValue": "You won {amount}!", "description": "{amount} is interpolated" }
]

The service keeps this file in its own repository (for example src/skins/<skinKey>/initial_translation_keys.json). The platform reads it at build/deploy time or via an admin endpoint.

stateDiagram-v2
[*] --> not_started
not_started --> in_progress: translator assigned
in_progress --> submitted: translator saved
submitted --> published: admin approved
published --> in_progress: re-edit
published --> [*]
StateMeaning
not_startedNo translation yet; default values are used
in_progressA translator is working (staging, reached via a magic token)
submittedSaved by the translator; awaiting admin review
publishedLive; players see this locale

Two separate responsibilities:

  • Platform (translator_assignments): which translator is assigned to which skin × locale, magic-token generation, deadlines. Operational.
  • Game service (<game>_translation_*): the actual translation content, the key set, staging vs. published values. The service’s domain.

When the platform assigns a translator, a magic token signals the game service to “edit this skin × locale.” The translator uses that token to reach a translation UI the service serves (or the service’s API).

When an admin resets a skin × locale:

  1. The service returns all of that locale’s keys to the initial_translation_keys.json defaults.
  2. The state returns to not_started.
  3. A translator can be reassigned.

Reset affects only that locale; the others are preserved.

The game service serves these endpoints (a recommendation; the service owns the domain), guarded by x-internal-config-secret:

EndpointDescription
GET /internal/skins/:skinKey/locales/:localeAll keys/values for a locale
PUT /internal/skins/:skinKey/locales/:localeSave translator values (staging)
POST /internal/skins/:skinKey/locales/:locale/publishPromote staging → published
POST /internal/skins/:skinKey/locales/:locale/resetReset to the initial keys

When adding a locale (for example de exists and de-AT is added), the service copies de’s published values into de-AT as staging, so the translator edits only the differences. This is an optional optimization, not a requirement.