Перейти к содержимому

Языки и переводы

Интерфейс игры может работать на 9 языках: en, pt, de, pl, tr, es, fr, it, ru. Не все строки пока переведены, всё отсутствующее откатывается на английский.

  • Выбор каждого игрока сохраняется для аккаунта (bs_users.language, добавлено миграцией 030_user_language.sql) и публикуется в state bag игрока bs_lang.
  • Пустой выбор означает “следовать языку сервера по умолчанию”. Он берётся из F1 Global.defaultLanguage, иначе из convar bs_defaultLanguage, иначе en. Лежит в GlobalState.bs_defaultLang.
  • Игроки меняют его на вкладке Settings в инвентаре. Это вызывает bs_core:setLanguage, и каждый resource обновляется вживую, без переподключения.
  • exports.bs_core:GetLanguage(src) возвращает язык игрока на сервере.

Resource с папкой locales/ на данный момент: bs_admin, bs_bodily, bs_boosters, bs_building, bs_chat, bs_cinecam, bs_core, bs_crafting, bs_drugs, bs_economy, bs_emotes, bs_events, bs_extraction, bs_faction_bases, bs_factions, bs_gadgets, bs_gates, bs_interactions, bs_inventory, bs_jobs, bs_medical, bs_menu, bs_mining, bs_multichar, bs_radial, bs_recycler, bs_scenes, bs_scoreboard, bs_skills, bs_stash, bs_tester, bs_traders, bs_ui, bs_vehicles, bs_vip, bs_weapons, bs_zombies.

Функции Lua и NUI описаны в API локалей.

shared_script '@bs_core/shared/sh_locale.lua'
files { 'locales/*.lua' }

Каждый файл возвращает плоскую таблицу. {name} - плейсхолдер.

-- locales/en.lua
return {
['ui.level'] = 'LEVEL',
['msg.picked_up'] = 'You picked up {item}.',
}

Скопируй en.lua в pt.lua (и так далее) и переведи значения. Ключи никогда не переводи. Отсутствующий ключ откатывается на английский, затем на сам ключ, так что наполовину готовый файл - это нормально.

-- client: the local player's language
local s = L('msg.picked_up', { item = 'Bandage' })
-- server: L(src, key, vars) or Lp(src, key, vars) uses that player's language
TriggerClientEvent('chat:addMessage', src, { args = { L(src, 'msg.picked_up', { item = 'Bandage' }) } })
-- server without a source: the server default
print(L('msg.picked_up', { item = 'Bandage' }))

BSLocale.OnChange(function(lang) ... end) срабатывает на клиенте при смене языка, для текста, который ты собрал сам.

Если у resource есть ui_page, скрипт локалей отправляет на страницу объединённую таблицу. Подключи общий helper до скрипта своей страницы:

<script src="nui://bs_ui/html/js/i18n.js"></script>

Затем размечай HTML. Английский текст в разметке служит запасным вариантом:

<span data-i18n="ui.level">LEVEL</span>
<p data-i18n-html="ui.help_html">Press <b>E</b></p>
<input data-i18n-attr="placeholder:ui.search;title:ui.search_tip" placeholder="Search">

В JS используй t('key', { name: 'x' }) и BSI18n.onChange(fn), чтобы перерисовывать динамический текст.

  • Держи ключи стабильными и сгруппированными (ui., msg., err.). Смена ключа ломает все его переводы.
  • Не пиши текст про баланс с жёстко вшитыми числами, используй плейсхолдеры, чтобы число следовало за конфигом.