Я хотел поиграть в «Корсаров» на Mac. И немного увлёкся
Я хотел поиграть в «Корсары: Город потерянных кораблей» на Mac. Через Wine игра работала с проблемами. Начал разбираться с совместимостью, затем захотел изменить несколько вещей в самой игре. Примерно через два месяца из этого вырос собственный ремастер.
Я работал с AI-агентами, в основном на GPT-5 Sol; использовал также Gemini и другие модели. По моей оценке, объём этой работы эквивалентен примерно $10–20 тыс. по тарифам OpenAI API. Проект сохранил знакомый пиратский мир и получил нативный рендерер, изменения игровых механик и отдельный режим корабельного дрифта.
Основа — ГПК 1.3.2 AT с ReConstruction 1.4.1: знакомые острова, корабли, персонажи и сюжет. Моя версия запускается отдельным приложением на Apple Silicon с macOS 15 или новее. Для игры не нужны Wine, Xcode или установка зависимостей.
Корабли были. Моря не было
После попыток с Windows-совместимостью и переводом графики я перешёл к своему рендереру на Metal. Первый прототип показывал сушу, корабли и интерфейс. Море отсутствовало. Для «Корсаров» это, конечно, проблема.
Пришлось разбираться с водой: отражениями, преломлением, пеной, цветом на глубине. Потом с тенями, частицами, растительностью и анимацией. Даже перенос анимации на GPU зацепил столкновения: им всё ещё нужна геометрия на CPU.
В Порто-Белло уже были вода и тени пальм, но земля выглядела мыльно. Ночью фонари светили, а между ними было сложно понять, куда идти. Одно починил, полез смотреть следующее.
На морских островах плоские карточки деревьев заменил объёмными деревьями с общими шейдерами ветра и теней. Их положение зависит от грунта, склона, берега и построек. После замены лес оказался редким; увеличил плотность размещения, не поднимая лимит деревьев, одновременно видимых в кадре.
Почему у меня пропала земля
Заодно переделал дерево причалов, палубы, песок, камни и пальмы. С текстурами пришлось быть аккуратным: если переставить доски внутри атласа, старая модель натянет их совсем не туда.
А часть пропавших поверхностей вернулась вообще без новых текстур. Двенадцать файлов с расширением .tga на самом деле были DDS. Старый загрузчик понимал содержимое, новый верил расширению. Исправили чтение контейнера — в Виллемстаде снова появились земля, форт и верфь.
Куда я вообще стреляю
Оригинальное золотое кольцо показывало направление взгляда. Где бортовой залп встретится с корпусом противника, я узнавал уже после выстрела.
Сделал прицел, который ложится на саму сцену: красный контур на корабле, белый на воде. Можно выбрать кусок корпуса, подправить курс и дождаться момента для залпа. Разброс и дальность остаются, автоматического захвата цели нет.
Добавил приближение от 1× до 5×: короткое нажатие правой кнопки переключает крайние значения, удержание позволяет остановиться между ними. Подзорная труба осталась отдельной вещью.
Одной пушкой тоже можно
Теперь можно стрелять по одному орудию или всем бортом. У каждой пушки свой заряд и перезарядка; переключение режима их не сбрасывает.
Добавил пятый боеприпас — шрапнельные бомбы с подрывом рядом с целью. У разных зарядов разный разброс и время перезарядки. Книппелями удобно работать по такелажу, шрапнелью — по открытой команде.
Четыре корабля, четыре одинаковых заботы
Когда у меня появилась эскадра, стало особенно заметно, сколько действий заканчиваются на флагмане. Еда, ром, лекарства, ремонт, отдых команды — всё это распространил на доступные корабли спутников. Запасы и деньги остаются настоящими: снабжение не возникает из воздуха.
Офицерам сделал пополнение боеприпасов и лекарств из сундука в каюте. Оттуда же они могут взять лучшее обычное снаряжение. Квестовые вещи и подходящее оружие, которое я надел вручную, система не трогает.
Казначей, запомни уже этот заказ
Для каждого корабля можно один раз задать, сколько держать провизии, пороха, бомб или досок. Казначей пополняет запасы до этих значений, учитывая кошелёк, магазин и свободный трюм. Повреждённому призу и боевому флагману нужны разные заказы.
С абордажной добычей та же история: захотелось разбирать её по своим правилам. Выбираю категории продажи, сколько копий оставить и какие вещи защитить, смотрю предпросмотр. Квестовые предметы и личное снаряжение в продажу не уходят.
Саму добычу можно собрать из каютных сундуков в сундук флагмана одним разговором или осмотреть вручную. Покупка и продажа включаются отдельно и работают в подходящем порту; загрузка сохранения сама по себе ничего не продаёт.
Капитан вырос. Здоровье — не особо
На 18-м ранге у моего капитана было 110 максимальных HP. Переделал рост здоровья и лимит офицеров: теперь на них влияют развитие героя и навыки, а не только характеристики, выбранные в начале. Начальная прокачка тоже требует меньше повторений.
Здорового капитана больше нельзя убить одним выстрелом: урон огнестрела ограничен 49% максимального здоровья. Раненого всё ещё можно добить. За большой состав офицеров по-прежнему приходится платить и следить за лояльностью.
Кто донёс
Напал на корабль — он сразу вступает в бой. А дальше важно, дошла ли весть до остальных. Донести могут выжившие, другой корабль, форт или собственная команда. Можно опознать флаг, не узнав капитана; смена флага не стирает уже известную историю.
Долги, мораль и навыки влияют на поведение команды. Прямой свидетель от этого никуда не исчезает. В разговорах с обычными персонажами тоже появилась возможность напасть, с сохранением защиты квестовых сцен.
Иногда лучше сдаться
Добавил сдачу властям вместо обязательного боя до смерти. Капитана могут посадить, оштрафовать и забрать снаряжение на хранение. В тюрьме есть занятия и отношения с другими заключёнными; при освобождении вещи возвращаются. Если героя этапировали, эскадра не остаётся забытым грузом на другом острове.
Табак выгодный. Но сколько влезет
В торговом журнале разделил цену, прибыль на вес, план груза и ожидаемый доход. Теперь можно сравнивать товары по месту, которое они займут в трюме. Цены берутся из известных данных: следующий порт всё ещё способен испортить красивый расчёт.
Просто походить по своему кораблю
Можно выйти на палубу во время плавания или боя, пока море продолжает жить. Ходить, бегать, смотреть в трубу, управлять кораблём и стрелять. Столкновения оставил с твёрдыми частями корабля; отдельный обход матросов убрал из-за лишней нагрузки.
Обогнуть дождь
Связал погоду на карте и в локальном море. Фронты движутся с ветром, дождь начинается и заканчивается постепенно. Облака могут оставаться после ливня; переход в город или помещение не создаёт новую погоду с нуля.
В шторме стало иметь значение, как идти и сколько парусов держать. Обычный штормовой износ останавливается у нижнего предела состояния корабля. Пушечные попадания, торнадо и цунами своих последствий из-за этого не теряют.
Мне бы до порта дотянуть
Бесплатный аварийный ремонт немного поднимает состояние корпуса и парусов; ремонт с материалами делает это быстрее и до более высокого предела. Команду и упавшие мачты они не возвращают.
Мачты чинятся отдельным приказом в безопасном море. Нужны люди, доски и игровое время. Перед началом видно, во что это обойдётся; отмена ничего не тратит. Полностью восстановить весь рангоут таким способом нельзя.
Чтобы ночью было куда идти
Небо, туман, вода и наружный свет пришлось согласовывать вместе. Поработал над горизонтом, тенями фонарей и промежутками между освещёнными местами. Хотелось сохранить ночной порт, в котором всё ещё можно разобраться, где ты находишься.
Увидеть Сан-Хуан с моря
Отдельным экспериментом перенёс геометрию Сан-Хуана на морской остров Пуэрто-Рико. Привёл город и остров к одному физическому масштабу, сохранил исходный форт с пушками и убрал лишние фоновые кварталы. Это эксперимент с видом берега; в сам город по-прежнему ведут обычные переходы между локациями.
Из моря — над своим кораблём
При выходе на карту камера поднимается над флагманом. На карте остаётся миниатюра именно моего корабля: с его корпусом, мачтами, парусами и повреждениями. Обратно в море камера идёт тем же путём в обратную сторону.
Я переработал корабельные пожары
Пожары были и в исходной игре, но их эффект и последствия меня не устраивали. Я переделал систему: огонь начинается в конкретном месте, распространяет тепло, обугливает дерево и повреждает паруса. Дождь помогает тушению. Можно бросить людей на борьбу за живучесть, но эти люди тогда не стоят у пушек. После тушения повреждения остаются и переживают сохранение.
Для изображения пламени понадобились свои правила. Изменение жара сдвигало всё поле шума; расстояние до камеры могло сбросить сетку выборки. Я отделил непрерывное движение пламени от интенсивности и сделал изменение выборки плавным по расстоянию. Расчёт тепла, топлива и сохраняемых повреждений остался прежним.
Потом жена предложила фонк
В какой-то момент я устал от постоянных исправлений. Жена предложила добавить фонк и попробовать корабельный дрифт. Так появился отдельный режим, в котором можно просто погонять боком.
В Phonk Mode парусник дрифтит под музыку с сиреневой подсветкой. С Shift разгоняется до 1000 узлов и чуть встаёт на дыбы; на цунами может взлететь. Сам разгоняешься, тормозишь и поворачиваешь. Выключаешь режим — возвращается обычное плавание.
Там же попробовал ядерные выстрелы. В автоматическом огне слабые заряды выпадают чаще; удержанием и отпусканием огня можно выбрать мощность от 1× до 10×. У каждого взрыва одна мощность для облака, ударной волны, небольшого цунами и пожара. Рисунок взрыва задаётся независимо от камеры, поэтому её движение не пересоздаёт эффект. После прямого попадания корабль не получает тот же урон повторно от ударной волны; уничтоженные корабли сохраняют тепло и импульс.
И ещё один квест
«Великий рецепт» начинается со слухов на Бермудах. Дальше — ночная встреча с Красной Бородой, бой в водовороте, плен и лунная бухта. Эта квестовая линия пока не закончена. На это время у бермудского торговца Паскаля Вуазье есть отдельная реплика: «Дай 200 шрапнельных бомб (квест пока не готов)». Партию можно получить бесплатно раз в семь игровых дней, если в трюме достаточно места.
Когда оптимизация испортила горизонт
В одном из проходов по рендереру я убирал лишнюю работу, но проба гибридного неба дала заметный шов на горизонте. Туман ослаб, остров и вода стали слишком тёмными на фоне светлого неба. Я вернул прежние шейдеры тумана и авторское небо, выключил гибрид, а независимые изменения для производительности сохранил. Ожидание подготовки корпуса, которое задерживало появление корабля в живом море, убрал из загрузки.
Позднее профилирование вернуло меня к работе CPU. У команды уже были заданные маршруты по палубе, поэтому я убрал проверки опорной геометрии из каждого обновления движения. Пушки, такелаж и корпус по-прежнему проверяют физическую опору. Оставшиеся запросы повторно используют найденную ближайшую геометрию. Перед первым кадром загрузчик текстур теперь читает покрытие альфа-канала прямо из DXT1, не декодируя ненужные ему цвета.
Параллельно пробовал материальные разломы корпуса при столкновениях. Эта ветка осталась выключенной по умолчанию: обычные столкновения и урон работают своим путём. Экономия в отдельных операциях измерена, но сопоставимого замера FPS всей игры у меня нет.
Можно поиграть
Получилось отдельное приложение для Mac. Сохранения и настройки лежат снаружи, поэтому замена приложения не забирает прогресс капитана. Ремастер остаётся экспериментальным.
Скачать сборку для Mac · Исходный код · Исходники движка и зависимости
В changelog на русском собраны подробности механик, требования и известные ограничения.