Локализация игр

Введение

Хотя инди- или нишевые игры обычно не требуют локализации, игры, ориентированные на более массовый рынок, часто требуют локализации. Godot предлагает множество инструментов для упрощения этого процесса, поэтому это руководство скорее похоже на сборник советов и рекомендаций.

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

Примечание

В качестве примера мы будем использовать официальную демо-версию; вы можете скачать ее из библиотеки ресурсов.

Настройка импортированного перевода

Переводы могут обновляться и повторно импортироваться при их изменении, но они все равно должны быть добавлены в проект. Это делается в разделе Проект → Настройки проекта → Локализация:

../../_images/localization_dialog.png

Приведенное выше диалоговое окно используется для добавления или удаления переводов в рамках всего проекта.

Локализация ресурсов

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

Для этого можно использовать вкладку Переназначения (Remaps):

../../_images/localization_remaps.png

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

Примечание

Система переназначения ресурсов не поддерживается для DynamicFonts. Чтобы использовать разные шрифты в зависимости от письменности языка, используйте резервную систему DynamicFont, которая позволяет определить любое количество резервных шрифтов.

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

Автоматическая установка языка

Рекомендуется использовать предпочитаемый пользователем язык по умолчанию, который можно получить с помощью OS.get_locale_language(). Если игра недоступна на этом языке, она будет переключена на Fallback в разделе Project Settings > Internationalization > Locale, или на en, если он пуст. Тем не менее, по разным причинам (например, из-за качества перевода или предпочтений игроков) рекомендуется разрешить игрокам менять язык в игре.

var language = "automatic"
# Load here language from the user settings file
if language == "automatic":
   var preferred_language = OS.get_locale_language()
   TranslationServer.set_locale(preferred_language)
else:
   TranslationServer.set_locale(language)

Локаль vs. языка

locale обычно представляет собой комбинацию языка с регионом или страной, но может также содержать информацию, например, о письменности или варианте.

Примеры:

  • en: English язык

  • en_GB: English в Great Britain (Великобритания) / British English

  • en_US: English в USA / American English

  • en_DE: English в Germany

Инди-играм, как правило, важен только язык, но читайте дальше, чтобы узнать больше.

Причины существования локальных различий можно проиллюстрировать на примере США и Великобритании. Обе страны говорят на одном языке (English), но во многом различаются: - Орфография: например, gray (США), grey (Великобритания). - Использование слов: например, eggplant (США), aubergine (Великобритания). - Единицы измерения или валюты: например, футы/дюймы (США), метры/см (Великобритания)

Однако это может быть сложнее. Представьте, что вы предлагаете разный контент в Европе и Китае (например, в MMO). Вам потребуется перевести каждый из этих вариантов контента на множество языков, а также хранить и загружать их соответствующим образом.

Преобразование ключей в текст

Некоторые элементы управления, такие как Button и Label, автоматически получают перевод, если их текст соответствует ключу перевода. Например, если текст метки имеет значение "MAIN_SCREEN_GREETING1" и этот ключ существует в текущем переводе, то текст будет автоматически переведен.

Такое автоматическое поведение перевода может быть нежелательным в некоторых случаях. Например, при использовании узла Label для отображения имени игрока вы, скорее всего, не захотите, чтобы имя игрока переводилось, если оно соответствует ключу перевода. Чтобы отключить автоматический перевод на определенном узле, отключите «Локализация» > «Автоперевод» в инспекторе.

В коде можно использовать функцию Object.tr(). Она будет просто искать текст в переводах и преобразовывать его, если он найден:

level.text = tr("LEVEL_5_NAME")
status.text = tr("GAME_STATUS_%d" % status_index)

Примечание

Если после смены языка текст не отображается, попробуйте использовать другой шрифт. Шрифт проекта по умолчанию поддерживает только подмножество набора символов Latin-1, который нельзя использовать для отображения таких языков, как русский или китайский.

Хорошим ресурсом по многоязычным шрифтам является Noto Fonts. Обязательно загрузите правильный вариант, если вы используете менее распространенный язык.

После загрузки шрифта загрузите TTF-файл в ресурс DynamicFont и используйте его в качестве пользовательского шрифта вашего узла Control. Для удобства повторного использования свяжите новый ресурс Theme с корневым узлом Control и определите DynamicFont как шрифт по умолчанию в теме.

Placeholders (Заполнители)

Чтобы добавить особенные заполнители в переведённые строки, используйте функцию Форматирование строки GDScript или эквивалентную функцию в C#. Это позволяет переводчикам свободно перемещать местоположение заполнителя в строке, что делает перевод более естественным. По возможности следует использовать именованные заполнители с функцией String.format(), поскольку они также позволяют переводчикам выбирать порядок отображения заполнителей:

# The placeholder's locations can be changed, but not their order.
# This will probably not suffice for some target languages.
message.text = tr("%s picked up the %s") % ["Ogre", "Sword"]

# The placeholder's locations and order can be changed.
# Additionally, this form gives more context for translators to work with.
message.text = tr("{character} picked up the {weapon}").format({character = "Ogre", weapon = "Sword"})

Translation contexts (Контексты перевода)

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

# "Close", as in an action (to close something).
button.set_text(tr("Close", "Actions"))

# "Close", as in a distance (opposite of "far").
distance_label.set_text(tr("Close", "Distance"))

Pluralization (Множественность)

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

В некоторых языках существует более двух форм множественного числа, и правила относительно количества объектов, необходимых для каждой формы, различаются. Godot поддерживает образование множественного числа (pluralization), чтобы целевые языки могли обрабатывать это автоматически.

Множественное число следует использовать только с положительными (или нулевыми) целыми числами. Отрицательные числа и числа с плавающей запятой обычно представляют физические объекты, для которых единственное и множественное число не имеют явного соответствия.

var num_apples = 5
label.text = tr_n("There is %d apple", "There are %d apples", num_apples) % num_apples

При необходимости это можно объединить с контекстом:

var num_jobs = 1
label.text = tr_n("%d job", "%d jobs", num_jobs, "Task Manager") % num_jobs

Примечание

Предоставление переводов во множественном числе поддерживается только с помощью Локализация с помощью gettext, а не CSV.

Изменение размеров элементов управления

Один и тот же текст на разных языках может сильно отличаться по длине. Для этого обязательно прочитайте руководство по Размер и якоря, так как динамическая настройка размеров элементов управления может помочь. Container может быть полезен, также как и опции обертывания текста, доступные в Label.

Чтобы проверить, поддерживает ли ваш пользовательский интерфейс (UI) переводы с более длинными строками, чем исходный текст, можно включить псевдолокализацию в расширенных настройках проекта. Это заменит все локализуемые строки их более длинными версиями, а также заменит некоторые символы в исходных строках их диакритическими версиями (при этом они останутся читаемыми). Заполнители сохраняются как есть, поэтому они продолжают работать при включении псевдолокализации.

Например, строка Hello world, this is %s! становится [Ĥéłłô ŵôŕłd́, ŧh̀íš íš %s!], если включена псевдолокализация.

Хотя на первый взгляд это может показаться странным, псевдолокализация имеет ряд преимуществ:

  • Это позволяет быстро обнаружить нелокализуемые строки, чтобы можно было просмотреть их и сделать локализуемыми (если это имеет смысл).

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

  • Он позволяет проверить, содержит ли ваш шрифт все символы, необходимые для поддержки различных языков. Однако, поскольку цель псевдолокализации — сохранить читаемость исходных строк, этот тест неэффективен для проверки поддержки шрифтом CJK или языков с письмом справа налево.

Настройки проекта позволяют настраивать поведение псевдолокализации, так что при желании можно отключить ее части.

TranslationSеrver

В Godot есть сервер, отвечающий за низкоуровневое управление переводами, который называется TranslationServer. Переводы можно добавлять и удалять во время выполнения; текущий язык также можно изменить во время выполнения.

Двунаправленный текст и Зеркалирование Пользовательского Интерфейса

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

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

Для языков с написанием справа налево Godot автоматически внесет следующие изменения в пользовательский интерфейс:

  • Mirrors отображает левые/правые якоря и поля.

  • Меняет местами выравнивание текста слева и справа.

  • Mirrors отображает горизонтальный порядок дочерних элементов управления в контейнерах и элементов в элементах управления Tree/ItemList.

  • Использует зеркальный порядок внутренних элементов управления (например, кнопка раскрывающегося списка OptionButton, выравнивание флажков, порядок столбцов списка, значки элементов дерева и выравнивание соединительных линий и т. д.), в некоторых случаях зеркальные элементы управления используют отдельные стили темы.

  • Система координат не зеркальна, и узлы, не относящиеся к пользовательскому интерфейсу (спрайты и т. д.), не затрагиваются.

Можно переопределить текст и управлять направлением макета, используя следующие свойства элемента управления:

  • text_direction — задаёт базовое направление текста. При значении "auto" направление определяется первым чётким символом направления в тексте в соответствии с Unicode Bidirectional Algorithm (Двунаправленный алгоритм Unicode),

  • language, переопределяет текущую локаль проекта.

  • structured_text_bidi_override свойство и обратный вызов _structured_text_parser позволяют выполнять специальную обработку структурированного текста.

  • layout_direction, переопределяет управление зеркалированием.

../../_images/ui_mirror.png

См. также

Вы можете увидеть, как работает набор текста справа налево, используя BiDI and Font Features demo project.

Добавление данных итератора прерывания в экспортированный проект

В некоторых языках используются пробелы, и для переноса слов и строк требуется больше, чем просто правила для последовательностей символов. Godot включает данные итератора разрыва на основе правил ICU и словаря, но эти данные по умолчанию не включаются в экспортируемые проекты. Чтобы включить их, перейдите в раздел Project → Project Settings → Localization → Text Server Data и нажмите Install support data.... Размер данных итератора разрыва составляет около 4 МБ.

../../_images/icu_data.png

Переопределение структурированного текста BiDi

Алгоритм Unicode BiDi предназначен для работы с естественным текстом и не способен обрабатывать текст с более высоким уровнем порядка, таким как имена файлов, URI, адреса электронной почты, регулярные выражения или исходный код.

../../_images/bidi_override.png

Например, путь для этой показанной структуры каталогов будет отображаться некорректно (верхний элемент управления "LineEdit"). Переопределение структурированного текста типа "File" разбивает текст на сегменты, а затем к каждому из них применяется алгоритм BiDi индивидуально для корректного отображения имён каталогов на любом языке и сохранения правильного порядка папок (нижний элемент управления "LineEdit").

Пользовательские обратные вызовы предоставляют возможность переопределить BiDi для других типов структурированного текста.

Локализация чисел

Элементы управления, специально разработанные для ввода или вывода чисел (например, ProgressBar, SpinBox), будут автоматически использовать локализованную систему исчисления, для других элементов управления TextServer.format_number(string, language) можно использовать для преобразования западных арабских чисел (0..9) в локализованную систему исчисления и TextServer.parse_number(string, language) для обратного преобразования.

Локализация иконок и изображений

Значки со стрелками, направленными влево и вправо, могут потребовать замены для Арабской и Ивритской локалей, если они обозначают движение или направление (например, кнопки «назад»/«вперёд»). В противном случае их можно оставить без изменений.

Тестирование переводов

Вам может потребоваться протестировать перевод проекта перед его выпуском. Godot предоставляет два способа сделать это.

Во-первых, в Project Settings, в разделе Internationalization > Locale (при включенных расширенных настройках), есть свойство Test. Задайте для него код локали языка, который вы хотите протестировать. Godot запустит проект с этой локалью при запуске (из редактора или при экспорте).

../../_images/locale_test.webp

Имейте в виду, что, поскольку это project setting, она отобразится в системе контроля версий, если ей присвоено непустое значение. Поэтому перед внесением изменений в систему контроля версий следует вернуть ей пустое значение.

Переводы также можно тестировать, запуская Godot из командной строки. Например, для тестирования игры на французском языке можно указать следующий аргумент:

godot --language fr

Перевод названия проекта

Название проекта становится названием приложения при экспорте в различные операционные системы и платформы. Чтобы указать название проекта на нескольких языках, перейдите в раздел Project > Project Settings> Application > Config. Нажмите кнопку Localizable String (Size 0). Под ней должна появиться кнопка Add Translation. Нажмите на неё, и вы перейдёте на страницу, где можно выбрать язык (и страну, если необходимо) для перевода названия проекта. После этого можно ввести локализованное название.

../../_images/localized_name.webp

Если вы не уверены в том, какой код языка использовать, обратитесь к списку кодов локалей.