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

Введение

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

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

Примечание

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

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

Translations can get updated and re-imported when they change, but they still have to be added to the project. This is done in Project > Project Settings > Localization > Translations:

../../_images/localization_dialog.webp

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

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

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

The Remaps tab can be used for this:

../../_images/localization_remaps.webp

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

Примечание

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

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

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

It is recommended to default to the user's preferred language which can be obtained via OS.get_locale_language(). If your game is not available in that language, it will fall back to the Fallback in Project > Project Settings > General > Internationalization > Locale, or to en if empty. Nevertheless, letting players change the language in game is recommended for various reasons (e.g. translation quality or player preference).

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

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

Why locales exist can be illustrated through the USA and Great Britain. Both speak the same language (English), yet differ in many aspects:

  • Spelling: e.g. gray (USA), grey (GB)

  • Use of words: e.g. eggplant (USA), aubergine (GB)

  • Units or currencies: e.g. feet/inches (USA), metres/cm (GB)

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

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

Some controls, such as Button and Label, will automatically fetch a translation if their text matches a translation key. For example, if a label's text is MAIN_SCREEN_GREETING1 and that key exists in the current translation, then the text will automatically be translated.

This automatic translation behavior may be undesirable in certain cases. For instance, when using a Label to display a player's name, you most likely don't want the player's name to be translated if it matches a translation key. To disable automatic translation on a specific node, set the Auto Translate > Mode to Disabled in the inspector.

В коде можно использовать функцию 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

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

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

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

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

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

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

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

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

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

TranslationSеrver

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

Bidirectional text and UI mirroring

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

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

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

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

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

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

  • Uses mirrored order of the internal control elements (e.g., OptionButton dropdown button, CheckBox/CheckButton alignment, List column order, TreeItem icons and connecting line alignment). In some cases, mirrored controls use separate theme styles.

  • Coordinate system is not mirrored.

  • Non-UI nodes (sprites, etc.) are not affected.

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

  • text_direction, sets the base text direction. When set to "auto", the direction depends on the first strong directional character in the text according to the Unicode Bidirectional Algorithm.

  • language, overrides the current project locale.

  • The structured_text_bidi_override property and _structured_text_parser callback, enable special handling for structured text.

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

../../_images/ui_mirror.png

См. также

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

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

В некоторых языках нет пробелов. В этих языках для переноса слов и строк требуется больше, чем просто правила для последовательностей символов. Godot включает данные правил ICU и итераторов переноса на основе словаря, но эти данные по умолчанию не включаются в экспортируемые проекты.

To include it, go to Project > Project Settings > General > Internationalization > Locale and enable Include Text Server Data, then export the project. Break iterator data is about 4 MB in size.

Переопределение структурированного текста 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 предлагает три способа сделать это.

Under Project > Project Settings > General > Internationalization > Locale (with advanced settings enabled) is a Test property. Set this property to the locale code of the language you want to test. Godot will run the project with that locale when the project is run (either from the editor or when exported).

../../_images/locale_test.webp

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

Во-вторых, в редакторе перейдите на верхнюю панель и нажмите View на верхней панели, затем перейдите к Preview Translation и выберите язык, который вы хотите просмотреть.

../../_images/locale_editor_preview.webp

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

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

godot --language fr

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

The project name becomes the app name when exporting to different operating systems and platforms. To specify the project name in more than one language go to Project > Project Settings > General > Application > Config. From here click on the Localizable String (Size 0) button, then the Add Translation button. It will take you to a page where you can choose the language (and country if needed) for your project name translation. After doing that you can now type in the localized name.

../../_images/localized_name.webp

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