How to translate a game’s .po and .mo files (gettext)
The .po is the editable source; the .mo is the compiled catalog the game actually loads — which is why editing the .po alone changes nothing. RuneTranslate reads both, protects %s and {count} placeholders, refits plural forms to your language, and writes a working .mo back.
Если вы открыли папку игры и нашли каталог locale, полный файлов .po и .mo, значит игра локализована через gettext — и RuneTranslate теперь может перевести её целиком, от создания проекта до экспорта играбельной сборки.
В этом руководстве объясняется, что эти два типа файлов представляют собой на самом деле, почему правка того файла, который вы можете прочитать, обычно ничего не меняет в игре, и как переводить их правильно.
.po и .mo — различие, на котором спотыкаются все
Это две формы одного и того же каталога:
- `.po` — Portable Object. Обычный текстовый файл, который открывается в любом редакторе. Каждая запись состоит из
msgid(исходная строка) иmsgstr(её перевод). Именно с этим файлом работают переводчики. - `.mo` — Machine Object. Скомпилированная двоичная версия тех же данных, устроенная так, чтобы игра мгновенно находила строку. Именно этот файл читает запущенная игра.
Последний пункт стоит людям половины дня. Можно перевести каждую строку в .po, сохранить, запустить игру — и не увидеть никаких изменений, потому что игра вообще не открывает .po. Она загружает лежащий рядом .mo, в котором остался старый текст. Обычно одно компилируют в другое утилитой msgfmt из GNU gettext. RuneTranslate записывает оба файла, так что отдельного шага компиляции не требуется.
Как выглядит папка игры с gettext
Каноническая раскладка — каталог locale, разбитый по кодам языков:
MyGame/game.exeMyGame/locale/en/LC_MESSAGES/mygame.moMyGame/locale/fr/LC_MESSAGES/mygame.moMyGame/locale/de/LC_MESSAGES/mygame.mo
Папка LC_MESSAGES — часть соглашения, а не ошибка, а mygame — это текстовый домен, имя, которое игра запрашивает при загрузке строк. Многие игры используют более плоскую форму вроде lang/fr.po, и это тоже работает.
Какие игры используют gettext?
Gettext возник в мире Unix и стал стандартным способом локализации программ на C, Python и всего, что построено на GTK. В играх это означает:
- Игры на Python и pygame
- Solarus, SDL и другие движки на C/C++
- Игры, локализованные через Poedit, Weblate или Crowdin — все они изначально понимают PO
- Некоторые проекты на Godot, где PO поддерживается как источник перевода
В западных инди-играх это встречается куда чаще, чем в японских: японские движки вроде Kirikiri и RPG Maker хранят текст в собственных форматах.
Перевод gettext-игры в RuneTranslate
- Укажите RuneTranslate папку игры. Ту, внутри которой есть
locale/,lang/илиi18n/. Определение читает фактические байты, а не полагается на расширение, поэтому.mo, который на деле является 3D-сценой, будет пропущен, а не превратится в сломанный проект. - Проверьте сводку. До создания проекта видно число каталогов, соотношение скомпилированных
.moи исходных.po, какие языки уже есть в игре и общее число строк. - Выберите язык и сервис. Бесплатный Google или DeepL либо собственный ключ DeepL, OpenAI, Claude или DeepSeek — см. сравнение сервисов.
- Проверьте и экспортируйте. Вы получите полную копию игры с уже применённым переводом.
Две вещи, которые незаметно ломают перевод gettext
Плейсхолдеры. msgid — это строка формата, а не готовый текст. В Hello, %s! имя игрока подставляется во время выполнения. Машинные переводчики склонны удалять %s, разделять его пробелами или — в именованной форме Python %(player)s — переводить слово внутри. Последствия не косметические: пропавший %s сдвигает все последующие аргументы, и большинство движков просто падает. RuneTranslate маскирует каждый найденный плейсхолдер (%s, %d, %(player)s, {count}, {0}) до отправки текста сервису и восстанавливает после.
Формы множественного числа. В английском их две («1 coin» / «5 coins»), в японском и турецком — одна, в русском и польском — три. Каталог объявляет их количество в заголовке, и если это число не совпадает с языком, gettext выходит за конец списка и молча возвращает непереведённый оригинал. RuneTranslate подгоняет формы под ваш целевой язык и переписывает заголовок.
Почему экспорт записывает каталог дважды
Экспорт создаёт и корректный новый язык — locale/<ваш язык>/LC_MESSAGES/ — и обновлённую копию каталога, который игра загружала и раньше.
Именно второе заставляет перевод действительно появиться. Игра решает, какую локаль загрузить, способами, о которых по папке ничего не узнать: она может читать язык системы, файл настроек, флаг лаунчера или просто иметь язык, зашитый в код. Добавить русский каталог в игру, которая запрашивает только английский, — значит смотреть на, казалось бы, неизменившуюся сборку. Перезапись того каталога, который она действительно загружает, снимает эту неопределённость. И то и другое происходит только в экспортированной копии — исходная папка игры не изменяется.
Непереведённые строки сохраняют перевод, который игра уже содержала, так что незавершённый проект никогда не обнуляет локализацию самого разработчика.
Чего это сделать не может
Перевести можно только текст, который уже есть в каталоге. Если разработчик записал строку прямо в коде, не пропустив её через gettext, её нет ни в .po, ни в .mo, и никакой PO-инструмент её там не найдёт. Это ограничение формата, а не программы.
RuneTranslate также считает msgid исходным текстом — так предписывает сам gettext. В некоторых проектах msgid на английском, а настоящий исходный язык лежит в msgstr; такие будут переведены с английского.
Наконец, если игра работает на движке с прямой поддержкой — Godot, Unity, Ren’Py — её обрабатывает этот движок, чтобы остальной текст игры тоже был доступен, а не только каталоги.
Прежде чем делиться
Запустите экспортированную сборку и прочитайте несколько экранов. Меню и кнопки — самая быстрая проверка, потому что там находится большая часть текста каталога. Если что-то не так — игра не определяется, экспорт не запускается или текст остался на исходном языке — сообщите через меню «Помощь» в приложении или в Discord. Скачайте RuneTranslate и откройте свой первый каталог.
Готовы попробовать RuneTranslate?
Бесплатный тариф открывает все движки и всех провайдеров перевода. Supporter ($3/mo) открывает полную скорость.
Скачать для Windows