Глава 5.1: stringtable.csv --- Локализация
Главная | stringtable.csv | Далее: inputs.xml >>
Краткое содержание: Файл
stringtable.csvпредоставляет локализованный текст для вашего мода DayZ. Движок читает этот CSV при запуске и разрешает ключи переводов на основе языковых настроек игрока. Каждая строка, видимая пользователю --- метки UI, названия привязок клавиш, описания предметов, текст уведомлений --- должна находиться в stringtable, а не быть жёстко закодированной.
Содержание
- Обзор
- Формат CSV
- Справочник столбцов
- Соглашение об именовании ключей
- Использование строк
- Создание нового stringtable
- Обработка пустых ячеек и поведение резервного варианта
- Многоязычный рабочий процесс
- Модульный подход к stringtable (DayZ Expansion)
- Реальные примеры
- Распространённые ошибки
Обзор
DayZ использует систему локализации на основе CSV. Когда движок встречает строковый ключ с префиксом # (например, #STR_MYMOD_HELLO), он ищет этот ключ во всех загруженных файлах stringtable и возвращает перевод, соответствующий текущему языку игрока. Если совпадение для активного языка не найдено, движок следует по цепочке резервных вариантов.
Файл stringtable должен называться строго stringtable.csv и размещаться внутри PBO-структуры вашего мода. Движок обнаруживает его автоматически --- регистрация в config.cpp не требуется.
Формат CSV
Файл представляет собой стандартный файл значений, разделённых запятыми, с полями в кавычках. Первая строка --- заголовок, каждая последующая строка определяет один ключ перевода.
Строка заголовка
Строка заголовка определяет столбцы. DayZ поддерживает до 15 столбцов:
"Language","original","english","czech","german","russian","polish","hungarian","italian","spanish","french","chinese","japanese","portuguese","chinesesimp",Строки данных
Каждая строка начинается с ключа строки (без префикса # в 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 (родной язык автора мода или текст по умолчанию).
| # | Имя столбца | Язык | Примечания |
|---|---|---|---|
| 1 | Language | --- | Идентификатор строкового ключа (например, STR_MYMOD_HELLO) |
| 2 | original | Родной язык автора | Резервный вариант последней инстанции; используется, если ни один другой столбец не подходит |
| 3 | english | Английский | Наиболее распространённый основной язык для международных модов |
| 4 | czech | Чешский | |
| 5 | german | Немецкий | |
| 6 | russian | Русский | |
| 7 | polish | Польский | |
| 8 | hungarian | Венгерский | |
| 9 | italian | Итальянский | |
| 10 | spanish | Испанский | |
| 11 | french | Французский | |
| 12 | chinese | Китайский (традиционный) | Традиционные китайские иероглифы |
| 13 | japanese | Японский | |
| 14 | portuguese | Португальский | |
| 15 | chinesesimp | Китайский (упрощённый) | Упрощённые китайские иероглифы |
Порядок столбцов имеет значение
Движок определяет столбцы по имени заголовка, а не по позиции. Однако соблюдение стандартного порядка, показанного выше, настоятельно рекомендуется для совместимости и читаемости.
Необязательные столбцы
Вам не нужно включать все 15 столбцов. Если ваш мод поддерживает только английский язык, можно использовать минимальный заголовок:
"Language","english"
"STR_MYMOD_HELLO","Hello World"Некоторые моды добавляют нестандартные столбцы, например korean (MyMod Missions). Движок игнорирует столбцы, которые не распознаёт как поддерживаемый язык, но эти столбцы могут служить документацией или подготовкой к будущей поддержке языков.
Соглашение об именовании ключей
Строковые ключи следуют иерархическому шаблону именования:
STR_MODNAME_CATEGORY_ELEMENTПравила
- Всегда начинайте с
STR_--- это универсальное соглашение DayZ - Префикс мода --- уникально идентифицирует ваш мод (например,
MYMOD,COT,EXPANSION,VPP) - Категория --- группирует связанные строки (например,
INPUT,TAB,CONFIG,DIR) - Элемент --- конкретная строка (например,
ADMIN_PANEL,NORTH,SAVE) - Используйте ЗАГЛАВНЫЕ БУКВЫ --- соглашение всех крупных модов
- Используйте подчёркивания как разделители, никогда пробелы или дефисы
Примеры из реальных модов
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() для разрешения ключа во время выполнения. Префикс # обязателен в аргументе.
string translated = Widget.TranslateString("#STR_MYMOD_CLOSE");
// translated == "Close" (если язык игрока --- английский)
// translated == "Fechar" (если язык игрока --- португальский)Также можно установить текст виджета напрямую:
TextWidget label = TextWidget.Cast(layoutRoot.FindAnyWidget("MyLabel"));
label.SetText(Widget.TranslateString("#STR_MYMOD_ADMIN_PANEL"));Или использовать строковые ключи непосредственно в свойствах текста виджета, и движок разрешит их:
label.SetText("#STR_MYMOD_ADMIN_PANEL"); // Тоже работает -- движок автоматически разрешаетВ inputs.xml
Используйте атрибут loc без префикса #.
<input name="UAMyAction" loc="STR_MYMOD_INPUT_MY_ACTION" />Это единственное место, где вы опускаете #. Система ввода добавляет его внутренне.
Сводная таблица
| Контекст | Синтаксис | Пример |
|---|---|---|
Атрибут text файла макета | #STR_KEY | text "#STR_MYMOD_CLOSE" |
TranslateString() в скрипте | "#STR_KEY" | Widget.TranslateString("#STR_MYMOD_CLOSE") |
| Текст виджета в скрипте | "#STR_KEY" | label.SetText("#STR_MYMOD_CLOSE") |
Атрибут loc в inputs.xml | STR_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 столбцов:
"Language","original","english","czech","german","russian","polish","hungarian","italian","spanish","french","chinese","japanese","portuguese","chinesesimp",Шаг 3: Добавление строк
Добавляйте по одной строке на каждую переводимую строку. Начните с английского языка, заполняйте другие языки по мере появления переводов:
"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" в логах скриптов. Смените язык игры в настройках для проверки поведения резервного варианта.
Обработка пустых ячеек и поведение резервного варианта
Когда движок ищет строковый ключ для текущего языка игрока и находит пустую ячейку, он следует по цепочке резервных вариантов:
- Столбец выбранного языка игрока --- проверяется первым
- Столбец
english--- если ячейка языка игрока пуста - Столбец
original--- еслиenglishтоже пуст - Необработанное имя ключа --- если все столбцы пусты, движок отображает сам ключ (например,
STR_MYMOD_TITLE)
Это означает, что вы можете безопасно оставлять неанглийские столбцы пустыми во время разработки. Англоговорящие игроки видят столбец english, а другие игроки видят резервный английский вариант, пока не будет добавлен правильный перевод.
Практическое следствие
Вам не нужно копировать английский текст в каждый столбец в качестве заглушки. Оставляйте непереведённые ячейки пустыми:
"STR_MYMOD_HELLO","Hello","Hello","","","","","","","","","","","","",Игроки, у которых установлен немецкий язык, увидят "Hello" (резервный английский вариант), пока не будет предоставлен немецкий перевод.
Многоязычный рабочий процесс
Для одиночных разработчиков
- Напишите все строки на английском языке (столбцы
originalиenglish). - Выпустите мод. Английский служит универсальным резервным вариантом.
- По мере появления добровольцев-переводчиков заполняйте дополнительные столбцы.
- Пересоберите и выпустите обновления.
Для команд с переводчиками
- Храните CSV в общем репозитории или электронной таблице.
- Назначьте одного переводчика на каждый язык.
- Используйте столбец
originalдля родного языка автора (например, португальский для бразильских разработчиков). - Столбец
englishвсегда заполнен --- это международный базовый вариант. - Используйте инструмент сравнения различий для отслеживания ключей, добавленных с момента последнего прохода перевода.
Использование табличного ПО
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 поддерживаемых языков:
"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:
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_:
"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:
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 служит документацией до тех пор, пока не будет добавлена официальная поддержка корейского языка.
Распространённые ошибки
Пропуск префикса # в скриптах
// НЕПРАВИЛЬНО -- отображает сырой ключ, а не перевод
label.SetText("STR_MYMOD_HELLO");
// ПРАВИЛЬНО
label.SetText("#STR_MYMOD_HELLO");Использование # в inputs.xml
<!-- НЕПРАВИЛЬНО -- система ввода добавляет # внутренне -->
<input name="UAMyAction" loc="#STR_MYMOD_MY_ACTION" />
<!-- ПРАВИЛЬНО -->
<input name="UAMyAction" loc="STR_MYMOD_MY_ACTION" />Дублирование ключей между модами
Если два мода определяют STR_CLOSE, движок использует тот, чей PBO загрузился последним. Всегда используйте префикс вашего мода:
"STR_MYMOD_CLOSE","Close","Close",...Несовпадение количества столбцов
Если строка имеет меньше столбцов, чем заголовок, движок может молча пропустить её или назначить пустые строки для отсутствующих столбцов. Всегда убеждайтесь, что каждая строка имеет то же количество полей, что и заголовок.
Проблемы с BOM
Некоторые текстовые редакторы вставляют UTF-8 BOM (маркер порядка байтов) в начало файла. Это может привести к тому, что первый строковый ключ в CSV будет молча повреждён. Если ваш первый строковый ключ не разрешается, проверьте и удалите BOM.
Использование запятых внутри полей без кавычек
STR_MYMOD_MSG,Hello, World,Hello, World,...Это нарушает парсинг, потому что Hello и World читаются как отдельные столбцы. Заключите поле в кавычки или избегайте запятых в значениях:
"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 столбцов и поведение резервных вариантов оставались стабильными во всех версиях.
