Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

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

Введение

Sería excelente que el mundo hablara solo un idioma (Было бы замечательно, если бы весь мир говорил только на одном языке). К сожалению, для нас, разработчиков, это не так. Если инди- или нишевые игры обычно не нуждаются в локализации, то игры, ориентированные на массовый рынок, часто требуют это. Godot предлагает множество инструментов, чтобы упростить этот процесс, поэтому данное руководство больше похоже на сборник советов и приёмов.

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

Примечание

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

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

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

../../_images/localization_dialog.png

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

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

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

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

../../_images/localization_remaps.png

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

Примечание

The resource remapping system isn't supported for DynamicFonts. To use different fonts depending on the language's script, use the DynamicFont fallback system instead, which lets you define as many fallback fonts as you want.

The upside of the DynamicFont fallback system is that it works regardless of the current language, making it ideal for things like multiplayer chat where the text language may not match the client's language.

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

Некоторые элементы управления, такие как 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. Обязательно загрузите правильный вариант, если вы используете менее распространенный язык.

Once you've downloaded the font, load the TTF file into a DynamicFont resource and use it as a custom font of your Control node. For better reusability, associate a new a Theme resource to your root Control node and define the DynamicFont as the Default Font in the theme.

Placeholders

To feature placeholders in your translated strings, use Форматирование строки GDScript or the equivalent feature in C#. This lets translators move the location of the placeholder in the string freely, which allows translations to sound more natural. Named placeholders with the String.format() function should be used whenever possible, as they also allow translators to choose the order in which placeholders appear:

# 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

If you're using plain English as source strings (rather than message codes LIKE_THIS), you may run into ambiguities when you have to translate the same English string to different strings in certain target languages. You can optionally specify a translation context to resolve this ambiguity and allow target languages to use different strings, even though the source string is identical:

# "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

Most languages require different strings depending on whether an object is in singular or plural form. However, hardcoding the "is plural" condition depending on whether there is more than 1 object is not valid in all languages.

Some languages have more than two plural forms, and the rules on the number of objects required for each plural form vary. Godot offers support for pluralization so that the target locales can handle this automatically.

Pluralization is meant to be used with positive (or zero) integer numbers only. Negative and floating-point values usually represent physical entities for which singular and plural don't clearly apply.

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

This can be combined with a context if needed:

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

Примечание

Providing pluralized translations is only supported with Локализация с помощью gettext, not CSV.

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

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

To check whether your UI can accommodate translations with longer strings than the original, you can enable pseudolocalization in the advanced Project Settings. This will replace all your localizable strings with longer versions of themselves, while also replacing some characters in the original strings with accented versions (while still being readable). Placeholders are kept as-is, so that they keep working when pseudolocalization is enabled.

For example, the string Hello world, this is %s! becomes [Ĥéłłô ŵôŕłd́, ŧh̀íš íš %s!] when pseudolocalization is enabled.

While looking strange at first, pseudolocalization has several benefits:

  • It lets you spot non-localizable strings quickly, so you can go over them and make them localizable (if it makes sense to do so).

  • It lets you check UI elements that can't fit long strings. Many languages will feature much longer translations than the source text, so it's important to ensure your UI can accommodate longer-than-usual strings.

  • It lets you check whether your font contains all the characters required to support various languages. However, since the goal of pseudolocalization is to keep the original strings readable, it's not an effective test for checking whether a font can support CJK or right-to-left languages.

The project settings allow you to tune pseudolocalization behavior, so that you can disable parts of it if desired.

TranslationSеrver

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

Bidirectional text and UI Mirroring

Arabic and Hebrew are written from right to left (except for the numbers and Latin words mixed in), and the user interface for these languages should be mirrored as well. In some languages the shape of a glyph changes depending on the surrounding characters.

Support for bidirectional writing systems and UI mirroring is transparent, you don't usually need to change anything or have any knowledge of the specific writing system.

For RTL languages, Godot will automatically do the following changes to the UI:

  • Mirrors left/right anchors and margins.

  • Swaps left and right text alignment.

  • Mirrors horizontal order of the child controls in the containers, and items in Tree/ItemList controls.

  • Uses mirrored order of the internal control elements (e.g. OptionButton dropdown button, checkbox alignment, List column order, Tree item icons and connecting line alignment, e.t.c.), in some cases mirrored controls use separate theme styles.

  • Coordinate system is not mirrored, and non-UI nodes (sprites, e.t.c) are not affected.

It is possible to override text and control layout direction by using the following control properties:

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

  • language, overrides current project locale.

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

  • layout_direction, overrides control mirroring.

../../_images/ui_mirror.png

См.также

You can see how right-to-left typesetting works in action using the BiDI and Font Features demo project.

Adding break iterator data to exported project

Some languages are written without spaces, and word and line breaking requires more than rules over character sequences. Godot includes ICU rule and dictionary based, break iterator data, but this data is not included into exported projects by default. To include it go to Project → Project Settings → Localization → Text Server Data and click Install support data.... Break iterator data is about 4 MB large.

../../_images/icu_data.png

Structured text BiDi override

Unicode BiDi algorithm is designed to work with natural text and it's incapable of handling text with the higher level order, like file names, URIs, email addresses, regular expressions or source code.

../../_images/bidi_override.png

For example, the path for this shown directory structure will be displayed incorrectly (top "LineEdit" control). "File" type structured text override splits text into segments, then BiDi algorithm is applied to each of them individually to correctly display directory names in any language and preserve correct order of the folders (bottom "LineEdit" control).

Custom callbacks provide a way to override BiDi for the other types of structured text.

Localizing numbers

Controls specifically designed for number input or output (e.g. ProgressBar, SpinBox) will use localized numbering system automatically, for the other control TextServer.format_number(string, language) can be used to convert Western Arabic numbers (0..9) to the localized numbering system and TextServer.parse_number(string, language) to convert it back.

Localizing icons and images

Icons with left and right pointing arrows which may need to be reversed for Arabic and Hebrew locales, in case they indicate movement or direction (e.g. back/forward buttons). Otherwise, they can remain the same.

Testing translations

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

First, in the Project Settings, under Internationalization > Locale (with advanced settings enabled), there 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

Keep in mind that since this is a project setting, it will show up in version control when it is set to a non-empty value. Therefore, it should be set back to an empty value before committing changes to version control.

Translations can also be tested when running Godot from the command line. For example, to test a game in French, the following argument can be supplied:

godot --language fr

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

Имя проекта становится именем приложения при экспорте в различные операционные системы и платформы. Чтобы указать имя проекта на нескольких языках, создайте новый параметр application/name в Project Settings и добавьте к нему идентификатор локали. Например, для испанского языка это будет application/name_es:

../../_images/localized_name.png

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