Skip to content

Глава 5.1: stringtable.csv --- Локализация

Главная | stringtable.csv | Далее: inputs.xml >>


Краткое содержание: Файл stringtable.csv предоставляет локализованный текст для вашего мода DayZ. Движок читает этот CSV при запуске и разрешает ключи переводов на основе языковых настроек игрока. Каждая строка, видимая пользователю --- метки UI, названия привязок клавиш, описания предметов, текст уведомлений --- должна находиться в stringtable, а не быть жёстко закодированной.


Содержание


Обзор

DayZ использует систему локализации на основе CSV. Когда движок встречает строковый ключ с префиксом # (например, #STR_MYMOD_HELLO), он ищет этот ключ во всех загруженных файлах stringtable и возвращает перевод, соответствующий текущему языку игрока. Если совпадение для активного языка не найдено, движок следует по цепочке резервных вариантов.

Файл stringtable должен называться строго stringtable.csv и размещаться внутри PBO-структуры вашего мода. Движок обнаруживает его автоматически --- регистрация в config.cpp не требуется.


Формат CSV

Файл представляет собой стандартный файл значений, разделённых запятыми, с полями в кавычках. Первая строка --- заголовок, каждая последующая строка определяет один ключ перевода.

Строка заголовка

Строка заголовка определяет столбцы. DayZ поддерживает до 15 столбцов:

csv
"Language","original","english","czech","german","russian","polish","hungarian","italian","spanish","french","chinese","japanese","portuguese","chinesesimp",

Строки данных

Каждая строка начинается с ключа строки (без префикса # в CSV), за которым следуют переводы для каждого языка:

csv
"STR_MYMOD_HELLO","Hello World","Hello World","Ahoj světe","Hallo Welt","Привет мир","Witaj świecie","Helló világ","Ciao mondo","Hola mundo","Bonjour le monde","你好世界","ハローワールド","Olá mundo","你好世界",

Завершающая запятая

Многие файлы stringtable включают завершающую запятую после последнего столбца. Это общепринятая практика и безопасна --- движок её допускает.

Правила кавычек

  • Поля обязательно должны быть заключены в двойные кавычки, если содержат запятые, переносы строк или двойные кавычки.
  • На практике большинство модов заключают каждое поле в кавычки для единообразия.
  • Некоторые моды (например, MyMod Missions) полностью опускают кавычки; движок обрабатывает оба стиля, если содержимое поля не содержит запятых.

Справочник столбцов

DayZ поддерживает 13 языков, выбираемых игроком. CSV имеет 15 столбцов, потому что первый столбец --- это имя ключа, а второй --- столбец original (родной язык автора мода или текст по умолчанию).

#Имя столбцаЯзыкПримечания
1Language---Идентификатор строкового ключа (например, STR_MYMOD_HELLO)
2originalРодной язык автораРезервный вариант последней инстанции; используется, если ни один другой столбец не подходит
3englishАнглийскийНаиболее распространённый основной язык для международных модов
4czechЧешский
5germanНемецкий
6russianРусский
7polishПольский
8hungarianВенгерский
9italianИтальянский
10spanishИспанский
11frenchФранцузский
12chineseКитайский (традиционный)Традиционные китайские иероглифы
13japaneseЯпонский
14portugueseПортугальский
15chinesesimpКитайский (упрощённый)Упрощённые китайские иероглифы

Порядок столбцов имеет значение

Движок определяет столбцы по имени заголовка, а не по позиции. Однако соблюдение стандартного порядка, показанного выше, настоятельно рекомендуется для совместимости и читаемости.

Необязательные столбцы

Вам не нужно включать все 15 столбцов. Если ваш мод поддерживает только английский язык, можно использовать минимальный заголовок:

csv
"Language","english"
"STR_MYMOD_HELLO","Hello World"

Некоторые моды добавляют нестандартные столбцы, например korean (MyMod Missions). Движок игнорирует столбцы, которые не распознаёт как поддерживаемый язык, но эти столбцы могут служить документацией или подготовкой к будущей поддержке языков.


Соглашение об именовании ключей

Строковые ключи следуют иерархическому шаблону именования:

STR_MODNAME_CATEGORY_ELEMENT

Правила

  1. Всегда начинайте с STR_ --- это универсальное соглашение DayZ
  2. Префикс мода --- уникально идентифицирует ваш мод (например, MYMOD, COT, EXPANSION, VPP)
  3. Категория --- группирует связанные строки (например, INPUT, TAB, CONFIG, DIR)
  4. Элемент --- конкретная строка (например, ADMIN_PANEL, NORTH, SAVE)
  5. Используйте ЗАГЛАВНЫЕ БУКВЫ --- соглашение всех крупных модов
  6. Используйте подчёркивания как разделители, никогда пробелы или дефисы

Примеры из реальных модов

STR_MYMOD_INPUT_ADMIN_PANEL       -- MyMod: метка привязки клавиш
STR_MYMOD_CLOSE                   -- MyMod: общая кнопка "Закрыть"
STR_MYMOD_DIR_NORTH                  -- MyMod: направление компаса
STR_MYMOD_TAB_ONLINE                 -- MyMod: имя вкладки админ-панели
STR_COT_ESP_MODULE_NAME            -- COT: отображаемое имя модуля
STR_COT_CAMERA_MODULE_BLUR         -- COT: метка инструмента камеры
STR_EXPANSION_ATM                  -- Expansion: название функции
STR_EXPANSION_AI_COMMAND_MENU      -- Expansion: метка ввода

Антипаттерны

STR_hello_world          -- Плохо: строчные буквы, нет префикса мода
MY_STRING                -- Плохо: отсутствует префикс STR_
STR_MYMOD Hello World    -- Плохо: пробелы в ключе

Использование строк

Существуют три различных контекста, где вы ссылаетесь на локализованные строки, и каждый использует немного отличающийся синтаксис.

В файлах макетов (.layout)

Используйте префикс # перед именем ключа. Движок разрешает его при создании виджета.

TextWidgetClass MyLabel {
 text "#STR_MYMOD_CLOSE"
 size 100 30
}

Префикс # сообщает парсеру макета: "это ключ локализации, а не буквальный текст."

В Enforce Script (файлы .c)

Используйте Widget.TranslateString() для разрешения ключа во время выполнения. Префикс # обязателен в аргументе.

c
string translated = Widget.TranslateString("#STR_MYMOD_CLOSE");
// translated == "Close" (если язык игрока --- английский)
// translated == "Fechar" (если язык игрока --- португальский)

Также можно установить текст виджета напрямую:

c
TextWidget label = TextWidget.Cast(layoutRoot.FindAnyWidget("MyLabel"));
label.SetText(Widget.TranslateString("#STR_MYMOD_ADMIN_PANEL"));

Или использовать строковые ключи непосредственно в свойствах текста виджета, и движок разрешит их:

c
label.SetText("#STR_MYMOD_ADMIN_PANEL");  // Тоже работает -- движок автоматически разрешает

В inputs.xml

Используйте атрибут loc без префикса #.

xml
<input name="UAMyAction" loc="STR_MYMOD_INPUT_MY_ACTION" />

Это единственное место, где вы опускаете #. Система ввода добавляет его внутренне.

Сводная таблица

КонтекстСинтаксисПример
Атрибут text файла макета#STR_KEYtext "#STR_MYMOD_CLOSE"
TranslateString() в скрипте"#STR_KEY"Widget.TranslateString("#STR_MYMOD_CLOSE")
Текст виджета в скрипте"#STR_KEY"label.SetText("#STR_MYMOD_CLOSE")
Атрибут loc в inputs.xmlSTR_KEY (без #)loc="STR_MYMOD_INPUT_ADMIN_PANEL"

Создание нового stringtable

Шаг 1: Создание файла

Создайте stringtable.csv в корне каталога содержимого PBO вашего мода. Движок сканирует все загруженные PBO на наличие файлов с именем stringtable.csv.

Типичное размещение:

@MyMod/
  Addons/
    MyMod_Scripts.pbo
      config.cpp
      stringtable.csv        <-- Здесь
      Scripts/
        3_Game/
        4_World/
        5_Mission/

Шаг 2: Написание заголовка

Начните с полного заголовка из 15 столбцов:

csv
"Language","original","english","czech","german","russian","polish","hungarian","italian","spanish","french","chinese","japanese","portuguese","chinesesimp",

Шаг 3: Добавление строк

Добавляйте по одной строке на каждую переводимую строку. Начните с английского языка, заполняйте другие языки по мере появления переводов:

csv
"Language","original","english","czech","german","russian","polish","hungarian","italian","spanish","french","chinese","japanese","portuguese","chinesesimp",
"STR_MYMOD_TITLE","My Cool Mod","My Cool Mod","","","","","","","","","","","","",
"STR_MYMOD_OPEN","Open","Open","Otevřít","Öffnen","Открыть","Otwórz","Megnyitás","Apri","Abrir","Ouvrir","打开","開く","Abrir","打开",

Шаг 4: Сборка и тестирование

Соберите PBO. Запустите игру. Убедитесь, что Widget.TranslateString("#STR_MYMOD_TITLE") возвращает "My Cool Mod" в логах скриптов. Смените язык игры в настройках для проверки поведения резервного варианта.


Обработка пустых ячеек и поведение резервного варианта

Когда движок ищет строковый ключ для текущего языка игрока и находит пустую ячейку, он следует по цепочке резервных вариантов:

  1. Столбец выбранного языка игрока --- проверяется первым
  2. Столбец english --- если ячейка языка игрока пуста
  3. Столбец original --- если english тоже пуст
  4. Необработанное имя ключа --- если все столбцы пусты, движок отображает сам ключ (например, STR_MYMOD_TITLE)

Это означает, что вы можете безопасно оставлять неанглийские столбцы пустыми во время разработки. Англоговорящие игроки видят столбец english, а другие игроки видят резервный английский вариант, пока не будет добавлен правильный перевод.

Практическое следствие

Вам не нужно копировать английский текст в каждый столбец в качестве заглушки. Оставляйте непереведённые ячейки пустыми:

csv
"STR_MYMOD_HELLO","Hello","Hello","","","","","","","","","","","","",

Игроки, у которых установлен немецкий язык, увидят "Hello" (резервный английский вариант), пока не будет предоставлен немецкий перевод.


Многоязычный рабочий процесс

Для одиночных разработчиков

  1. Напишите все строки на английском языке (столбцы original и english).
  2. Выпустите мод. Английский служит универсальным резервным вариантом.
  3. По мере появления добровольцев-переводчиков заполняйте дополнительные столбцы.
  4. Пересоберите и выпустите обновления.

Для команд с переводчиками

  1. Храните CSV в общем репозитории или электронной таблице.
  2. Назначьте одного переводчика на каждый язык.
  3. Используйте столбец original для родного языка автора (например, португальский для бразильских разработчиков).
  4. Столбец english всегда заполнен --- это международный базовый вариант.
  5. Используйте инструмент сравнения различий для отслеживания ключей, добавленных с момента последнего прохода перевода.

Использование табличного ПО

CSV-файлы естественно открываются в Excel, Google Sheets или LibreOffice Calc. Обратите внимание на следующие подводные камни:

  • Excel может добавить BOM (Byte Order Mark) к файлам UTF-8. DayZ обрабатывает BOM, но это может вызвать проблемы с некоторыми инструментами. Сохраняйте как "CSV UTF-8" для надёжности.
  • Автоформатирование Excel может исказить поля, которые выглядят как даты или числа.
  • Окончания строк: DayZ принимает как \r\n (Windows), так и \n (Unix).

Модульный подход к stringtable (DayZ Expansion)

DayZ Expansion демонстрирует лучшую практику для крупных модов: разделение переводов на множество файлов stringtable, организованных по функциональным модулям. Их структура использует 20 отдельных файлов stringtable внутри каталога languagecore:

DayZExpansion/
  languagecore/
    AI/stringtable.csv
    BaseBuilding/stringtable.csv
    Book/stringtable.csv
    Chat/stringtable.csv
    Core/stringtable.csv
    Garage/stringtable.csv
    Groups/stringtable.csv
    Hardline/stringtable.csv
    Licensed/stringtable.csv
    Main/stringtable.csv
    MapAssets/stringtable.csv
    Market/stringtable.csv
    Missions/stringtable.csv
    Navigation/stringtable.csv
    PersonalStorage/stringtable.csv
    PlayerList/stringtable.csv
    Quests/stringtable.csv
    SpawnSelection/stringtable.csv
    Vehicles/stringtable.csv
    Weapons/stringtable.csv

Зачем разделять?

  • Управляемость: Один stringtable для крупного мода может вырасти до тысяч строк. Разделение по функциональным модулям делает каждый файл управляемым.
  • Независимые обновления: Переводчики могут работать над одним модулем за раз без конфликтов слияния.
  • Условное включение: PBO каждого подмода включает только stringtable для своей функции, сохраняя размеры PBO меньше.

Как это работает

Движок сканирует каждый загруженный PBO на наличие stringtable.csv. Поскольку каждый подмодуль Expansion упакован в собственный PBO, каждый из них естественно включает только свой stringtable. Специальная настройка не нужна --- просто назовите файл stringtable.csv и поместите его внутрь PBO.

Имена ключей по-прежнему используют глобальный префикс (STR_EXPANSION_) для избежания коллизий.


Реальные примеры

MyMod Core

MyMod Core использует полный формат из 15 столбцов с португальским языком в качестве столбца original (родной язык команды разработчиков) и полными переводами для всех 13 поддерживаемых языков:

csv
"Language","original","english","czech","german","russian","polish","hungarian","italian","spanish","french","chinese","japanese","portuguese","chinesesimp",
"STR_MYMOD_INPUT_GROUP","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod","MyMod",
"STR_MYMOD_INPUT_ADMIN_PANEL","Painel Admin","Open Admin Panel","Otevřít Admin Panel","Admin-Panel öffnen","Открыть Админ Панель","Otwórz Panel Admina","Admin Panel megnyitása","Apri Pannello Admin","Abrir Panel Admin","Ouvrir le Panneau Admin","打开管理面板","管理パネルを開く","Abrir Painel Admin","打开管理面板",
"STR_MYMOD_CLOSE","Fechar","Close","Zavřít","Schließen","Закрыть","Zamknij","Bezárás","Chiudi","Cerrar","Fermer","关闭","閉じる","Fechar","关闭",
"STR_MYMOD_SAVE","Salvar","Save","Uložit","Speichern","Сохранить","Zapisz","Mentés","Salva","Guardar","Sauvegarder","保存","保存","Salvar","保存",

Примечательные паттерны:

  • original содержит португальский текст (родной язык команды)
  • english всегда заполнен как международный базовый вариант
  • Все 13 языковых столбцов заполнены

COT (Community Online Tools)

COT использует тот же формат из 15 столбцов. Его ключи следуют паттерну STR_COT_MODULE_CATEGORY_ELEMENT:

csv
Language,original,english,czech,german,russian,polish,hungarian,italian,spanish,french,chinese,japanese,portuguese,chinesesimp,
STR_COT_CAMERA_MODULE_BLUR,Blur:,Blur:,Rozmazání:,Weichzeichner:,Размытие:,Rozmycie:,Elmosódás:,Sfocatura:,Desenfoque:,Flou:,模糊:,ぼかし:,Desfoque:,模糊:,
STR_COT_ESP_MODULE_NAME,Camera Tools,Camera Tools,Nástroje kamery,Kamera-Werkzeuge,Камера,Narzędzia Kamery,Kamera Eszközök,Strumenti Camera,Herramientas de Cámara,Outils Caméra,相機工具,カメラツール,Ferramentas da Câmera,相机工具,

VPP Admin Tools

VPP использует сокращённый набор столбцов (13 столбцов, без столбца hungarian) и не добавляет к ключам префикс STR_:

csv
"Language","original","english","czech","german","russian","polish","italian","spanish","french","chinese","japanese","portuguese","chinesesimp"
"vpp_focus_on_game","[Hold/2xTap] Focus On Game","[Hold/2xTap] Focus On Game","...","...","...","...","...","...","...","...","...","...","..."

Это демонстрирует, что префикс STR_ является соглашением, а не требованием. Однако его отсутствие означает, что вы не можете использовать разрешение с префиксом # в файлах макетов. VPP ссылается на эти ключи только через код скрипта. Префикс STR_ настоятельно рекомендуется для всех новых модов.

MyMod Missions

MyMod Missions использует CSV без кавычек и без заголовка стандартного стиля (без кавычек вокруг полей) с дополнительным столбцом Korean:

csv
Language,English,Czech,German,Russian,Polish,Hungarian,Italian,Spanish,French,Chinese,Japanese,Portuguese,Korean
STR_MYMOD_MISSION_AVAILABLE,MISSION AVAILABLE,MISE K DISPOZICI,MISSION VERFÜGBAR,МИССИЯ ДОСТУПНА,...

Примечание: столбец original отсутствует, а Korean добавлен как дополнительный язык. Движок игнорирует нераспознанные имена столбцов, поэтому Korean служит документацией до тех пор, пока не будет добавлена официальная поддержка корейского языка.


Распространённые ошибки

Пропуск префикса # в скриптах

c
// НЕПРАВИЛЬНО -- отображает сырой ключ, а не перевод
label.SetText("STR_MYMOD_HELLO");

// ПРАВИЛЬНО
label.SetText("#STR_MYMOD_HELLO");

Использование # в inputs.xml

xml
<!-- НЕПРАВИЛЬНО -- система ввода добавляет # внутренне -->
<input name="UAMyAction" loc="#STR_MYMOD_MY_ACTION" />

<!-- ПРАВИЛЬНО -->
<input name="UAMyAction" loc="STR_MYMOD_MY_ACTION" />

Дублирование ключей между модами

Если два мода определяют STR_CLOSE, движок использует тот, чей PBO загрузился последним. Всегда используйте префикс вашего мода:

csv
"STR_MYMOD_CLOSE","Close","Close",...

Несовпадение количества столбцов

Если строка имеет меньше столбцов, чем заголовок, движок может молча пропустить её или назначить пустые строки для отсутствующих столбцов. Всегда убеждайтесь, что каждая строка имеет то же количество полей, что и заголовок.

Проблемы с BOM

Некоторые текстовые редакторы вставляют UTF-8 BOM (маркер порядка байтов) в начало файла. Это может привести к тому, что первый строковый ключ в CSV будет молча повреждён. Если ваш первый строковый ключ не разрешается, проверьте и удалите BOM.

Использование запятых внутри полей без кавычек

csv
STR_MYMOD_MSG,Hello, World,Hello, World,...

Это нарушает парсинг, потому что Hello и World читаются как отдельные столбцы. Заключите поле в кавычки или избегайте запятых в значениях:

csv
"STR_MYMOD_MSG","Hello, World","Hello, World",...

Лучшие практики

  • Всегда используйте префикс STR_MODNAME_ для каждого ключа. Это предотвращает коллизии при одновременной загрузке нескольких модов.
  • Заключайте каждое поле в CSV в кавычки, даже если содержимое не содержит запятых. Это предотвращает тонкие ошибки парсинга, когда переводы на другие языки содержат запятые или специальные символы.
  • Заполняйте столбец english для каждого ключа, даже если ваш родной язык другой. Английский является универсальным резервным вариантом и базой для переводчиков сообщества.
  • Храните один stringtable на PBO для небольших модов. Для крупных модов с 500+ ключами разделяйте на файлы stringtable по функциям в отдельных PBO (следуя паттерну Expansion).
  • Сохраняйте файлы в UTF-8 без BOM. При использовании Excel явно выбирайте формат "CSV UTF-8" при экспорте.

Теория и практика

Что говорит документация и как это на самом деле работает во время выполнения.

КонцепцияТеорияРеальность
Порядок столбцов не имеет значенияДвижок определяет столбцы по имени заголовкаВерно, но некоторые инструменты сообщества и экспорт из таблиц могут изменить порядок столбцов. Сохранение стандартного порядка предотвращает путаницу
Цепочка резервных вариантов: язык > english > original > сырой ключДокументированный каскадЕсли english и original пусты, движок отображает сырой ключ с удалённым префиксом # --- полезно для обнаружения отсутствующих переводов в игре
Widget.TranslateString()Разрешает при вызовеРезультат кэшируется на сессию. Смена языка игры требует перезапуска для обновления поисков в stringtable
Несколько модов с одним ключомПобеждает последний загруженный PBOПорядок загрузки PBO не гарантирован между модами. Если два мода определяют STR_CLOSE, отображаемый текст зависит от того, какой мод загрузится последним --- всегда используйте префикс мода
Префикс # в SetText()Движок автоматически разрешает ключи локализацииРаботает, но только при первом вызове. Если вы вызываете SetText("#STR_KEY") и затем вызываете SetText("literal text"), возврат к SetText("#STR_KEY") работает нормально --- проблем с кэшированием на уровне виджета нет

Совместимость и влияние

  • Мультимод: Коллизии строковых ключей --- основной риск. Два мода, определяющих STR_ADMIN_PANEL, будут конфликтовать молча. Всегда добавляйте к ключам имя вашего мода (STR_MYMOD_ADMIN_PANEL).
  • Производительность: Поиск в stringtable быстрый (на основе хэша). Наличие тысяч ключей в нескольких модах не оказывает измеримого влияния на производительность. Весь stringtable загружается в память при запуске.
  • Версия: Формат stringtable на основе CSV не менялся с альфы DayZ Standalone. Макет из 15 столбцов и поведение резервных вариантов оставались стабильными во всех версиях.

Released under CC BY-SA 4.0 | Code examples under MIT License