После локализаций самая болезненная часть — шрифты. Хотелось бы один общий шрифт для всего UI, без ручных переключений и сюрпризов «квадратиков». Ниже — мой рабочий, быстрый и юридически чистый пайплайн.
1) База: Google Fonts
Ищу гарнитуры на fonts.google.com – лицензии прозрачные, видно покрытие языков и доступность стилей. Локализую на:en, ru, uk, ar, zh, cs, da, nl, fi, fr, de, he, hi, hu, id, it, ja, ko, nb, pl, pt, ro, sk, es, sv, th, tr, vi
Важно: отдельные семейства почти всегда нужны для th, vi, hi (Devanagari), zh, ja, ko.
2) Сборка «комбайна» из нескольких TTF/OTF
Задача — получить один файл со всеми глифами. Из десятка файлов (по скриптам) собираю общий TTF так:
- Открываю все гарнитуры во вкладках FontCreator.
- В каждой вкладке выделяю все глифы и копирую, а потом→ Edit → Paste Special… в «основной» шрифт.
- Включаю опции: Glyphs with the same name и Add non-matching — так недостающие символы добавляются, а существующие не затираются.

- Если нужно точечно заменить (обычно цифры) — обычная вставка в выбранный глиф целевого шрифта.

Результат — один TTF «на всё». В Defold он работает, но выходит тяжёлым. Дальше — оптимизация.
3) Белый список символов из локализаций
Мне нужен ровно тот набор символов, который реально встречается в тексте игры. Его собираю скриптом в Google Apps Script (в файле локализаций):
/**
* Печатает строку: ПРЕФИКС + все уникальные символы из всех листов книги (в одну линию).
*/
function printCharsInlineAllSheets() {
const PREFIX = "-=.1234567890"; // свои «обязательные» символы: HUD, счётчики и т.п.
const INCLUDE_HIDDEN_SHEETS = false; // true — если нужно учитывать скрытые листы
const IGNORED_CHARS = new Set(['\n', '\r', '\t']);
const ss = SpreadsheetApp.getActive();
const sheets = ss.getSheets().filter(sh => INCLUDE_HIDDEN_SHEETS || !sh.isSheetHidden());
const seen = new Set(PREFIX.split(''));
const extra = [];
sheets.forEach(sh => {
const values = sh.getDataRange().getDisplayValues();
values.forEach(row => row.forEach(cell => {
for (const ch of cell) { // итерируем по юникод-символам
if (IGNORED_CHARS.has(ch)) continue;
if (!seen.has(ch)) { seen.add(ch); extra.push(ch); }
}
}));
});
// стабильная сортировка по локали — удобно для воспроизводимости
const collator = new Intl.Collator(undefined, { usage: 'sort', sensitivity: 'variant' });
extra.sort(collator.compare);
const line = PREFIX + extra.join('');
Logger.log(line); // откройте Логи и скопируйте строку
}
Запускаю, копирую строку из логов — это и есть мой whitelist.
4) Подключение в Defold
В .font указываю собранный TTF/OTF, размер, и в поле Characters вставляю строку из скрипта. Получаю аккуратный атлас только с нужными глифами — без лишнего веса.

