Когда движок игры тебя ненавидит: Тройной УСПЕХ, мясо и сломанные сейвы PS3
Обычно слово «УСПЕХ» пишется один раз. Но если вы взялись переводить игру на движке SEGA 2007 года, будьте готовы к тому, что он наложит текстуру три раза подряд. Это только верхушка айсберга. За красивым словом «УСПЕХ» скрываются сдвинутые на пару байт таблицы индексов, из-за которых пистолеты превращаются в мясо, а обычные миссии — в битву с финальным боссом. Хочу рассказать, как я боролся с этим цифровым хаосом.
Кстати, «Тройной УСПЕХ» здесь — это не просто метафора. Это буквально то, что я увидел на экране, когда запустил игру после первой правки текстур. На экране отрисовались три наложенные друг на друга надписи. Но, как оказалось чуть позже, это слово идеально описывает всю мою ситуацию в целом. Ведь сломалось у меня тогда сразу три вещи: интерфейс, база предметов и логика миссий. Так что слово «УСПЕХ» можно смело брать в кавычки.
Давайте по порядку.
Проблема №1. Тройной УСПЕХ: как сломать интерфейс и не заметить
В игре есть графические плашки (например, когда ты выполняешь задачу или убиваешь босса). В оригинале слово SUCCESS было собрано из четырёх отдельных спрайтов (букв), которые лежали в файле интерфейса .csb.
Я перевёл его в УСПЕХ, закинул новую текстуру... и игра отрендерила её ТРИ РАЗА ПОДРЯД. На экране красовалось «УСПЕХ УСПЕХ УСПЕХ».
Почему? Потому что старые слоты-дубликаты никуда не делись. Игра просто наложила новые буквы поверх старых структур, привязанных к разным координатам.
Решение: Пришлось вручную ковырять координаты в .csb файле. Я оставил только один активный слот по центру, а остальные буквы отправил «гулять» за экран, прописав им координату X=5000.
С масштабом, правда, до сих пор беда — фон масштабируется отдельно от текста, поэтому сейчас красиво смотрится только мелкий шрифт. Но хоть без тройных галлюцинаций. (Спасибо тестеру за идею со смайлами вместо текста, но я решил, что текст надёжнее, уж больно таких плашек в игре много).
Проблема №2. Тарелка мяса и Расецу Амон: как дедупликация сломала базы данных
Когда я впервые собрал файлы своим плагином, всё выглядело вполне прилично. Упаковщик удалял дубликаты, файлы уменьшались в весе, и я думал, что всё работает идеально. А потом я зашёл в первый обучающий туториал.
Вместо обычных зомби на меня выбежал секретный супербосс Расецу Амон. Миссии сломались. Как выяснилось, при удалении дубликатов потерялись нулевые байты-разделители. Таблица индексов съехала на пару байт вбок, и игра вместо обычной миссии начала читать данные финального босса.
Я полез это чинить и полностью переписал движок сборки. Вырезал дедупликацию, заставил сборщик сохранять каждую строку на своём месте. Запускаю игру — Амона в туториале нет, миссии работают. Ура? Не совсем.
Когда я открыл меню оружия, мой стартовый пистолет превратился в тарелку с мясом с названием (null). Сдвиг байтов сломал уже инвентарь и названия глав. Стрелять тарелкой с мясом по зомби в туториале — зрелище, конечно, незабываемое, но играть так было нельзя.
Пришлось переделывать вообще всё. Я разбил проект на модули, заставил упаковщик жёстко выравнивать структуру по 4 байта и сохранять уникальные адреса для каждой строки. Файлы из-за этого выросли в весе, зато байты встали на свои места. Оружие снова стреляет, зомби кусаются, а не вызывают на дуэль финального босса.
Кстати, массовой сборкой все файлы по новой архитектуре я до сих пор не прогнал. Лень, да и страшно. Надеюсь, что остальные файлы не сломаются. Но если что — я знаю, где искать Амона.
Проблема №3. Проклятие кодировок: почему EASY навсегда останется английским
Файл BOOT.ELF я перевел еще в самом начале, когда только начинал ковырять игру. Перевел меню, какие-то системные надписи и забил. А потом, когда я уже дошел до сохранений в самой игре и нажал «Сохранить», игра выдала мне ошибку. В логе было написано что-то про то, что игра не понимает введенные данные.
Сначала я подумал: «Ага, классика. Строка слишком длинная, не влезла в отведенный буфер». Я зашел в редактор, нашел эти строки (уровни сложности EASY, NORMAL, HARD) и попытался сократить русский перевод. Например, вместо слова «ОБЫЧНАЯ» (которое было длиннее английского NORMAL) я вписал короткий вариант. Запускаю, нажимаю «Сохранить»... и снова ошибка. Даже несмотря на то, что текст стал короче оригинала.
Вот тогда до меня дошло, что дело вообще не в длине, а в том, как игра работает с кодировками. И тут всплыли две разные проблемы.
Первая: Системные сообщения в BOOT.ELF
Это те самые строки про сохранения, установку игры и ошибки (Save your progress?, Installing game data..., Game data is corrupt), которые на скрине в плагине подсвечены фиолетовым. Так вот, в отличие от обычного текста в игре (который читается в 1 байте), здесь игра понимает только UTF-8 (2 байта). Если попытаться скормить ей 1-байтовую кодировку, на экране появятся иероглифы. Но эти строки хотя бы реально перевести, если использовать правильную кодировку.
Вторая: Сами сохранения игры
А вот тут всё гораздо хуже. Сохранения игры не понимают ни 1 байт, ни 2 байта. Они принимают исключительно чистый английский (ASCII). Поэтому уровни сложности и названия глав, которые передаются в системный вызов PS3 для записи сейва, навсегда останутся на английском. Если туда всунуть кириллицу, консоль просто выдаст ошибку и заблокирует сохранение.
Меня это поначалу напрягало, но потом я смирился. Сложности EASY и NORMAL и названия глав в системном меню остаются на английском. Это плата за то, что игра в принципе сохраняется. Зато сам текст заданий в меню паузы (который лежит в базе .bin и читается в 1 байте) прекрасно переведен и отображается на русском.
Что насчет черных заставок с иероглифами?
Там написано 隔離された街 (Изолированный город), а внизу английская подпись Cut Off. Тут пришлось делать жесткий выбор. Я не могу просто убрать Cut Off и написать русский текст, потому что эти строки используются в сейвах. Если я переведу текст для заставки, в сохранениях начнется непонятная каша.
Поэтому мне пришлось выбирать: либо красивая переведенная 5-секундная плашка, либо рабочие сохранения. Я выбрал сохранения. Поэтому на черном фоне останутся иероглифы и английское Cut Off. А вот в самом меню игры (которое лежит в .bin и читается в 1 байте, где сейвы не ломаются), я перевел это как «Блокада». Смысл тот же, и по длине влезает идеально.
Итоги
Конечно, до полного завершения перевода ещё далеко. Там осталась куча всего, и это не только текст.
Что касается текстур и обычного текста. «УСПЕХ» — это только начало. Там есть ещё куча надписей, собранных из отдельных букв, и с ними придётся повозиться. Плюс есть места, где перевод получился кривым или неестественным. Я сохранил их как есть. Но даже когда обновляешь метаданные, длинный текст (длиннее оригинала) всё равно может обрезаться. А в игре ещё и рамки маленькие, места под текст выделено мало. Так что местами перевод придётся сокращать.
Что касается архивов. Кроме баз данных, есть ещё архив паузы. Я туда только заглянул, и там своя атмосфера: файлы без английского, только японский. Какие-то из них — обычные с полями для плагина РГГ ДБ, а какие-то — просто голый текст, который, скорее всего, придётся выковыривать через навигатор Сузуки.
И самое главное — всё это раскидано. Файлы лежат в разных местах, имеют разную структуру. Частично логика в этом есть, но разбираться сложно. Я даже не уверен, что в архиве boot ничего не пропустил.
Пока планов куча. Наверное, сначала разберу остальные архивы (те, где структура папок хотя бы похожа на уже известные), переведу текст, где найду, а уже потом вернусь к корректировке и сокращению того, что есть. Плагины теперь работают как надо, так что переписывать их сильно не придётся — буду просто подставлять новые файлы. Главное, что фундамент готов и сборщик больше ничего не ломает(наверное).