Переведённая игра не запускается? Найдите строку
Переведённая игра открывается и тут же закрывается или вечно висит на экране загрузки. Одна из переведённых строк никогда не была текстом: идентификатор, путь, флаг, который игра сравнивает. Сначала убедитесь, что дело именно в переводе, а затем найдите строку делением пополам: около тринадцати экспортов сводят пять тысяч строк к одной.
Окно открывается. Окно закрывается. Вчера эта игра работала, потом вы потратили вечер на перевод, и теперь она мертва.
Где-то среди этих строк есть одна, которая никогда не была текстом: имя сцены, путь к файлу, флаг, который игра сравнивает. Движок наткнулся на неё и сдался, не нарисовав ничего.
Вы не станете читать пять тысяч строк, чтобы её найти. Вы зададите один вопрос «да или нет» примерно тринадцать раз.
Короткий ответ. Сначала докажите, что дело вообще в переводе, а затем делите пополам: переведите половину подозреваемых, экспортируйте, запустите. Та половина, что ломается, содержит вашу строку. Повторяйте с ней, пока не останется одна.
Прежде чем искать: дело вообще в переводе?
- Запустите оригинальную игру. Не свой экспорт, а нетронутую копию. Если и она не работает, дело в вашем компьютере, в папке или в самой игре.
- Переведите одну короткую безобидную строку, экспортируйте, запустите. Подойдёт слово из меню, которое видно на экране.
- Только после этого начинайте искать строку.
В шаге 2 намеренно сказано одну строку, а не ни одной. Несколько адаптеров прерываются, когда писать нечего, поэтому пустой экспорт проверяет копирование файлов, а не доставку, и может пройти успешно, пока настоящая доставка ломается.
Если сборка с одной строкой тоже не запускается, ни одна отдельная строка не виновата и деление пополам ничего не найдёт. Экспортируйте заново в совершенно новую пустую папку, убедитесь, что запускаете экспортированную копию, а не оригинал, и прочитайте предупреждения экспорта. Если и тогда не работает, сообщите об этом как о проблеме доставки.
Проверка стоит двух запусков и одного экспорта: минуты на небольшом проекте RPG Maker, дольше на крупной игре Unity. Зато она экономит вечер поисков строки, которой там нет.
Два похожих случая, которые сюда не относятся. Квадратики, вопросительные знаки или испорченная латиница при работающей игре — это проблема шрифта или кодировки. Вылет сразу после установки плагина или оверлея — это инструмент, а не ваши строки.
Найдите строку делением пополам
В большинстве проектов много файлов, и список файлов проще всего разрезать надвое.
- Сбросить все переводы на панели инструментов.
- Откройте Выбрать файлы для перевода — окно говорит само за себя: «Выберите, какие файлы переводить. Неотмеченные файлы останутся нетронутыми». Снимите отметку с половины файлов и переведите остальные.
- Экспортируйте в новую пустую папку и запустите игру.
- Если запускается, ваша строка в той половине, которую вы не трогали; если нет — в той, которую только что перевели. В любом случае список уменьшился вдвое, а про вторую половину вы забываете.
- Снова Сбросить все переводы, поделите оставшийся список пополам, экспортируйте, запустите.
- Повторяйте, пока не останется один файл, а затем делите внутри этого файла, пока не останется одна строка.
Деление по файлам грубее деления по строкам, поэтому число раундов зависит от числа файлов: сорок файлов — это около шести раундов до нужного файла, а потом вы начинаете заново внутри него.
У проектов из одного файла — скрипт NScripter, игра Kirikiri или Wolf с единственным сценарием — нет списка файлов, который можно разрезать. Вместо этого протяните рамку по строкам: флажки и панель массовых действий появятся сами, а дальше всё сделает Перевести выбранные заново. Для более широкого прохода сначала сузьте строки фильтром и поиском, а потом используйте Выбрать всё видимое. С этим осторожнее: берётся ровно то, что показывает фильтр, поэтому забытый фильтр незаметно испортит все следующие раунды. Запишите, какой фильтр вы применили.
Сломанная партия из ста строк, разыгранная до конца:
- Раунд 1 — 100 под подозрением, переводим первые 50: запускается, значит она в других 50.
- Раунд 2 — 50 под подозрением, переводим первые 25: ломается, значит она в этих 25.
- Раунд 3 — 25 под подозрением, переводим первые 13: запускается, значит она в других 12.
- Раунд 4 — 12 под подозрением, переводим первые 6: ломается, значит она в этих 6.
- Раунд 5 — 6 под подозрением, переводим первые 3: ломается, значит она в этих 3.
- Раунд 6 — 3 под подозрением, переводим первые 2: запускается, осталась одна строка.
Семь экспортов — худший случай для ста строк, около тринадцати — худший для пяти тысяч.
Сколько стоит один раунд
Один экспорт, один запуск и столько времени, сколько игре нужно, чтобы дойти до первой строки диалога. Две-три минуты на небольшом проекте RPG Maker. На крупной игре Unity, где экспорт копирует её целиком, а заставка не торопится, ближе к десяти.
То есть тринадцать раундов — это почти весь вечер. И это по-прежнему дешёвый вариант, потому что альтернатива — прочитать пять тысяч строк и угадать правильно.
Вручную ошибаются в двух вещах. Экспортируйте в новую пустую папку каждый раунд, потому что некоторые движки подключают патчи накопительно, и раунд 3, легший поверх раундов 1 и 2, проверяет все три сразу. Сброс значит сброс: используйте Сбросить все переводы, а не ручную правку, потому что он возвращает текст, зафиксированный при создании проекта, даже если вы с тех пор перезаписали исходную папку.
Если после возврата строки всё равно не работает
Значит, их было больше одной — обычный итог первого прогона «перевести всё» на движке, чувствительном к разбору. Оставьте найденную строку непереведённой и прогоните цикл заново по всему, что ещё переведено. Второй виновник очень часто относится к тому же типу строк, что и первый, и лежит в том же файле.
В следующий раз переводите партиями
Партии не экономят экспорты; это экспорты, которые вы всё равно собирались делать, и каждая поломка приходит уже локализованной. Сломалось в последней партии, значит деление пополам начинается со ста строк, а не с пяти тысяч. Начните со 100 и переходите к 500 или к целому файлу, когда несколько партий пройдут чисто.
Какие движки ломаются, если перевести не ту строку?
Про движки говорят «строгий» и «терпимый». На самом деле всё решает то, куда попадает ваш перевод.
Одни движки читают его как данные: отдельный файл и перехватчик во время выполнения в Ren'Py, экранированный JSON в RPG Maker, значение .locres, у которого хеши ключей остаются нетронутыми, в Unreal. Структура игры вашего текста не видит, поэтому неверная строка стоит вам неверной строки. Другие вставляют его в файл, который игра разбирает как скрипт, разметку или поток байтов, и ваша фраза становится частью структуры этого файла. Тогда двоеточия, скобки, одного лишнего байта или строки, которая была ещё и ключом поиска, достаточно, чтобы остановить игру.
Вот и всё правило. Найдите свой движок, прочитайте его строку и идите дальше.
- RPG Maker MV/MZ — ничего структурного: экранированные JSON и CSV, и предлагается лишь фиксированный набор команд событий. Единственный реальный риск — плагин, сравнивающий имя говорящего точно; экспорт переписывает и ключ этого плагина.
- Ren'Py — почти ничего. Исходный код никогда не переписывается, поэтому строка, которая заодно служит логическим ключом, в безопасности.
- Unreal Engine — мы не видели ни одного сбоя на уровне строки: строки
.locresпо устройству являются отображаемым текстом. Риск здесь — пропавший текст, а не мёртвая сборка. - Unity — тяжело и незаметно: имена сцен, ключи переменных и колбэки хранятся так же, как диалог. Ждите бесконечной загрузки, мёртвой кнопки или чёрного экрана.
- Godot — тяжело. Пути узлов, StringName и ссылки
res://— это адрес, по которому движок ищет; обратная запись их отклоняет. - Wolf RPG — самый хрупкий формат здесь. Смещение в один байт рассинхронизирует весь поток, и процесс завершается ещё до появления окна.
- Kirikiri / KAG — тяжело: скобки — это синтаксис, а имена хранилищ — имена файлов. Переведённое имя тега, преобразованная скобка или переведённое имя графического файла — каждое из этого останавливает игру намертво.
- Electron VN — тяжело. Шаблонный заполнитель, записанный в живой JavaScript внутри
app.asar, — это синтаксическая ошибка, а не плохой перевод. - TyranoBuilder / TyranoScript — то же семейство, что Kirikiri: теги KAG — это разметка, поэтому переведённый тег — это синтаксис. Встроенные ссылки на персонажей никогда не переписываются.
- NScripter — тяжело и по-своему:
?,%и$— это префиксы переменных, поэтому один случайный символ — синтаксическая ошибка. - YU-RIS — тяжело, потому что многое из того, что формат называет строкой, на деле операнд. Их разделение снизило одну игру с 40 678 активных строк до 8 914 без потери диалогов.
У других движков есть свои страницы, у каждой своё руководство, в разделе движки.
Три строки, которые убили игру
Каждое правило исключения в RuneTranslate оплачено игрой, которая перестала запускаться. Эти три исправлены. В каждом случае сломанная строка выглядела совершенно разумно, а экспорт завершился зелёным.
Godot: игра придумывает персонажа. Строка гласила Warning: the door is locked. Безупречный английский. Dialogic экранирует каждое двоеточие в сохранённом тексте, потому что неэкранированное двоеточие — это как раз способ отделить имя говорящего. Записанная обратно как есть, фраза была разобрана заново как персонаж по имени Warning, говорящий the door is locked, и дополнение его послушно создало.
Kirikiri: игра ищет файл с именем `End`. Тег кнопки нёс имя графического файла и метку перехода, а маскировка не могла охватить тег со своими собственными скобками, поэтому оба оказались открыты и переведены. Теперь сканер понимает скобки: он закрывается на парной скобке, так что вложенное выражение остаётся внутри тега, а обычный тег заканчивается на своей первой ].
RPG Maker: портрет тихо исчезает. Плагин портретов выбирает изображение персонажа, сравнивая имя говорящего буква за буквой с таблицей в собственной конфигурации. Перевести имя правильно; не трогать эту конфигурацию тоже правильно, ведь она полна ключей ресурсов. Вместе они сломали равенство, и портреты персонажа исчезли, не оставив записи в журнале.
Все три экспорта отчитались об успехе. Чистый экспорт не является доказательством работающей игры ни на одном движке. Единственное доказательство — запустить её.
Когда дело вовсе не в ваших строках
Деление пополам этого не найдёт, потому что ни одна половина не запускается: проблема в том, куда попал экспорт. Игры Wolf RPG читают свой архив .wolf раньше любого отдельного файла рядом, так что одна показывала заставку, пока переведённые данные лежали на диске непрочитанными. Addressables в Unity отвергает пакет, байты которого больше не совпадают с контрольной суммой, и выдаёт чёрный экран без единой записи в логах. Упакованные игры RPG Maker игнорируют файлы данных рядом с исполняемым файлом. Все три случая уже обработаны — поэтому сбой доставки стоит не выслеживать, а сообщить о нём.
Есть ли признак, по которому видно, какие строки — диалог?
Нет. И относитесь с подозрением к тем, кто утверждает обратное.
Один пользователь как-то рассказал нам, что нашёл игру на Godot, где каждая строка диалога была обёрнута в ||; он перевёл только их, и игра заработала. Для той игры — действительно полезно. Но это привычка одного разработчика, а не соглашение Godot, и следующая игра сделает иначе.
Контрпример — из YU-RIS. В одной игре канал обратных кавычек содержал всю таблицу строк интерфейса, 687 из её 692 строк были отображаемым текстом — и всё же обратная кавычка там ничего не значит. Все три вида кавычек компилируются в одно и то же, поэтому правило, построенное на разделителе, помечает настоящую прозу. Где лежало значение — говорило всё; как оно было закавычено — не говорило ничего.
Полагайтесь на положение и форму и позвольте игре научить вас обоим. Запустите её, прочитайте первую строку диалога на экране, а затем найдите именно эту строку в редакторе: её файл, её группа и её соседи — вот как выглядит диалог в этой игре. Всё, что лежит в другом месте, — кандидат на то, чтобы диалогом не быть.
Что приложение помечает и чего оно знать не может
RuneTranslate помечает строки, которые считает кодом, путями к ресурсам или идентификаторами, как исключённые. Они остаются видимыми, а не скрываются: подсвечены оранжевым за переключателем показать исключённые, чтобы вы видели принятое решение и могли принудительно перевести любую строку через всё равно перевести. Можно также добавить свои шаблоны.
Выберите исключённые строки и запустите прогон — он остановится и спросит: «12 из 340 выбранных вами строк исключены — помечены вашими фильтрами или самим RuneTranslate как код, пути к ресурсам или идентификаторы. Их перевод может сломать игру. Пропуск оставит их исключёнными. Перевод включит их и в будущие прогоны».
Пройти дальше — нормально. Просто запомните, что вы это сделали, потому что это первое место, куда стоит заглянуть, когда экспорт перестаёт запускаться.
Честное ограничение: исключение — это догадка о строке, поэтому оно не может знать, что одно предложение в вашей игре заодно служит ключом поиска в каком-то плагине, который эта игра поставляет. Игра, исходный язык которой уже английский, защищена ещё меньше, потому что самые сильные фильтры спрашивают, содержит ли строка текст на исходном языке.
Частые вопросы
Почему моя игра не запускается после перевода?
Почти всегда потому, что одна переведённая строка была идентификатором, путём, именем сцены или флагом, который игра сравнивает как точную строку. Её изменение ломает разбор или поиск.
Как найти, какая переведённая строка сломала игру?
Делите пополам. Сбросьте все переводы, переведите половину, экспортируйте в пустую папку, запустите. Та половина, что ломается, содержит строку; поделите её пополам и повторите. Шесть-семь раундов из ста строк, около тринадцати из пяти тысяч.
Переведённая игра закрывается сразу — что это значит?
Фатальная ошибка при запуске. На Kirikiri, визуальных новеллах Electron и NScripter обычно синтаксическая ошибка: переведённая или потерянная скобка, кавычка либо заполнитель. На Wolf RPG и YU-RIS — рассинхронизированный поток.
Почему переведённая игра открывается чёрным экраном?
Обычно это загрузка, упавшая внутри кода, который проглотил исключение; на Unity — пакет, контрольная сумма которого больше не совпадает с записью каталога. Попробуйте сборку с одной безобидной переведённой строкой: если и она чёрная, виновата доставка, а не какая-то строка.
Переведённая игра застряла на экране загрузки — это перевод?
Скорее всего да, если это Unity. Бесконечная загрузка — классический симптом переведённого имени сцены или ключа переменной: игра ждёт имя, которое больше не совпадает, и никакой ошибки не возникает.
Какие строки нельзя переводить никогда?
Всё, что игра разрешает по точному совпадению строки: пути, имена сцен и узлов, имена переменных и событий, коды языков, всё, что похоже на snake_case или res://. Если вы не можете представить игрока, читающего это с экрана, оставьте как есть.
Игра работает, но текст — квадратики или вопросительные знаки. Это та же проблема?
Нет. Одинаковые квадратики означают, что в шрифте нет глифа для этих символов; настоящий вопросительный знак означает, что они потерялись при записи файла. И то и другое — проблемы шрифта или кодировки с другим решением.
Куда двигаться дальше
Начинаете перевод, а не чините его? Как сделать патч перевода описывает всю работу целиком.
Когда найдёте свою строку: оставьте её на исходном языке, переведите всё вокруг, экспортируйте в новую пустую папку и запустите. Один непереведённый идентификатор не стоит игроку ничего.
Готовы попробовать RuneTranslate?
Бесплатный тариф открывает все движки и всех провайдеров перевода. Supporter ($3/mo) открывает полную скорость.
Скачать для Windows
