C.O.P. The Recruit (2009) - спин-офф серии Driver.
Если коротко, то я это прошел и даже запилил перевод.
Необязательная и чрезвычайно длинная подводка к сабжу
⠀Летом 2024-го я созрел до прохождения серии Driver. Обычно у меня так и случается - долго собираюсь, жду настроения, а потом - бац! - и сразу несколько игр одной серии прохожу. Вот и тогда два года назад я, наконец-то собравшись, одолел тот гараж (ладно, я уже проходил этот этап раньше) и пошёл катать по американским городам под фанковые ритмы: солнечные Майами и Сан-Франциско, хмурый Нью-Йорк, сверкающий огнями Лос-Анджелес. И спасение президента в зимнем Нью-Йорке - финальная миссия, поджигающая пукан не хуже самой первой обучающей.
⠀Там, где первая, там же и вторая. Все еще круто, пусть и слегка изменилось по атмосфере. Чикаго, Гавана, Лас-Вегас и Рио - города стали как будто бы больше по сравнению с первой частью. Да и герой научился выходить из машины (зачем-то). Кстати, играл я в ПК-порт ReDriver 2 - тогда у него ещё была низкая дальность прорисовки, как на оригинальной консоли.
⠀Третья часть - Driv3r, о которой обычно отзываются крайне негативно, на самом деле оказалась не такой уж плохой. Она просто сырая, её заканчивали в спешке под нажимом издателя, так что получилось, что получилось. Зато здесь снова есть Майами, а ещё Ницца и Стамбул. И ведь при внимательном рассмотрении заметно, что в некоторых местах на карте планировались какие-то активности, но, спасибо Atari, мы о них никогда не узнаем.
⠀Когда-нибудь дойдут у меня руки пройти версию этой игры для GBA...
⠀Пару лет спустя вышла ещё одна игра - Driver: Parallel Lines, где атмосферу 70-х из первой части (а про время действия там нигде не упоминалось) буквально превратили в сеттинг: половина игры проходит в солнечном 1978-м, а другая - в угрюмой современности 2006-го. Местом действия стал Нью-Йорк - Манхэттен, Куинс, Бронкс, Бруклин и Нью-Джерси. В сравнении с прошлой частью игралось уже получше.
⠀Через год на PSP вышел приквел - Driver '76. Всё то же самое, даже место действия не поменяли, мы всё также катаемся по всё тому же Нью-Йорку.
⠀Последняя крупная игра серии вышла в 2011-м. И Driver: San Francisco внезапно вернулся к корням - теперь это чисто гоночная аркада без пеших сегментов и стрельбы. Зато с новой механикой - переселением в других водителей. Несложная, весёлая, стильная - в целом приятная, если серия так никогда и не продолжится, то это было бы отличным её завершением.
⠀Но тогда, в 2024-м, я прошел ещё одну игру серии - Driver: Renegade, которая сюжетно располагается между первой и второй частями серии. Пришлось долго искать эмулятор Nintendo 3DS, который бы у меня заработал. А сама игрушка в принципе оказалась так себе: три часа на сюжетные задания и еще семь на режим карьеры из 84 заездов. И все это на урезанной карте из Driver: Parallel Lines - пропала западная часть Нью-Джерси, Бронкс и Южный Бруклин.
⠀Однако, именно в Driver: Renegade в меню я заметил постер, который оказался не просто рандомной картинкой, а обложкой предыдущей игры, которая должна была быть частью серии Driver, но как-то отпочковалась от неё в самостоятельный продукт - C.O.P.: The Recruit. Само собой, у меня возникло желание пройти и её, раз уж она почти часть франшизы. Однако, игра консольная (значит придется юзать эмулятор Nintendo DS) и без перевода (значит придется напрягаться в процессе, пытаясь успевать понять, что там пишут в субтитрах). И вот второй пункт как раз и отбил все желание, игра всё-таки с полноценным сюжетом, а напрягаться мне было уже не в кайф.
⠀Но в этом году, читая, как кто-то сделал перевод какой-то игры с NDS с помощью нейросетей (распаковал ресурсы, разобрал форматы, запаковал обратно и т.д.), я решил, что пора. Пора пройти игру, параллельно пиля перевод.
Что там по игре
⠀Сама игра - это аркадный экшен в открытом мире, причем мир этот - тот же самый урезанный Нью-Йорк из Driver: Renegade, но на пару лет раньше и графически попроще. Хотя сам факт полноценного трехмерного города на слабенькой карманной консоли впечатляет.
⠀Главный герой - Дэн Майлз, ранее участвовавший в нелегальных гонках (в жилах течет бензин и все такое). После одной погони по улицам города, закончившейся ДТП, вместо отбывания наказания в тюрьме Майлз соглашается принять участие в программе реабилитации преступников - Criminal Overturn Program (та самая титульная C.O.P.) и работать в Отделе Городского Контроля (CCD). Это что-то вроде полицейской организации, оказывающей содействие остальным ведомствам города.
⠀Сюжет игры разделен на миссии, разбитые на семь дней. И это будут весьма насыщенные семь дней для новоиспеченного офицера CCD: погони, перестрелки, захват заложников, руководство отрядом SWAT во время штурма, скрытное проникновение, работа под прикрытием, слежка, тушение пожаров, участие в нелегальных гонках, потеря наставника, соблазнение его безутешной сестры (на следующий же день - парень времени не теряет), работа на армянскую мафию и , наконец, предотвращение террористического акта и раскрытие коррупционного заговора.
⠀Сами миссии в основном довольно короткие - 3-7 минут. Хотя есть и весьма растянутые задания из нескольких этапов, минут на 15 минимум, а по факту займут больше. Например, миссия 37 - "Блэкаут" - начинается с прибытия на место на катере, потом на этом катере придется плыть по канализационным стокам, лавируя между взрывающимися бочками; перестрелять панков, облюбовавших канализацию; выбравшись на поверхность бежать в магазин, где перестрелять мародёров, после чего торопиться-на электростанцию тушить пожар и искать ящики с маршрутизаторами, затем бежать ещё в одно место, а там будет уже стэлс-сегмент с проникновением и обходом охраны.
⠀По геймплею тут все стандартненько для игр с открытым миром. Мы либо катаемся на машинах, либо бегаем и стреляем. Правда, вождение тут какое-то неудобное, что как бы странновато, учитывая, откуда у игры ноги растут: в серии Driver таких проблем не наблюдалось.
Да и стрельба тут специфическая, всё-таки это двухэкранная NintendoDS, и прицеливание осуществляется с помощью тачскрина и стилуса. В эмуляторе, конечно же, для этих целей используется мышь. Наверняка, на оригинальном железе процесс гораздо удобнее.
⠀Тот же самый стилус и тачскрин используются в игровом процессе и иначе. По сюжету у главного героя есть что-то вроде КПК под названием City Control Console - сокращенно 3C. И картинка на тачскрине, которую видит игрок, это как раз интерфейс этой 3C, который видит персонаж. На экране может отображаться карта, на которой можно поставить метку, окно рукописного ввода кодов, картинка с камер наблюдения или оптоволоконной камеры во время штурма. Правда, кнопка "Загрузить", которую тоже как бы видит персонаж, немного ломает четвертую стену.
⠀Катаясь по городу между миссиями можно получить сообщения от диспетчера, что где-то неподалёку ограбление или буйный водитель. Это местные побочные задания, всего их 24.
⠀Восемь заданий с погоней: нужно таранить машину, чтобы остановить (правда, в итоге она всё равно бабахнет). Минус в том, что нужно впечататься в машину именно мордой, просто бортануть слева-справа урона не нанесёт. С местным управлением не особо удобно.
⠀Ещё восемь заданий - вызов на место ограбления или скопление вооруженных людей. Эти задания загружают какой-нибудь интерьер - банк, магазин, стоянку, заброшенный дом - и требуют просто размотать там всё живое.
⠀И последний тип побочных миссий - погоня за машиной (можно провалить, если слишком отстать) с последующей перестрелкой в интерьере (тут врагов поменьше, типа они все сидели в машине).
⠀Побочные задания лучше трогать после завершения сюжета, когда откроется лучшее оружие. Штурмовая винтовка и автоматический дробовик - наше всё.
⠀Задания с погонями, кстати, тоже имеют одну особенность. У игры есть как минимум два, а может быть и три состояния траффика: условно "нормальный", "час пик" и "ходи пешком, лошара, машины почти не спавнятся". Игра переключается между этими состояниями каждый раз, когда главный герой помещается в мир: при загрузке сохранения, при выходе из интерьера и после смерти/провала миссии, когда спавнится у больницы.
⠀И, очевидно, побочные задания с погонями лучше начинать именно когда игра находится в режиме полупустых улиц. Для этого нужно подобрать правильный момент - либо сразу после загрузки сохранения улицы будут пустые, либо смерть и воскрешение у одной из больниц даст траффику нужное состояние (это ещё и от больницы, походу, зависит).
⠀Кстати, с траффиком ещё одна забавная фишка есть. Загружая сохранение, игра каждый раз будет спавнить одни и те же машины рядом с игроком (и пешеходов тоже). Пройденная миссия меняет состояние машин после загрузки - другие машины и в другом порядке. При этом состав машин в глобальном траффике тоже меняется после каждой миссии, где фигурируют конкретные автомобили. Например, местная версия Мини Купера появляется на улицах после задания, в котором герой на нем катался. А финальная миссия, где приходилось гоняться за спорткарами, после прохождения заменяет все машины на эти самые спорткары - в эндгейме уже не будет пикапов, внедорожников и мусоровозов.
⠀Прохождение миссий отражается в статистике с помощью "трофеев" - просто звёздочки напротив соответствующих достижений, по пять напротив каждого. Часть из них выдаются просто по факту завершения миссии, а для получения других потребуется уложиться в таймер во время миссии. Например, трофей "Лётчик" - награда за выполнение гоночных миссий за отведенное время, хотя сами миссии можно пройти и без оглядки на таймер.
⠀Туда же в статистику идут и побочные задания - трофеи "Охотник", "Гроза воров" и "Чистильщик", а также коллекционные предметы. Тут в роли коллектиблсов выступают 25 точек для съемки фотографий, 50 дорожных барьеров и 50 агитационных плакатов. Большинство из них всегда на виду, а барьеры расставлены в переулках-шорткатах. Так что большая часть так или иначе будет собрана в процессе прохождения миссий.
⠀Так в эндгейме у меня оставалось не найдено только 10 из 125 предметов. Последние три, когда стало лень их искать, я собрал с помощью карты из интернета. И, конечно же, они торчали на самом видном месте.
⠀Ну и ещё один минус, пока не забыл. В игре музыка есть только в миссиях, а вот рассекать по городу придется чисто под звуки этого самого города, хотя в той же GTA Chinatown Wars некое подобие радио в транспорте было.
Мой совет: включить на фоне саундтрек из первого Driver.
Сразу становится ДРАЙВОВЕЕ!
Про то, как оно переводилось.
⠀Процесс перевода начался с того, что я буквально спросил у нейронки (это был Grok AI), как распаковать ROM и что делать дальше.
После чего, распотрошив образ с помощью Tinke и получив кучу файлов, начался процесс поиска, какие именно файлы отвечают за текст и шрифт.
⠀Нейронка просила сбросить Hex-дамп файла, подозреваемого на содержание текстовых строк, но смогла отыскать только пару коротких обрывков, за которые мы и зацепились. Постепенно, сравнивая два языковых файла - английский и французский - Grok пришел к выводу, что они зашифрованы неопределенным сжатием VC.
⠀Далее, чтобы это сжатие расшифровать, нейросеть просила делать дампы памяти во время игры, и продолжать сбрасывать ей куски Hex-дампов исследуемых файлов.
⠀Когда стало понятно, что пока ни к чему это не приведет, я попробовал подойти с другого конца. Среди игровых ресурсов были файлы с расширением .gfx - очевидные картинки. Причем в большом количестве были файлы с названием, начинавшимся на wiki - это картинки из внутриигрового справочника: оружие, машины и персонажи. Такую картинку Grok распознал без проблем - сырые 8bpp пиксели без заголовка и без тайловой перестановки. В комплекте ещё шли файлы палитры с расширением .pal. На этом этапе нейронка уже смогла наклепать простенькую графическую оболочку для открытия этих файлов.
⠀Далее, попытавшись открыть другие gfx-файлы, и убедившись, что не выходит, было решено, что функцию распаковки VC нужно искать в arm9.bin - открыть его с помощью Ghidra и скидывать из неё функции, адреса и участки кода.
⠀Так продолжалось, пока нейронке не удалось частично восстановить алгоритм распаковки VC, а потом уже дорабатывался он. Так, например, уточнить его удалось с помощью файла с зашифрованным текстом: зная конкретные текстовые строки, нейросеть смогла их правильно декодировать.
⠀Далее доводка шла уже на gfx файле с логотипом Юбисофт и его скриншотом из игры в качестве эталона. Сначала долго получалось какое-то говно с битыми пикселями (Ubisoft как никак), затем, когда эта картинка стала выходить нормально, а остальные стали читаться в оттенках серого, я уже использовал другие по той же схеме - связка скриншота и gfx-файла - для правильного применения палитры, которая тоже оказалась сжата контейнером VC. Так, прогоняя по циклу, сверяясь с различными gfx файлами получился сносный декодер. Который, впрочем, впоследствии ещё не раз дорабатывался.
⠀Теперь, расшифровав с помощью декодера языковой файл, можно было приступить к переводу. Предварительно выяснив, в каком файле сидит шрифт и как он запакован: в игре два шрифта - один в виде тайловой сетки в формате 8×8 4bpp , а второй в виде горизонтального 4bpp-атласа 956x13.
⠀И если с первым шрифтом проблем не возникло, то у второго пришлось ещё менять размеры глифов - адреса начала буквы в атласе и прописывать их в arm9. Для этого Grok сделал отдельное приложение, где открывался шрифт и было видно, как отображается буква. Позже возникла идея ещё и расширить этот атлас, чтобы буквы по ширине совпадали с оригинальным шрифтом, а то поначалу пришлось сильно ужаться. Оказалось, что максимальный размер - 1024 пиксела, больше тоже можно, но память игры забивается , а это влияет на все - у меня, например, из-за этого миссии не стартовали без перезагрузки сохранения или ломался интерфейс.
⠀Подготовив шрифт, я попросил нейронку накидать excel-таблицу с текстовыми строками из трех разных языковых файлов (английский, немецкий и французский) и уже вручную все это переводил - английский как основа, а два других языка вспомогательные (их уже гугл-переводчиком). И если вдруг какое-то предложение звучит кривовато, то это чисто человеческий фактор, а не нейросеть.
⠀К тому же обнаружилось, что некоторые фразы отличаются по содержимому, так что при переводе я комбинировал несколько вариантов из разных языков. А в паре некритичных мест выдавал полную отсебятину, чтобы разбавить однотипные сообщения от диспетчера.
⠀Потом возникла следующая ситуация. Текстовые строки ограничены по размеру, выйдя за границы сбивается весь последующий текст. И сначала я честно пытался делать перевод, умещая его в имеющиеся рамки, но потом мне это надоело, так что навайбкоденный текстовый редактор научился пересобирать таблицу смещений, чтобы строки можно было расширить.
⠀И вот, потихоньку делая перевод миссий по одной и проверяя, как он работает в игре, я двигался по сюжету, периодически натыкаясь на проблемы. Так, например, у некоторых строк в начале стоит префикс, обозначающий говорящего - "3" - главный герой, "1" - сообщение о провале, "5" - строки меню или субтитры в заставках. Кстати, в одном месте префикс стоял неправильный, и вместо системного сообщения получалась реплика от персонажа, с которым я ещё даже не знаком.
⠀Так вот, среди этих префиксов есть и знаки препинания, и пробел, и даже знак переноса строки. Редактор неправильно их интерпретировал, не считая частью строки, и все последующие смещения ломались. После исправления редактора пришлось заново брать оригинальный языковой файл и заново же вставлять в него строки. И перепроверять, ничего ли теперь не слетело в уже пройденных миссиях.
⠀И так было несколько раз в начале игры, потом после 10-й миссии проблем особо не возникало. До 30-й, где обнаружилось, что все это время таблица смещений пересчитывалась неправильно и накопившаяся ошибка ломала последующий текст напрочь. Там уже копировать все предыдущие строки вручную было бы уже верхом мазохизма, так что появилась идея добавить в редактор функцию построчного копирования между двумя файлами с параллельным пересчетом таблицы смещений.
⠀Кстати, в процессе обнаружилось, что текст из заставки в 17 миссии в журнале прописывается в 16-ю. Это не мой косяк, это Юбисофт нафигачили.
⠀А к концу перевода ещё и выяснилось, что некоторые строки в игре вообще не используются. Например, у каждой миссии есть уникальное сообщение о провале, но не у всех оно вызывается на экран, вместо него вылезает стандартная фраза-заглушка. То есть спрятанное мной в одном месте "Потрачено" так никто и не увидит. Обидно.
⠀Потом, разобравшись с текстом, пришла очередь интерфейса. Буквально несколько спрайтов набитых тайлами: один файл для текста начального меню, в одном зашиты куски игрового интерфейса (тут запрятана фраза "Миссия выполнена") и текст для кнопок 3С. И с первыми двумя проблем не возникло, а вот с третьим пришлось повозиться.
⠀Казалось бы, тут все вроде просто: есть кнопки, на них написаны буквы. Вот только буквы на самом деле идут кусками-тайлами 8x8 в файле спрайта, причем отдельные куски могут быть сдвинуты относительно друг друга по вертикали. При русификации слова получаются длиннее оригинальных, например "Map" явно короче, чем "Карта". Хорошо хоть некоторые слова в файле спрайта в игре не используются, так что можно позаимствовать их место.
⠀В итоге отдельной утилитой пришлось редактировать размеры слов по числу тайлов, да ещё и смещать тайлы по вертикали, к тому же некоторые из них на кнопку набиваются в два ряда...
⠀Ну, а когда и текст и интерфейс оформились, было принято решение подправить парочку текстовых текстурок в заставках. Проблема в том, что все текстуры одной заставки напиханы в файл .tex, причем подряд, причем в разных форматах - 8bpp, 4bpp, 2bpp, полноценый RGBA. Тут тоже долго вносились костыльные правки в редактор-декодер, так что к концу он почти превратился в монстра Франкенштейна: не очень понятно что из того, что в нем есть, работает в данный момент, а что атавизм от ранних итераций. Сами картинки в контейнере tex редактор друг от друга отделяет плохо, приходится вручную указывать размеры, а у тех, что в 8bpp и ниже - ещё и смещение палитры вручную подбирать. И это ради восьми необязательных картинок.
⠀Конечно же я понимаю, что весь процесс был максимально неоптимальным, наверняка всё можно было осуществить и как-то проще, по-умному.
⠀Но главное, по итогу-то, перевод я всё-таки доделал. Я, конечно же, пытался отловить опечатки и всё такое, но не факт, что удалось это сделать полностью. В остальном русифицированный ROM (русский стоит вместо английского) нормально играется на эмуляторе DeSmuME, запускается на No$GBA и MelonDS. Я от начала и до конца прошел игру в стимовской Retroarch на ядре MelonDs Ds. Вроде бы всё работает.
⠀Правда, не могу гарантировать, что будет пахать на настоящем железе.
⠀Свистните, кто смог протестить.
⠀Хотел выложить итоговый вариант в зелёном магазине, но я так запарился, набирая эту простыню текста, что мучиться с оформлением ещё и там мне не охота. Так что вот ссылка на ЯндексДиск (Хз, можно ли вообще тут ссылки такого рода постить).
Короче, забирайте, пока в Nintendo не очухались.