WienerWiener
  • Introduction
  • Comparison
  • Pricing
  • FAQ
  • Use Cases
  • License
  • Unity Asset vs Standalone
  • Obfuscation & Tamper Detection
  • Mismatch Detection & Debug
  • Localization
  • Versioning
  • Google Sheets Input
  • Excel
  • YAML
  • Settings
  • Data Format
  • Convert
  • ValueOnly Format
  • Startup
  • Samples
  • Converter
  • YAML Editor
  • Setting Editor
  • 日本語
  • English
  • Introduction
  • Comparison
  • Pricing
  • FAQ
  • Use Cases
  • License
  • Unity Asset vs Standalone
  • Obfuscation & Tamper Detection
  • Mismatch Detection & Debug
  • Localization
  • Versioning
  • Google Sheets Input
  • Excel
  • YAML
  • Settings
  • Data Format
  • Convert
  • ValueOnly Format
  • Startup
  • Samples
  • Converter
  • YAML Editor
  • Setting Editor
  • 日本語
  • English
  • Features

    • Obfuscation & Tamper Detection
    • Mismatch Detection & Debug
    • Localization
    • Versioning
    • Google Sheets Input

Localization

Wiener handles Static Game Data localization transparently without requiring changes to your application code.

Overall Flow

Excel / YAML (collect fields with localize flag)
    ↓
Generate translation CSV (auto-updated)
  Column A (Key): {ClassName}.{FieldKey}.{UniqueID}
  Column B (Source): Source text
  Column C+: Language translations (filled in by translators)
    ↓
Convert (integrity check → binary output)
    ↓
Runtime API (transparent access)
  wm.Item[0].Name  // returns the current language automatically

Setup Steps

1. Add localization to the settings file

Using a CSV file:

localization:
  enable: true
  input:
    path: "localize/translations.csv"  # relative path from the current directory

Using separate input and output (e.g. read from spreadsheet, write to CSV):

localization:
  enable: true
  input:
    path: "https://docs.google.com/spreadsheets/d/xxxxxxxx/edit#gid=0"
    sheet: "translations"
  output:
    path: "localize/translations.csv"

2. Create a unique key in YAML fields

Prepare a field that uniquely identifies each row. This field is used to generate translation CSV keys.

fields:
- key: Id
  name: id
  type: Int

3. Add localization to the YAML Header

Set localization.id_key on the YAML that contains localized fields.
id_key should be the key of the field that uniquely identifies each row.

header:
  name: Item
  localization:
    id_key: Id

4. Add localize: True to YAML fields

Add localize: True to any String field you want to localize.

fields:
- key: Id
  name: id
  type: Int

- key: Name
  name: name
  type: String
  localize: True

Translator CSV Format

The translation CSV is generated and updated automatically at convert time.
Translators only need to fill in the columns from column C onward.

KeySourcejaenzh
Item.Name.1001Sword剣Sword剑
Item.Name.1002Shield盾Shield盾
Quest.Title.1001The Lost Sword失われた剣The Lost Sword失落之剑
  • Key: {ClassName}.{FieldKey}.{UniqueID} format (UniqueID is the value of the field specified by id_key)
  • Source: Source text read from Excel (auto-updated when changed)
  • Language columns: Column header names become language codes. Untranslated cells are managed with ----

Automatic CSV Management

SituationBehavior
CSV does not existCreated new. No language columns (translators add columns)
New key addedRow added to CSV. Translation columns set to ----
Source text changedTranslation columns reset to ----
Key deletedRow removed from CSV
No changes to source or keysCSV is not modified

When source text changes or keys are deleted, diff data is output.

Output destinationDiff write location
CSV file{csv-name}_diff_{timestamp}.csv (same directory)
SpreadsheetNew sheet named diff_{timestamp} in the same spreadsheet

Language Switch API

// Get available language codes (CSV column header names)
string[] codes = wm.GetLanguageCodes();

// Switch language
wm.SetLanguage("ja");  // subsequent accesses return Japanese
wm.SetLanguage("en");

// Reset to default (source text)
wm.ResetLanguage();

// Language change event (for UI refresh, etc.)
// langCode is null when ResetLanguage is called
wm.OnChangeLanguage += (langCode) => RefreshUI();

Language codes are the strings in the header row of the CSV starting from column C (BCP 47 recommended: "ja", "en", "zh-Hans", etc.).

Design Highlights

  • Runtime cost: No string-key Dictionary lookup. Values are accessed by row index → array reference only
  • Integrity check: When the source text changes, it is updated in column B and translation columns are automatically cleared (making it clear that re-translation is needed)
  • Untranslated cells: Cells with ---- fall back to the source text in development mode; in production mode (development: false in the settings file) they cause a convert error for languages listed in target_languages (all languages if not defined)
  • Diff tracking: Updated or deleted keys are recorded in a diff CSV

Workflow During Development

When enable: true, the translation CSV is updated every time a convert runs, causing CSV commits on every Static Game Data change.

It is recommended to keep enable: false (or omit the setting) during development.

TimingRecommended setting
Normal development / data updatesenable: false
Before starting translation work (update CSV and hand to translators)enable: true
Testing or verifying a localized binaryenable: true
Production convertsenable: true

Notes

  • fields.localize: True can only be applied to String type fields
  • The field specified by header.localization.id_key automatically has duplicate checking (unique) enabled
  • The id_key field must not be manual_only: True

Related

  • Version Management — version control for per-language binaries
  • Settings File — localization settings details
  • YAML Header Definition — localization.id_key setting
  • Fields Definition — localize flag
Last Updated:: 6/12/26, 2:44 AM
Contributors: artisan-sawasaka
Prev
Mismatch Detection & Debug
Next
Versioning