От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

И её даже можно пройти. Сам патч доступен бесплатно для всех желающих в посте вместе с инструкцией по установке.

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

Навигация

Queen`s

Думаю, многие тут не раз сталкивались с ситуацией, когда хочется пройти какую-то игру, но оказывается, что она не издавалась на русском, английском или ещё каком-то знакомом вам языке.

Первое, что приходит в голову, — поискать фанатские патчи, которые зачастую спасают. Но чем нишевее, обскурнее и просто технически сложнее игра, тем стремительнее падают шансы.

После того как я прошёл серию Endless Frontier, захотелось найти ещё что-то подобное (?), и рекомендации нейросетей привели к дилогии Queen's Blade / Queen's Gate, выходившей эксклюзивно на PSP в японском регионе. Забавно, что и тут не обошлось без Super Robot Wars. С франшизой я раньше знаком не был (там есть и аниме, и множество других материалов, в том числе игр, а начиналась она вообще с «визуальных боевых книг»). Но пост не про это.

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

Оказалось, что для Queen's Blade в сети есть патч, который команда добровольцев (минимум человек пять, а то и больше) делала с 2015 по 2022 год. Финальная версия 1.8 позволяет пройти игру полностью и достаточно комфортно. Правда, часть проблем так и не была решена, и японский при прохождении встречается, но это совершенно не мешает.

Логично, что после этого ребята захотели взяться за сиквел, и тут возникли трудности. Судя по их сообщениям, разработчики немного изменили движок, и взламывать его повторно стало слишком проблематично. Так и не решив эту задачу, в конце 2024 года один из участников опубликовал в своём блоге почти полный текстовый перевод сюжета, предметов, навыков и прочих записей в формате .xlsx. Туда же были приложены переведённые ролики из игры, залитые на YouTube. Было прямо объявлено, что работа прекращается, а наработки остаются в открытом доступе.

Перед тем как пойти на крайние меры, я перепробовал несколько инструментов: экранные переводчики, экстракторы текста. Но все они дают не особо... удобный опыт, да и качество машинного перевода оставляет желать лучшего. А тут уже готовый имеется.

И проблема показалась мне интересной. Сам я в ромхакинге почти ничего не понимаю, но, благо, удалось накопать инструменты энтузиастов ещё от первой части, плюс сейчас есть нейросети, которые усиленно тренируют именно под кодинг. С этого и началось увлекательное «приключение». Да и сиквел хотелось пройти.

Какие же стояли задачи?

В теории всё просто: выдернуть текст, перевести (это уже было сделано на ~98%), запихнуть назад. Выдернуть видео, сделать субтитры (тоже почти готово), вернуть на место. Но на практике...

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

Сначала поговорим про текст. Существует удобная программа для извлечения данных из .iso под названием UMDGen. Заполучив нужные архивы shared.bin и map.bin, в которых хранится большинство игровых строк, нейросеть принялась внедрять перевод. Удобно, что в .xlsx-таблицах уже были расставлены указатели, куда необходимо вставлять переведённые реплики. Оставалось лишь написать скрипт для автоматизации процесса и залить всю латиницу.

Первый результат был обнадёживающим: текст действительно появился в игре. Хотя сначала английские строки вообще были пустыми. Как выяснилось, движок игнорирует обычные однобайтовые символы. Поэтому весь перевод пришлось кодировать «широкими» двухбайтовыми знаками, которые игра считала родственниками японских символов.

Тут и начались первые проблемы. Текст получался разреженным, так как используется широкая двухбайтовая кодировка. Позже я узнал, что даже буквы здесь являются текстурой...

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

Но хотя бы начало было положено! И текст благополучно переехал в игру. Тут же вылезли первые баги: часть строк начала рендериться в ячейке для имени, а часть вообще пропадала. В отдельные моменты выводился уже прочитанный фрагмент или вовсе непонятно откуда взявшийся.

Причина оказалась довольно интересной. Внутри файлов находились две таблицы с адресами строк, а первый вариант скрипта обновлял только одну. Игра исправно шла по старым адресам и попадала в середину совершенно другого текста.

После исправления второй таблицы диалоги наконец перестали перемешиваться. Для надёжности появился отдельный тест: после каждой сборки скрипт проверяет тысячи указателей и убеждается, что каждый из них ведёт именно на начало строки, а не куда-то в её середину.

Но и Excel оказался не одной аккуратной таблицей. В обычных сюжетных листах перевод лежал в одном столбце, во Free Talk — в другом. Некоторые строки были продолжением предыдущей реплики и вообще не имели отдельного японского оригинала. Имена, системные сообщения и повторяющиеся фразы тоже хранились по-разному. Поэтому загрузчик постепенно научился понимать все эти исключения, а не просто механически копировал ячейки.

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

В чём проблема сделать текст поуже?..

Нужно понять, как он вообще рисуется. Движок берёт изображение нужного символа, рисует его и сдвигает курсор на стандартное расстояние. Для японских иероглифов одинаковая ширина выглядит нормально, но английская i занимала столько же места, сколько W.

Нужен был так называемый VWF — шрифт с переменной шириной. То есть после i курсор должен сдвигаться совсем немного, по сравнению с m. Для каждого символа должно быть своё расстояние.

Для этого пришлось лезть в MIPS-ассемблер исполняемого файла игры и искать место, где движок прибавляет ширину очередной буквы. Идея патча была такой: на одну инструкцию отправить игру в небольшой дополнительный обработчик, узнать символ, взять его ширину из нашей таблицы и затем вернуться обратно.

Вместо вставки новых данных в середину EBOOT.bin (движок игры) мы нашли пустую область внутри уже существующего файла и разместили код там. Размер EBOOT при этом вообще не изменился.

Правда, позднее выяснилось, что первая «свободная комната» на самом деле принадлежала изменяемым данным игры. Внешне там были нули, но движок мог записывать туда что-то во время работы. Из-за этого сохранения состояния PPSSPP восстанавливали уже повреждённые инструкции, после чего игра пыталась прыгнуть по адресу 0, deadbeef или ещё куда-нибудь. Это приводило к вылетам.

Моё любимое
Моё любимое

Обработчик перенесли в область, которую игра может только читать. После этого новые состояния перестали падать, а ширина букв, пробелов, апострофов, запятых и троеточий ещё несколько раз корректировалась по скриншотам.

EBOOT.bin

Когда с диалогами было покончено, стартовал второй этап: перевод системных надписей, вроде подписей к кнопкам, действий на экране битвы, пунктов в магазине и т. д. Оказывается, они выводятся не так, как сюжетный текст, а лежат напрямую в исполняемом файле игры EBOOT. Просто так его не переведёшь: там жёсткое ограничение по памяти, строка не может занять больше отведённого ей числа байт.

Всего скрипт обрабатывает около 560 системных строк. Сначала мы переводили их строго на месте и использовали свободные нули после строки там, где это было безопасно. Позже для самых заметных надписей нашли более нормальный способ: длинный текст размещается в свободном участке, а игровая инструкция перенаправляется на новый адрес.

Так появились полноценные Train, Free Talk, Equip Items, Use Items, System Settings, Save, Load, Clear и другие подписи. При этом некоторые сокращения оказались вызваны не памятью, а размером самого элемента интерфейса. Например, полное Buy Item уже находилось в игре, но последняя буква просто вылезала за пределы узкой кнопки. Поэтому в магазине в итоге остались естественные Buy, Sell, Forge.

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

Оставалось перевести меню между миссиями и некоторые элементы боевого интерфейса. Поиск японских строк ничего не давал ни в архивах, ни в EBOOT. Всё оказалось проще: никаких строк там не было. Разработчики заранее нарисовали надписи прямо на текстурах интерфейса.

На помощь пришёл PPSSPP, который умеет сохранять используемые игрой текстуры и подменять их пользовательскими. Более того, выяснилось, что разработчики повторно использовали части интерфейса из Queen's Blade. В дампе первой игры нашлась уже переведённая английская текстура, очень похожая на текстуру из Queen's Gate. Немного работы в Фотошопе, и меню было готово.

Но такая замена работает именно через PPSSPP. Для настоящей PSP графические ресурсы пришлось бы полноценно перепаковывать.

Результат
Результат

Проблема в том, что таких текстур в игре достаточно много и каждую надо перерисовывать, поэтому японский всё ещё можно встретить, но это не критично и на прохождение не влияет.

Видео

В целом на этом игра уже стала играбельной без какого-либо дискомфорта. Но оставалось добавить анимационные вставки, которые тоже были переведены в виде одного длинного ролика на YouTube.

Внутри игры находится архив movie.bin с тринадцатью роликами в формате PMF. Причём для архива выделено строго определённое место: сделать его хоть немного больше нельзя.

Сначала из оригинальных PMF получили точную продолжительность каждого фрагмента. Затем длинное видео с субтитрами нарезали на части с теми же таймингами. Здесь даже разница в несколько кадров имела значение: в конце одного ролика мог внезапно появиться первый кадр следующей сцены. Была проблема, что видео на YouTube и реальные ролики из игры имели рассинхрон на несколько сотых секунды. Для movie_000 этот момент пришлось вручную закрыть чёрным кадром, чтобы переход выглядел как нормальная концовка.

Ролики подготовили в разрешении PSP 480×272, звук и видео перекодировали с помощью FFmpeg и официальных инструментов Sony PSMF, после чего собрали новый movie.bin. Фрагменты с 000 по 011 получили субтитры, а 012 остался оригинальным, поскольку в нём нет диалогов.

После упаковки все тринадцать файлов проверялись автоматически: правильный заголовок PMF, выравнивание, наличие видео и звука, совпадение размеров. Затем архив извлекался обратно, и каждый ролик сравнивался с исходным побайтно.

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности

Как был организован процесс

Хотелось бы, конечно, но история в духе «написал один запрос и получил готовый перевод» пока ещё не осуществима.

Разные модели по очереди изучали файлы, писали скрипты, разбирали ассемблер, проверяли работу предыдущих моделей и документировали находки. Для передачи контекста использовался большой WORKPLACE.MD, где записывались адреса, форматы архивов, обнаруженные ошибки, результаты тестов и планы следующих версий.

Но окончательной проверкой приходилось заниматься вручную. Нейросеть могла уверенно заявить, что инструкция закодирована правильно, а PPSSPP через секунду показывал синий экран.

В итоге получился налаженный процесс с воспроизводимой сборкой. GitHub Actions брал чистый японский образ, последовательно вставлял системные тексты и видео, проверял указатели и создавал xdelta.

После этого xdelta тут же применялся к оригинальному образу ещё раз, а результат побайтно сравнивался с собранной версией. Только если файлы полностью совпали, патч публиковался. Сам ISO при этом, разумеется, не распространялся и xdelta содержал только различия.

Были использованы модели: Fable 5 medium, GLM 5.2 max, GPT 5.5 x-high, GPT 5.6 Sol x-high.

Установка

Прежде чем что-то патчить, понадобится PPSSPP и японский оригинальный .iso, а также DeltaPatcher. Отдельно расписывать, где всё это взять и как установить, не буду, задача достаточно тривиальная.

Сам патч можно скачать по ссылке:

После скачивания нужно будет запустить DeltaPatcher, выбрать .iso и сам xdelta и применить патч. Создастся новый .iso с английским переводом.
Также нужно будет включить в PPSSPP замену текстур и положить текстуры по пути: .\memstick\PSP\TEXTURES\ULJS00377. Не переименовывайте файлы.

Удивлён, что Bandai Namco такое издавала, да ещё и на консоли Sony.

От ассемблера до регрессионных тестов: как нейросети помогли мне сделать английский патч для Queen's Gate, японской PSP-игры 15-летней давности
355
85
45
18
5
5
4
2
2
2
2
1
1
1