Bản dịch

Ai cũng phải đọc được

càng nhiều ngôn ngữ càng tốt

Bản dịch

Phải có cách dịch toàn bộ trò chơi sang ngôn ngữ khác một cách dễ dàng. Sau vài lần thử nghiệm, tôi đã tạo lớp I18n cho engine3. Hiện tại nó chỉ có thế này.

function I18n:new()
    self.locale = nil
    self.currentLocaleFile = nil
end

--- Convert string to i18n locale
---@param str? string
---@param replacements? table
function I18n:s(str, replacements)
    if str == nil then
        return
    end

    local strOut = tostring(str)

    -- Maybe there is a overwrite
    if self.locale[strOut] ~= nil then
        strOut = self.locale[strOut]
    end

    -- Maybe there are replacements
    if replacements then
        return string.gsub(strOut, "[%%%d]+", replacements)
    end

    return strOut
end

---@param file string
---@param data table
function I18n:createI18nData(file, data)
    self.locale = data
    self.currentLocaleFile = file
end

--- Load the locale in memory
---@param file string Path to the source file .mp only at the moment
function I18n:load(file)
    if type(file) ~= "string" then
        error("Cannot load i18n file, is not a string")
    end

    if string.find(file, ".mp") == nil then
        error("i18n file is is not supported: " .. file)
    end

    local msgPackData = Msgpack:load(file)
    if msgPackData == nil then
        error("File data is nil for file: " .. file)
        return
    end

    self:createI18nData(file, msgPackData)
end

Sau đó trong trò chơi có thể dùng nó ở mọi nơi như một hàm toàn cục theo cách sau

-- load the selected language once
i18n:load(config.localeDefault) -- nl.mp

-- use the default english strings into the selected language
local i18nHoverText = i18n:s("Hello")

language.yaml

en:
    "Hello" : null
nl:
    "Hello" : "Hallo"

Như bạn thấy, ngôn ngữ ’en’ cũng có trong language.yaml nhưng với giá trị null. Điều đó có nghĩa là phải dùng câu tiếng Anh gốc. Nhờ vậy sau này cũng có thể dịch ngay tiếng Anh sang những câu khác.

en:
    "Hello z" : "Hallo y"
nl:
    "Hello z" : "Hallo y"
print(i18n:s("Hello z")) -- Hallo y

Hiện tại như vậy là đủ và có vẻ chạy tốt, nhanh.