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).
initial_translation_keys.json
Section titled “initial_translation_keys.json”The default key set for a skin. When an admin chooses “Reset,” this set is re-seeded. It is an array of JSON objects:
| Field | Required | Description |
|---|---|---|
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.
Lifecycle (per skin × locale)
Section titled “Lifecycle (per skin × locale)”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 --> [*]| State | Meaning |
|---|---|
not_started | No translation yet; default values are used |
in_progress | A translator is working (staging, reached via a magic token) |
submitted | Saved by the translator; awaiting admin review |
published | Live; players see this locale |
Assignments vs. content
Section titled “Assignments vs. content”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:
- The service returns all of that locale’s keys to the
initial_translation_keys.jsondefaults. - The state returns to
not_started. - A translator can be reassigned.
Reset affects only that locale; the others are preserved.
Internal API
Section titled “Internal API”The game service serves these endpoints (a recommendation; the service owns the
domain), guarded by x-internal-config-secret:
| Endpoint | Description |
|---|---|
GET /internal/skins/:skinKey/locales/:locale | All keys/values for a locale |
PUT /internal/skins/:skinKey/locales/:locale | Save translator values (staging) |
POST /internal/skins/:skinKey/locales/:locale/publish | Promote staging → published |
POST /internal/skins/:skinKey/locales/:locale/reset | Reset to the initial keys |
Clone staging to a new locale
Section titled “Clone staging to a new locale”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.
Related
Section titled “Related”- Content Modules — structural game content
- Data Ownership — what each side stores