Lokalizacje skryptów FiveM: tłumaczalne skrypty z en.lua, ox_lib i ESX
Uczyń swój skrypt FiveM tłumaczalnym: folder locales z en.lua i es.lua, prosta funkcja locale, system locale ox_lib, ESX TranslateCap i konfiguracja języka.
Twój skrypt ma 'You have no money' na stałe zakodowany w czterdzieści miejscach. Właściciel serwera w Madrycie lub Berlinie chce tego w jego języku, a jedynym sposobem jest edycja kodu. Rozwiązaniem jest warstwa locale: stringi żyją w plikach dla każdego języka, kod prosi o klucze. Ten przewodnik pokazuje prostą wersję czystego Lua, potem system ox_lib i ESX.
Pomysł
Zamiast:
ESX.ShowNotification('You have no money')kod pisze:
ESX.ShowNotification(L('no_money'))i plik języka dostarcza tekst dla no_money. Tłumacze potem zmieniają pliki, nigdy kod, i otwórz pliki locale mogą być wysyłane nieszyfrowane (zobacz escrow_ignore).
Prosta funkcja locale Lua
Układ foldera:
my_script/
fxmanifest.lua
config.lua
locales/
en.lua
es.lua
shared/locale.lualocales/en.lua:
Locales = Locales or {}
Locales['en'] = {
no_money = 'You have no money',
bought = 'You bought %s for $%s',
}locales/es.lua:
Locales = Locales or {}
Locales['es'] = {
no_money = 'No tienes dinero',
bought = 'Compraste %s por $%s',
}shared/locale.lua, funkcja, która wygląda klucz:
function L(key, ...)
local lang = Locales[Config.Locale] or Locales['en']
local text = lang[key] or Locales['en'][key] or key
if select('#', ...) > 0 then
return text:format(...)
end
return text
endManifest, z locales najpierw i konfigu przed funkcją:
fx_version 'cerulean'
game 'gta5'
shared_scripts {
'config.lua',
'locales/*.lua',
'shared/locale.lua',
}
client_script 'client/main.lua'
server_script 'server/main.lua'I w config.lua:
Config = {}
Config.Locale = 'en'Użycie, z %s placeholders wypełnionymi przez string.format:
print(L('bought', 'bread', 5)) -- You bought bread for $5Fallbacky ma znaczenie: brakujący klucz w es wraca do en, i brakujący klucz wszędzie zwraca klucz sam, więc widzisz no_money na ekranie zamiast błędu. Dziura w tłumaczeniu potem pokazuje się jako widoczny klucz, nie crash.
Wskazówka: utrzymuj te same klucze w każdym pliku języka. Mały skrypt, który porównuje klucze
enz każdym innym plikiem, łapie brakujące tłumaczenia przed wydaniem.
System locale ox_lib
Jeśli Twój skrypt już zależy od ox_lib, możesz użyć jego wbudowanej locales zamiast pisania L(). Kształt to: załaduj ox_lib w manifestcie, umieść swoje tłumaczenia w folderze locales/ (ox_lib używa plików .json nazwanych według języka, jak locales/en.json), dołącz je z files i wywołaj lib.locale() raz:
-- fxmanifest.lua
shared_script '@ox_lib/init.lua'
files { 'locales/*.json' }{
"no_money": "You have no money",
"bought": "You bought %s for $%s"
}lib.locale() -- load the language
lib.notify({ description = locale('no_money'), type = 'error' })
print(locale('bought', 'bread', 5))Sprawdzaj dokumenty ox_lib dla bieżącego formatu i dla tego, jak język jest wybierany (convar serwera), ponieważ układ pliku i nazwy opcji zmieniły się między wersjami. Jeśli widzisz ox_lib/init.lua nie znaleziony, napraw to najpierw: ox_lib init.lua not found.
ESX i TranslateCap
Skrypty ESX mają swój własny wzór locale. Pliki locale wypełniają tabelę Locales i framework dostarcza funkcję tłumaczenia:
-- fxmanifest.lua
shared_scripts {
'@es_extended/imports.lua',
'@es_extended/locale.lua',
'locales/*.lua',
'config.lua',
}-- locales/en.lua
Locales['en'] = {
['no_money'] = 'You have no money',
}TriggerEvent('esx:showNotification', TranslateCap('no_money'))Starsze skrypty używają _U('no_money') dla tej samej rzeczy. TranslateCap to bieżąca nazwa w ostatnim ESX Legacy, a język jest wybrany przez Config.Locale lub własne ustawienie frameworku. Jak w ox_lib, sprawdzaj dokumenty wersji ESX, którą uruchamiasz dla dokładnych nazw plików i który z dwóch funkcji to oczekuje.
QBCore ma podobny moduł Lang (locales/en.lua używając Lang:t('key')), który działa w ten sam sposób: tabela na język i funkcja, która rozwiązuje klucze.
Wybieranie języka
Oferuj jedną linię konfigu, blisko szczytu config.lua:
Config.Locale = 'en' -- 'en', 'es', 'fr'...Jeśli Twój skrypt jest mieszanką klienta, serwera i NUI, pamiętaj, że tekst NUI potrzebuje swoich własnych tłumaczeń: wyślij stringi na stronę raz, gdy się otwiera, zamiast pisać angielski w HTML. Zobacz FiveM NUI with React and Vite dla przekazywania danych do strony.
Checklist
| Objaw | Rozwiązanie |
|---|---|
| Tekst angielski na stałe zakodowany w kodzie | Przenieś go do locales/en.lua i wezwij L('key') |
attempt to index a nil value na Locales[...] |
Załaduj pliki locale zanim kod, który je czyta |
| Raw klucz pokazany na ekranie | Klucz brakuje w wybranym języku i w en |
| Użyty zły język | Sprawdzaj Config.Locale i convar locale |
ox_lib locale() zwraca klucz |
Najpierw wezwij lib.locale() i dołącz locales/*.json w files |
| NUI wciąż angielski | Przekaż przetłumaczone stringi do strony |
Szybkie odpowiedzi
Gdzie powinienem umieścić tłumaczenia w skrypcie FiveM?
W folderze locales/ z jednym plikiem na język, takim jak en.lua i es.lua, załadowanym zanim kod, który go używa. Skrypt potem prosi o klucz, nigdy o dosłowny string.
Czy ox_lib ma system locale?
Tak. Czyta pliki locale i daje Ci locale('key') po tym, jak wywołasz lib.locale(). Sprawdzaj dokumenty ox_lib dla bieżącego formatu pliku i ustawienia, które wybiera język.
Jak wybrać język?
Za pomocą wartości Config.Locale w Twoim konfigu, lub za pomocą convara, którą Twój framework lub ox_lib czyta. Wróć do angielskiego, gdy klucz lub język brakuje.
Skrypty bez tego problemu
Mic PhoneSkładany telefon, który rozkłada się w tablet i działa też na prawdziwym telefonie gracza.Zobacz skrypt →
Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →
Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →