My friend localized the mod by attaching third-party mod without affecting the original mod
However, it seems difficult to translate lua files, and even if lua files are translated, the consequence is that the code becomes difficult to maintain
Therefore I wrote a simple localization module that allows us to import localized texts from any Lua script without overwriting the original mod
This is all of its code without any dependencies:
LuaUserData.MakeFieldAccessible(Descriptors["Barotrauma.GameSettings"], "currentConfig")
local locallanguage = GameSettings.currentConfig.Language.Value.Value
print(("'%s' was detected as the local language"):format(locallanguage))
---@class l10nstr
---@field value string
---@field format fun(self:l10nstr, ...:any):string
---@class l10nmgr
---@overload fun(keys:string|string[]):l10nstr
local l10nmgr = {}
l10nmgr.__index = l10nmgr
local languages = {}
---@type { [string]:table }
local caches = {}
---@param lang table
local addlang = function(lang)
table.insert(languages, lang)
end
---@param lang table
local removelang = function(lang)
for i = #languages, 1, -1 do
if languages[i] == lang then
table.remove(languages, i)
end
end
end
---@param dir string
function l10nmgr.loadlangs(dir)
local files = File.DirSearch(dir)
for _, file in pairs(files) do
local lang = caches[file]
if lang == nil then
if file:endsWith(".lua") then
lang = dofile(file)
if lang[1] ~= locallanguage then
lang = nil
end
end
end
if lang ~= nil then
addlang(lang)
print(("Loaded a lang in '%s'"):format(file))
caches[file] = lang
end
end
end
---@param dir string
function l10nmgr.unloadlangs(dir)
local files = File.DirSearch(dir)
for _, file in pairs(files) do
local lang = caches[file]
if lang ~= nil then
removelang(lang)
print(("Unloaded a lang in '%s'"):format(file))
end
end
end
setmetatable(l10nmgr, {
__call = function(_, ...)
local keys = ...
if type(keys) == "string" then keys = { keys } end
local size = #keys
for _, lang in ipairs(languages) do
local result = nil
for i = 1, size, 1 do
local key = keys[i]
result = result and result[key] or lang[key]
if result then
if i == size then
if type(result) == "string" then
return {
value = result,
format = function(lstr, ...)
local str = lstr.value
for ph, repl in ipairs(table.pack(...)) do
str = str:gsub('{' .. ph .. '}', repl)
end
return str
end
}
else
break
end
elseif type(result) ~= "table" then
break
end
else
break
end
end
end
return {
value = table.concat(keys, '.'),
format = function(lstr)
return lstr.value
end
}
end
})
return l10nmgr
After requiring the module for the first time, the local language will be determined and returns l10nmgr
.
Calling l10nmgr.loadlangs(dir)
with a path to load all localization files from the specified directory, for example:
l10nmgr.loadlangs(DssiShuttleDogfight.Path .. "/Lua/DSSI Shuttle Dogfight/texts")
There are two localization files in the directory: english.lua and schinese.lua
Content in english.lua:
return {
[[English]],
ShuttleDogfight = {
SubmarineRelativePosition = "Located at its main submarine {1} o'clock {2}, distance {3}m",
Faction_A = "Coalition",
Faction_B = "Separatism",
ChatCommand = {
FindShuttles = {
Help = "Find Shuttles",
NonSpectating = "Only spectators can look for submarines!",
Ask = "What shuttles are you looking for?",
AllShuttles = "All",
WithCrewOnBoard = "With crew",
}
}
}
}
It returns a table that the first value is 'English' which is used to define the localization file belongs to English
Content in schinese.lua:
return {
[[Simplified Chinese]],
ShuttleDogfight = {
SubmarineRelativePosition = "ä½äŗå
¶äø»ę½č {1} ē¹éę¹å {2}ļ¼č·ē¦» {3} ē±³",
Faction_A = "čē",
Faction_B = "åč£",
ChatCommand = {
FindShuttles = {
Help = "åÆ»ę¾ę½č",
NonSpectating = "åŖęč§ēč
ęåÆ仄åÆ»ę¾ę½čļ¼",
Ask = "ä½ č¦åÆ»ę¾åŖäŗē©æę¢čļ¼",
AllShuttles = "ęęē",
WithCrewOnBoard = "ęč¹åä¹åē",
}
}
}
}
Same as above, but it will only be used on servers where SChinese is the local language
l10nmgr.loadlangs(dir)
supports importing mutliple localized files from anywhere without conflicting
Calling l10nmgr()
with a string[] or string (A key sequence used to find localized text) to get the corresponding localized text, for example:
print(l10nmgr { "ShuttleDogfight", "ChatCommand", "FindShuttles", "Help" }.value)
-- print "Find Shuttles"
-- if the localized text is not being found by the specified key sequence,
-- it returns an empty object, and print
-- "ShuttleDogfight.ChatCommand.FindShuttles.Help"
print(l10nmgr { "ShuttleDogfight", "SubmarineRelativePosition" }:format(4, 'ā', 300))
-- print "Located at its main submarine 4 o'clock ā, distance 300m"
-- if the localized text is not being found by the specified key sequence,
-- it returns an empty object, and print
-- "ShuttleDogfight.SubmarineRelativePosition"
If you adopt this translation solution, I can submit a pr on github and adapt it to all the text in lua that needs to be translated.