Перевод игр нейросетью: локализация строк без сломанных тегов
Как перевести тысячи игровых строк так, чтобы не сломались плейсхолдеры, теги и вёрстка интерфейса: формат пакета, проверки, повторы и стоимость.
5 мин · · автоматизация · разработка
Нейросеть для перевода игр снимает большую часть ручной работы, но игровые строки — коварный материал. В реплике Hello, {player}! You found %d coins. модель легко «переведёт» имя переменной или потеряет %d, и игра вылетит или покажет пустое место. Ниже процесс, который переводит строки из JSON, CSV и PO-файлов и автоматически ловит поломки до того, как они попадут в билд.
Почему игровой текст переводить сложнее обычного
У игровых строк есть четыре особенности, которые портят автоматический перевод:
- Плейсхолдеры и теги.
{name},%s,%d,{{count}},<b>…</b>,[color=red],\n. Их нельзя ни переводить, ни терять. - Ограничения длины. Кнопка, рассчитанная на слово
Play, не вместитНачать игру. Русский текст обычно длиннее английского. - Нет контекста. Строка
Run— это «Бежать», «Запустить» или «Забег»? Без подсказки модель выберет наугад. - Единая терминология. Предмет
Iron Swordдолжен называться одинаково в квестах, инвентаре и подсказках.
Все четыре решаются на уровне формата запроса, а не «умным» промптом.
Формат пакета: ID, контекст, лимит
Не отправляйте строки целыми файлами. Разбейте их на пакеты по 30–60 штук и передавайте как JSON-список с идентификатором, исходным текстом и подсказками:
[
{"id": "ui.play", "text": "Play", "context": "кнопка главного меню", "max_len": 12},
{"id": "npc.smith.01", "text": "Need a hand, {player}?", "context": "кузнец, дружелюбный тон"},
{"id": "item.sword", "text": "Iron Sword", "context": "название предмета"}
]Поля context и max_len вы заполняете сами или выгружаете из движка. Даже короткая пометка вроде «кнопка» или «диалог героя» помогает модели выбрать нужное значение слова. В системный промпт добавьте правила и словарь:
Ты переводишь игровые строки с английского на русский.
Правила:
- Верни JSON-список объектов {"id": ..., "text": ...} в том же порядке.
- Плейсхолдеры ({name}, %s, %d, {{x}}), теги (<b>, [color=red]) и \n копируй без изменений.
- Уважай max_len: если не помещается, сократи формулировку.
- Используй словарь терминов, не придумывай другие варианты.
Словарь: Iron Sword = Железный меч; Health = ЗдоровьеСловарь держите коротким и подставляйте в каждый пакет: он одинаково работает для всех строк и обеспечивает единые названия.
Скрипт: перевод пакета с проверкой
Пример на Python с официальным SDK openai (документация по клиенту: Python API). Адрес — https://api.zukko.pro/v1:
import json, re
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_ваш_ключ")
SYSTEM = open("system.txt", encoding="utf-8").read()
TOKEN_RE = re.compile(r"\{\{?\w+\}?\}|%[sd]|%\d*\.?\d*[dsf]|<[^>]+>|\[/?\w+(?:=\w+)?\]|\\n")
def tokens(s: str) -> list[str]:
return sorted(TOKEN_RE.findall(s))
def translate_batch(items: list[dict], model="deepseek-v4.1-flash") -> dict:
resp = client.chat.completions.create(
model=model,
temperature=0.2,Ключевая функция здесь find_bad: она сравнивает набор плейсхолдеров и тегов в оригинале и переводе. Любое расхождение — повод перевести строку заново. Регулярное выражение TOKEN_RE подгоните под формат вашей игры: у каждого движка свой синтаксис разметки.
Дальше цикл: перевели пакет, нашли испорченные строки, отправили только их ещё раз (можно более сильной моделью), после двух попыток остаток складываем в файл для ручной правки. Если запросов много, ориентируйтесь на статью про асинхронную обработку тысяч запросов, а общие приёмы работы с локализационными файлами смотрите в материале про перевод i18n файлов.
Форматы: JSON, CSV, PO
Модель всегда работает с одной и той же внутренней структурой id → текст, а форматы файлов — это адаптеры на входе и выходе.
- JSON. Плоский словарь или вложенный: обойдите дерево и соберите ключи через точку. Записывая результат, восстановите ту же структуру и тот же порядок ключей, чтобы diff в git оставался читаемым.
- CSV. Читайте стандартным
csv-модулем сencoding="utf-8", переводите нужную колонку и записывайте в новую. Не склеивайте строки вручную: запятые и кавычки внутри текста ломают разбор. - PO. Подойдёт библиотека
polib:po = polib.pofile("ru.po"), у записей поляmsgidиmsgstr, сохранение черезpo.save(). Контекст записи (msgctxt) передавайте в полеcontext.
Для файлов из чужих движков сначала выгрузите строки в одну из этих форм утилитой для вашего движка, а после перевода загрузите обратно. Если вы переводите чужую игру или мод, проверьте условия лицензии и правила издателя: это вопрос права, а не техники.
Сколько стоит перевод игры
Расчёт на 18 октября 2026. Допущения: 20 000 строк, пакеты по 50, то есть 400 запросов. На запрос: системный промпт со словарём 1 500 токенов плюс 50 строк по 30 токенов = 3 000 токенов входа; русский перевод пакета с JSON-обвязкой около 2 500 токенов выхода. Итого 400 × 3 000 = 1,2M входа и 400 × 2 500 = 1,0M выхода. Реальные цифры смотрите в usage ответа; русский текст обычно занимает больше токенов, чем английский.
Формула: вход × цена входа + выход × цена выхода.
| Модель | Расчёт | Итого |
|---|---|---|
deepseek-v4.1-flash | 1,2 × $0,013 + 1,0 × $0,038 | $0,054 |
gpt-6.1-sol | 1,2 × $0,27 + 1,0 × $1,32 | $1,64 |
claude-sonnet-5-5 | 1,2 × $0,4 + 1,0 × $2 | $2,48 |
claude-opus-5-5 | 1,2 × $0,8 + 1,0 × $4 | $4,96 |
Добавьте запас на повторы: если примерно каждая десятая строка переводится дважды, это плюс около 10% к итогу. Цены меняются: актуальный список — GET https://api.zukko.pro/v1/models. Практичная схема: дешёвая модель делает основной проход, более сильная переводит только то, что не прошло проверки. Подбирать модель стоит на пробной выборке из 100–200 строк, которую вы прочитаете сами: заранее сказать, кто лучше передаст стиль вашей игры, нельзя.
Ключ для скрипта создайте в кабинете и задайте на него лимит расхода: ошибка в цикле не должна съесть весь баланс.
Частые вопросы
Как не сломать плейсхолдеры при переводе?
Скажите модели в промпте копировать их без изменений и проверяйте результат кодом: сравнивайте наборы плейсхолдеров и тегов в оригинале и переводе. Строки с расхождением отправляйте на повторный перевод.
Как учесть ограничение длины строки?
Передавайте max_len вместе с каждой строкой, а после ответа проверяйте длину. Слишком длинные строки переводите заново с просьбой сократить. Окончательную проверку делайте в самой игре, на реальных элементах интерфейса.
Чем переводить: дорогой моделью или дешёвой?
Начните с дешёвой на пробной выборке и прочитайте результат. Для сюжетных диалогов стоит попробовать модель посильнее, для интерфейса и предметов часто хватает недорогой. Выбор делайте по своей выборке, а не по общим обещаниям.
Можно ли переводить файл целиком одним запросом?
Для небольших файлов можно, но надёжнее пакеты по 30–60 строк с идентификаторами: проще проверять, повторять сбойные части и не терять порядок строк.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Перевод субтитров нейросетью: SRT без сбитых таймкодовГлавный риск при переводе SRT нейросетью — сломанная структура файла. Показываем схему, где таймкоды не попадают к модели, и скрипт на Python с проверкой.
- Редактирование текстов нейросетью: корректура, стиль и сокращениеРазные виды редактуры требуют разных промптов. Показываем формулировки для корректуры, стиля и сокращения, как получать правки с объяснением и не терять авторский голос.
- Нейросеть для написания скриптов: Bash, PowerShell и PythonМодель быстро пишет скрипты для рутины, но запускать их вслепую нельзя. Показываем, как ставить задачу, требовать безопасный режим dry-run и проверять результат до запуска.
- Dify в Docker: установка, первичная настройка и подключение моделейСтавим Dify через Docker Compose, создаём администратора и подключаем модели Claude, GPT и DeepSeek по одному ключу. Отдельно — что делать, если контейнеры не стартуют.