reckfellENGINE

Интернационализация игры и интерфейса

Автоматический перевод, вычисленный текст, замены ресурсов, шрифты, RTL и проверка запуска.

На этой странице

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

Подготовить проект

  1. Импортируйте и зарегистрируйте каталоги RU/EN по инструкции подключения переводов.
  2. Используйте постоянные ключи интерфейса. Задавайте контекст, если слово имеет разные значения; сохраняйте заполнители в каждом переводе.
  3. Выбирайте только среди языков, которые входят в игру. Применяйте сохранённый выбор после чтения настроек; иначе определяйте язык по локали ОС с явным резервным вариантом. Полный алгоритм для RU/EN есть в руководстве по локалям.
  4. Предоставьте переключатель языка. TranslationServer.SetLocale меняет текущий язык, но не сохраняет выбор.

Храните переводы в CSV или PO. Не заменяйте каталоги отдельными if/else для каждой надписи.

Автоматический, вычисленный и пользовательский текст

Тип текстаПодход
Постоянная подпись Label/ButtonСохраните ключ в Text и включите автоматический перевод
Счётчик, форматированный результат или составленное предложениеНайдите полный шаблон, при необходимости выберите форму числа, подставьте значения и обновляйте по уведомлению о смене перевода
Имя игрока, чат, внешний текстОтключите автоматический перевод и показывайте полученный текст

Label сохраняет исходный ключ в Text, хотя его внутренний переведённый текст меняется. Не считайте Text готовым отображаемым переводом. Отключение автоматического перевода может наследоваться от предка; режим Always позволяет переопределить это для отдельной Entity.

Полный локализованный интерфейс

Создайте VBoxContainer и прикрепите LocalizedHud.cs ниже. Зарегистрируйте таблицы с PLAY_KEY и ключами множественных форм ITEM/ITEMS. PLAY_KEY должен переводиться как Play/Играть; для ITEM/ITEMS используйте таблицу множественных форм CSV.

C#
using Reckfell;

public partial class LocalizedHud : VBoxContainer
{
    public Label PlayLabel { get; private set; } = null!;
    public Label PlayerLabel { get; private set; } = null!;
    public Label CountLabel { get; private set; } = null!;
    public int ItemCount { get; set; } = 5;

    public override void _Ready()
    {
        PlayLabel = new Label { Text = "PLAY_KEY" };
        PlayerLabel = new Label
        {
            AutoTranslateMode = AutoTranslateModeEnum.Disabled,
            Text = "PLAY_KEY"
        };
        CountLabel = new Label { AutoTranslateMode = AutoTranslateModeEnum.Disabled };
        AddChild(PlayLabel);
        AddChild(PlayerLabel);
        AddChild(CountLabel);
        RefreshCount();
    }

    public override void _Notification(int what)
    {
        if (what == NotificationTranslationChanged && CountLabel != null)
            RefreshCount();
    }

    public void RefreshCount()
    {
        string form = TranslationServer.TranslatePlural("ITEM", "ITEMS", ItemCount).ToString();
        CountLabel.Text = string.Format(form, ItemCount);
    }

    public void SetGameLocale(string locale)
    {
        TranslationServer.SetLocale(locale);
    }
}

Вызовите SetGameLocale("en"), затем SetGameLocale("ru"). Первая строка меняется с Play на Играть; вторая остаётся буквально PLAY_KEY, имитируя имя игрока, совпавшее с ключом; счётчик меняется с 5 items на 5 предметов. После изменения ItemCount вызывайте RefreshCount. Вместо диагностического имени передавайте настоящий пользовательский текст.

TranslatePlural выбирает шаблон, string.Format подставляет число. Не склеивайте отдельно переведённые фрагменты: переводчику может понадобиться другой порядок слов. Полное сообщение с заполнителями должно находиться в каталоге.

Контекст должен попасть в поиск

Для автоматического перевода Control задайте TranslationContext до присваивания Text. Для вычисленного текста передайте контекст непосредственно в TranslationServer.Translate. Изменение одного TranslationContext сейчас не пересчитывает существующий буфер перевода Label. После смены контекста вызовите label.PropagateNotification((int)Entity.NotificationTranslationChanged), где label — существующий Label. Повторное присваивание прежнего значения Text само по себе обновление не вызывает.

Локализованные ресурсы

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

Настройка project.reckfell ниже показывает замену ресурсов Gradient. При закрытом редакторе объедините её с существующим разделом internationalization:

Конфигурация
[internationalization]
locale/translation_remaps={"asset://Locale/palette.rdata": PackedStringArray("asset://Locale/palette-en.rdata:en", "asset://Locale/palette-ru.rdata:ru")}

Сначала создайте все три ресурса Gradient. Загружайте asset://Locale/palette.rdata. При смене локали загруженный ресурс с заменой перечитывается: кешированный объект может сохранить идентичность, изменив содержимое. Если подходящей альтернативы для локали нет, используется оригинал. Резервный язык текста автоматически не выбирает альтернативный ресурс: подготовьте подходящий оригинал.

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

Шрифты и вёрстка

Используйте актуальные ресурсы Font/FontFile и Font.Fallbacks, а не DynamicFont. Задавайте общую типографику через Theme, например DefaultFont, вместо замены у каждого Control. Подготовьте шрифты для настоящего текста, включая пользовательский ввод, язык которого может отличаться от интерфейса. Добавление резервного ресурса не доказывает покрытие символов: проверьте нужные знаки и соблюдайте лицензии шрифтов.

Label.Language влияет на обработку текста; он не меняет локаль TranslationServer и не выбирает другой каталог. TextDirection управляет направлением текста, Control.LayoutDirection — направлением раскладки интерфейса. Это разные настройки. Для путей и других структурированных строк может понадобиться StructuredTextBidiOverride вместо обычного порядка абзаца.

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

Разрешайте контейнерам расти, а надписям — переноситься там, где это нужно; проверяйте минимальный размер окна. Для проверки длины используйте псевдолокализацию, учитывая ограничения заполнителей C# и множественных форм. Латинский текст с диакритикой не заменяет проверку китайского, японского, корейского или RTL.

TranslationServer.FormatNumber/ParseNumber преобразуют символы поддерживаемых систем счисления, но не задают полные правила валют, единиц и культурного форматирования. Отделяйте формат чисел от выбора каталога. Для языков со словарным разбиением строк проверьте internationalization/locale/include_text_server_data и экспортированную сборку с нужной поддержкой TextServer; не переносите результат редактора на экспорт без проверки.

Проверить запуск и настройки выпуска

internationalization/locale/test принудительно задаёт локаль запуска. Сбросьте значение перед выпуском, если игра должна выбирать язык игрока. Параметр командной строки может переопределить тестовую настройку:

PowerShell
& "C:\path\Reckfell Engine.console.exe" --path "C:\path\Game" --language ru

Замените оба пути на установленный исполняемый файл и проект. Код, который позже вызывает SetLocale, всё ещё может изменить язык.

Для локализованного названия приложения application/config/name_localized хранит соответствия локалей и названий. Проверяйте метаданные экспортированного приложения на целевой платформе: перевод Label внутри игры не подтверждает название в системе или магазине.

Приёмка и диагностика

ОшибкаПервая проверка
Видно ключРегистрация, точный ключ/контекст, активная локаль и резервный язык
Обычная подпись обновилась, счётчик — нетОбработчик уведомления и повторное форматирование шаблона
Имя игрока неожиданно перевелосьAutoTranslateMode этого элемента
Текст поменялся, локализованный ресурс — нетИсходный путь загрузки, альтернативы и кешированное состояние потребителя
Строка правильная, но есть квадраты, обрезка или неверное направлениеОтдельно покрытие шрифта, обработка текста и вёрстка
Язык сбросился после перезапускаСохранённый выбор и тестовая настройка запуска

В движке проверены точный пример интерфейса, текстовые буферы Label, наследование перевода, обновление контекста, отличие локали от Language, замены загруженного Gradient и язык командной строки. Также проверены явные флаги RTL и API резервных шрифтов FontFile. Это не подтверждает отображение символов, зеркальную вёрстку, отсутствие обрезки, воспроизведение изображений/звука, сохранение выбора, работу в редакторе или экспорт. Для них нужны отдельные проверки приёмки.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.