По следам якудза: как наработки с перевода Yakuza 5 разбились о Dead Souls, и почему я перевожу её как «Мертвецы»

Всем привет. Какое-то время назад я делился здесь своим опытом перевода Yakuza 5. Наивно полагая, что после ковыряния её внутренностей меня уже ничем не удивить, я решил в одиночку взяться за проект, релиз которого в наши дни ждут от силы полтора землекопа. Речь о том самом зомби-спиноффе — Yakuza: Dead Souls.
Сразу отвечу на вопрос, который наверняка возникнет: почему в моём переводе игра будет называться «Мертвецы», а не транслитом Dead Souls или дословным «Мёртвые души»? В японском оригинале игра носит лаконичный подзаголовок Of the End, но западные локализаторы, как обычно, всё переиграли. Я решил добавить немного осознанной отсебятины. Слово «Мертвецы» — ёмкое, универсальное и отлично ложится в контекст игры, будь то реплики персонажей или названия уровней сложности.
Залетая в файлы, я был уверен, что багаж знаний от пятой части позволит мне щёлкать текст как орешки. Движок-то один! Но архитектура PS3 быстро дала понять, что всё вроде бы похоже, но работает совершенно иначе.
Этот пост — хроника попыток договориться с капризным кодом, памятка для самого себя и предупреждение для тех безумцев, кто вдруг тоже решит залезть в ромхакинг старых игр RGG Studio.
Когда видишь главный исполняемый файл игры под названием EBOOT.BIN, сразу закрадывается подозрение, что с ним придётся... скажем так, знатно повозиться. И подозрения полностью оправдались.
В пятой Якудзе я уже воевал с похожей бедой — файлом string_tbl.bin. Там тоже приходилось дописывать переведённый текст в конец файла и пересчитывать указатели, но там хотя бы была какая-то логичная структура. Здесь же — кромешный мрак.
Чёткой структуры в EBOOT нет, поэтому мой скрипт просто вслепую выдёргивает из него весь английский текст наугад, рискуя зацепить системные команды. Наверное, настоящие хакеры-профи смогли бы расковырять его красиво и качественно, но я делаю как могу — лишь бы работало. Плюс ко всему, каждый раз нужна сторонняя утилита (TrueAncestor), чтобы переподписать изменённый бинарник обратно под PS3. Выцепил пару строк, перевёл, переподписал, закинул в эмулятор и молишься, чтобы не словить чёрный экран. И так по кругу.
Пока мне удалось частично победить главное меню и базовый интерфейс. А вот названия глав, имена персонажей во всплывающих окнах и куча мелкого текста всё ещё сопротивляются. Возможно, проблема кроется в том, что я перевожу всё исключительно КАПСОМ (почему — расскажу чуть позже), и из-за этого где-то слетают лимиты или проверки движка.
Честно говоря, я вообще не уверен, что смогу перевести этот файл до конца на все 100%. Но пока то, что сделано — работает, и на том спасибо. Буду дожимать остальное точечно на живых тестах.
Если с извлечением текста я худо-бедно разобрался, то дальше в дело вступили шрифты. Текстуру русского шрифта я взял из наработок по Yakuza 5 — игра на том же движке, так что база подошла, но со своими нюансами.
Из-за различий в ширине символов оригинальный английский текст местами выглядит забавно: кавычки превратились в странные значки, а узкая английская буква «i» норовит уехать влево и налипнуть на соседнюю букву. Вручную перерисовывать атлас шрифта и часами выверять координаты каждого глифа прямо сейчас не вижу смысла — сначала нужно победить сам текст и логику файлов, а косметику навести всегда успеется.
Почему весь перевод кричит КАПСОМ
Двухбайтовая кодировка в этой версии Dead Souls не завелась от слова совсем. Пришлось собирать всё на 1-байтовой системе (CP1252 через подмену символов). Но и тут движок подкинул свинью: если писать строчными русскими буквами, их байты конфликтуют с японской таблицей Shift-JIS. Игра думает, что это начало японского символа, и радостно выдаёт на экран иероглифы.
Решение оказалось простым и бескомпромиссным:
весь русский перевод пишется исключительно заглавными буквами (КАПСОМ). Строчные буквы — для слабаков! Игра про суровых мужиков и зомби должна говорить с тобой громко. Зато буква «Ё» встала как влитая и отлично рендерится в игре, хотя в HEX-редакторе отображалась подозрительным символом параграфа.
Ловушка эмулятора: куда исчезают изменения?
Отдельная техническая подлянка, на которую я напоролся при тестах шрифта и текста — виртуальный кэш RPCS3.
Я меняю файлы, закидываю свежий архив в папку игры (PS3_GAME/USRDIR/data/), запускаю эмулятор... а в игре ничего не поменялось. Всё на английском.
Оказалось, Yakuza: Dead Souls при первом запуске устанавливает свои служебные данные (включая шрифты и системные архивы) на виртуальный жесткий диск PS3 в папку dev_hdd0/game/BLES01399/USRDIR/data/. И эмулятор упрямо читает всё из этого кэша, полностью игнорируя папку с игрой!
Чтобы игра наконец увидела обновлённые файлы, нужно либо закидывать их напрямую в эту скрытую папку dev_hdd0, либо каждый раз сносить установленные данные в эмуляторе (Game Data). Запомните это, если когда-нибудь полезете модифицировать PS3-версии.
Когда я закончил воевать с меню, настало время самого главного — сюжетных роликов. И тут движок Yakuza снова раскрылся во всей красе.
Архивная матрёшка и структура катсцен
Если в обычных играх субтитры лежат в понятных текстовых файлах, то в Dead Souls они упакованы в матрёшку из архивов.Каждая сцена лежит по пути data/auth/<название_сцены>/<название_сцены>.par. Но внутри этого .par лежит... ещё один вложенный архив *_cmn.par, и только внутри него спрятан бинарник Auth.bin.
Сам Auth.bin — это не текст, а фиксированная таблица слотов ровно по 272 байта на каждую реплику:
- Первые 16 байт — заголовок (кадр появления и исчезновения фразы в Big-Endian формате).
- Оставшиеся 256 байт — сам текст, а всё пустое место до конца слота забито нулями.
- Перенос строки здесь кодируется не одиночным байтом 0x0A, а строго двумя байтами 5C 6E (\n).
Главная ловушка: почему игра висела намертво?
Я распарсил текст, написал перевод, собрал архив популярной утилитой ParTool, закинул в игру... и словил бесконечный чёрный экран «Now Loading».
Оказалось, обычный ParTool по умолчанию собирает архивы для ПК-версий (в формате Little-Endian). А консоль PS3 работает на процессоре Cell с архитектурой Big-Endian и ждёт в первых четырёх байтах заголовка строгую сигнатуру PARC (50 41 52 43). Не найдя её, игра просто зависает навечно.
Спасением стал скрытый флаг утилиты:
ParTool.exe create "." "a010.par" -c 0 --alternative-mode
Флаг --alternative-mode как раз принудительно заставляет утилиту генерировать правильный заголовок PARC под PS3, а ключ -c 0 отключает сжатие. Без сжатия 100+ архивов катсцен собираются за 15 секунд вместо полутора часов, а консоль не вылетает из-за переполнения памяти.
Плюс собирать их нужно строго «снизу вверх»: сначала запаковывать внутренний архив *_cmn.par, а затем внешний контейнер сцены.
Приют «Асагао», логотипы и «Мертвецы»
Первая же сцена игры встречает нас мирной жизнью Кирю на Окинаве. И тут в глаза сразу бросается разброд в головах официальных западных переводчиков:
- В Yakuza 3, 4 и Dead Souls они обозвали приют Кирю как Sunshine Orphanage.
- В Yakuza 5 те же локализаторы внезапно переименовали его в Morning Glory.
Я не стал плодить эту путаницу и вернул всему каноничное японское имя — Приют «Асагао» (тем более на деревянной табличке перед входом буквально вырезано иероглифами あさがお).
С иероглифами глав перед катсценами ситуация интересная: я сначала думал перерисовать их на русский манер, но потом прикинул объём работы и понял, что оно того, пожалуй, не стоит — проще и стильнее оставить оригинальную японскую тушь по центру и дать перевод снизу (тем более сама SEGA в английской версии сделала именно так).
А вот над титульными заставками и логотипами Dead Souls я ещё думаю. Возможно, попробую перерисовать их в более чётком качестве и вставить туда название «Мертвецы». Собственно, почему я и остановился на этом слове: оно хотя бы по смыслу близко к Dead Souls, в отличие от оригинального японского Of the End, и отлично встанет в дизайн заставок.
Раз уж пришлось повозиться с эмулятором, запишу сюда то, что реально помогло стабилизировать картинку и убрать просадки:
1. Разрешение и белый засвет
- Разрешение: Внутри игры лучше оставить дефолтные 100% (1280x720), чтобы не ловить баги масштабирования и не перегружать видеокарту.
- Масштабирование: В пункте Output Scaling можно поставить FidelityFX Super Resolution 1 с резкостью RCAS: 60%, чтобы картинка на мониторе была чётче.
- Белый засвет по краям: Главным виновником оказался параметр Write Color Buffers — его нужно выключить (снять галку). Без него засвет по краям сразу пропадает, а эмулятору становится легче.
- Strict Rendering Mode — выключен, иначе сильно проседает производительность.
2. Настройки для более стабильного фреймрейта
Вкладка GPU:
- ZCULL Accuracy — ставим на Approximate (Fast).
- Anti-Aliasing (MSAA) — Disabled.
- Multithreaded RSX и Asynchronous Texture Streaming — включены.
- Vsync — Disabled (или в панели управления NVIDIA выставить режим Fast Sync).
Вкладка Advanced:
- Enable SPU loop detection — включить (слева в блоке Core).
- RSX FIFO Accuracy — ставим на Fast.
- Driver Wake-Up Delay — выставить на 200 μs.
Game Patches (в верхнем меню Manage ➔ Game Patches):
- Включить патч Disable SPU MLAA - Multiple titles (02).
Вкладка Debug (включается в CurrentSettings.ini строкой showDebugTab=true):
- Включить Force CPU blit emulation.
Пока на этом всё. На данный момент удалось полностью победить пайплайн катсцен (разобрался со структурой, текст встал на место, без сжатия собирается быстро и без вылетов) и частично оживить главное меню с интерфейсом.
Смогу ли я в итоге добить эту игру до 100% финала — честно, не знаю, время покажет, ковырять там ещё очень много. Просто решил выложить то, с чем уже разобрался, чтобы не забыть самому и оставить готовую техническую памятку тем, кто вдруг тоже захочет полезть в дебри движка Yakuza на PS3.