Defold Localization example
This is example how to use google sheet table for localization.
Localization support plurals and placeholders.
Example use 2 fonts. One for all languages and one for set of languages without chinese, japanese and korean. You can run game with small font and use liveupdate to download full font.
How to use
-
You will need credentials.json to download from google sheets.
-
Copy localization folder in your project
- Add files to .gitignore
/localization/load_localization/node_modules
/localization/load_localization/package-lock.json
/localization/load_localization/token.json
/localization/load_localization/credentials.json
/localization/load_localization/localization/\*\*
- Install node dependencies.
cd localization/load_localization
npm install
- Config index.js
Paste your spreadsheet id to config_sheet variable.
Use you sheet name and range
async function main(auth) {
console.log(“start”);
const sheets = google.sheets({version: ‘v4’, auth});
// https://docs.google.com/spreadsheets/d/1BUmB7w0f4RVaqfJtRp3ix_3HKL0V5Izu-I9MB9NhCX4
const config_sheet = “1BUmB7w0f4RVaqfJtRp3ix_3HKL0V5Izu-I9MB9NhCX4”
let localization = await download_localization(sheets, “localization!A8:L1000”, auth, config_sheet);
- Download localization
cd ./localization/load_localization
node index.js
You will have 6 files.
- Font forge scripts to exclude symbols from ttf file.
font_forge_all.txt
font_forge_small.txt
- Localization data in json format. You will need localization_compact.json for your game.
localization.json
localization_compact.json
- Symbols list in txt format. To include symbols in defold .font files
symbol_list.txt
symbol_list_small.txt
- Google sheets localization
-
Add localization_compact.json to custom resources
-
Use localization in your game. Look in localization.lua and main.gui_script for example.
--localization.lua
local I18N = require “localization.i18n.init”
local TAG = “[LOCALIZATION]”
-–@class Localization
local M = {
}
function M:init(locale)
self.config_all = localization.load_localization_from_resources(“custom/localization_compact.json”)
self.config_tiny @class {}
for k, v in pairs(M.config_all) do
if k ~= “ko” and k ~= “zh” and k ~= “ja” then
self.config_tiny[k] = v
end
end
I18N.load(self.config_tiny)
I18N.setFallbackLocale(“en”)
self:set_locale(assert(locale))
end
function M:set_locale(locale)
print(TAG, “set locale:” .. locale)
I18N.setLocale(locale)
–you can create events or use messages to trigger components when language is changed
–EVENTS.LANGUAGE_CHANGED:trigger()
end
function M:locale_get()
return I18N.getLocale()
end
function M:translate(key, data)
local translation = I18N.translate(key, data)
if not translation then
print(TAG, “translation not found:” .. key)
return key
end
return translation
end
function M:is_exist(id)
return I18N.translate(id) ~= nil
end
function M:on_font_loaded(font_all)
self.font_all = assert(font_all)
I18N.load(self.config_all)
–add delay to fix some font not changed it metrics
–timer.delay(0.1, false, function ()
– EVENTS.LANGUAGE_CHANGED:trigger()
–end)
end
return M
--main.gui_script
local function on_language_changed(self)
local language_str = LOCALIZATION:translate(“language”)
local date_str = os.date(“%d.%m.%Y”)
local test_locale = LOCALIZATION:translate(“test_locale”, {language = language_str, date = date_str})
gui.set_text(gui.get_node(“title”), test_locale)
gui.set_text(gui.get_node(“load_font_status”), LOCALIZATION.font_all and “font loaded” or “font not loaded”)
gui.set_text(gui.get_node(“msg_zero”), LOCALIZATION:translate(“messages”, {count = 0}))
gui.set_text(gui.get_node(“msg_one”), LOCALIZATION:translate(“messages”, {count = 1}))
gui.set_text(gui.get_node(“msg_two”), LOCALIZATION:translate(“messages”, {count = 2}))
gui.set_text(gui.get_node(“msg_few”), LOCALIZATION:translate(“messages”, {count = 5}))
gui.set_text(gui.get_node(“msg_many”), LOCALIZATION:translate(“messages”, {count = 10}))
gui.set_text(gui.get_node(“msg_other”), LOCALIZATION:translate(“messages”, {count = 20}))
end


