~/wiki / novosti / codex-fixed-frostpunk-crash-macos-openal-patch

Попросил Codex починить ForstPunk на MacOs Tahoe. Он скомпилировал библиотеку из исходников и пропатчил бинарник

◷ 8 мин чтения 03.06.2026

Основной чат

Чат для вайбкодеров: новости, гайды, поиск исполнителей, маркетплейс и разбор реальных кейсов.

$ cd раздел/ $ join vibe dev
Попросил Codex починить ForstPunk на MacOs Tahoe. Он скомпилировал библиотеку из исходников и пропатчил бинарник - обложка

Frostpunk падал при каждом проигрыше. Не зависал, не выдавал ошибку — просто мгновенно вылетал в момент, когда город должен был рухнуть. Каждый раз. На macOS Tahoe Beta 26.5, на Apple Silicon, через Rosetta.

Стандартные советы из интернета не помогли. Поддержка игры молчала. Я открыл Codex и написал: «Игра постоянно крашится, разберись».

Через несколько часов игра работала. Codex собрал нужную библиотеку из исходников и пропатчил бинарник. Вот как это было.

Диагноз: где именно падает

Codex первым делом прочитал crash report. Это уже нетривиально — stack trace системного краша выглядит как стена текста, и большинство людей не знают, что с ним делать.

code
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Crashed Thread: Audio Thread
  SoundEngine::Update()
    OpenAL / AudioToolbox
      alSourceQueueBuffers
      alDeleteSources

Вердикт агента: игра падает не в графике, не в памяти, не в сохранениях. Падает в аудиостеке — именно в системной реализации OpenAL от Apple, при попытке поставить в очередь звук проигрыша. Старая игра (2018), новый macOS (Tahoe Beta), несовместимость.

Конкретная причина для поиска, которую Codex сформулировал сам:

Frostpunk 1.1.1 GOG Mac crashes on game over in SoundEngine / OpenAL / AudioToolbox, EXC_BAD_INSTRUCTION SIGILL, triggered by sequences/sequence_gameover.ogg on macOS 26.5 Tahoe beta under Rosetta.

Попытка 1: виртуальное аудиоустройство

Первая гипотеза — несовместимость частоты дискретизации. Системный OpenAL мог падать из-за того, что игра пытается отдать 16kHz аудио в стек, настроенный на 44.1kHz.

Codex установил BlackHole — виртуальный аудиодрайвер, которому можно принудительно выставить любую частоту:

bash копировать
brew install blackhole-2ch
# после перезагрузки
SwitchAudioSource -s "BlackHole 2ch"
sudo defaults write /Library/Preferences/Audio/com.apple.audio.SystemSettings \
  "Default Sample Rate" -float 16000

BlackHole встал, частота выставлена в 16000 Hz, Frostpunk запущен. Игра падала точно в тот же момент.

Гипотеза не подтвердилась. Дело не в частоте — дело в самой реализации Apple OpenAL на новом macOS.

Попытка 2: заменить OpenAL целиком

OpenAL — открытый стандарт. Помимо системной реализации Apple существует OpenAL Soft — кроссплатформенная open-source альтернатива, которую используют тысячи игр именно для совместимости.

Идея: заставить Frostpunk грузить OpenAL Soft вместо Apple OpenAL. Если падение в системной реализации — оно уйдёт.

bash копировать
brew install openal-soft

Codex поставил — и сразу проверил архитектуру:

bash копировать
file /opt/homebrew/lib/libopenal.dylib
# libopenal.dylib: Mach-O 64-bit dynamically linked shared library arm64

Проблема: Homebrew на Apple Silicon ставит arm64 библиотеки. Frostpunk — старая игра, x86_64, запускается через Rosetta. arm64 библиотеку она физически не сможет загрузить — разные архитектуры.

Ключевой шаг: сборка x86_64 из исходников

Готового x86_64 пакета нет. Codex решил собрать OpenAL Soft самостоятельно — из исходного кода, с явным указанием целевой архитектуры.

bash копировать
git clone --depth 1 --branch 1.25.2 \
  https://github.com/kcat/openal-soft.git /tmp/openal-soft-frostpunk

cmake -S /tmp/openal-soft-frostpunk \
  -B /tmp/openal-soft-frostpunk/build-x86 \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_OSX_ARCHITECTURES=x86_64 \
  -DCMAKE_INSTALL_PREFIX=/tmp/openal-soft-frostpunk/install-x86 \
  -DALSOFT_UTILS=OFF -DALSOFT_EXAMPLES=OFF -DALSOFT_TESTS=OFF

Сборка упала с ошибкой. Xcode в Tahoe превращает предупреждение -Wfunction-effects в ошибку компиляции — это новая строгость нового компилятора, о которой авторы OpenAL Soft просто не знали на момент релиза 1.25.2.

Codex нашёл строку в CMakeLists.txt, которая добавляла флаг, и удалил её:

bash копировать
# Находим строку в CMake-файле
grep -n "Werror=function-effects" \
  /tmp/openal-soft-frostpunk/CMakeLists.txt

# Удаляем её sed-ом
sed -i '' '/Werror=function-effects/d' \
  /tmp/openal-soft-frostpunk/CMakeLists.txt

Пересборка прошла успешно:

bash копировать
cmake --build /tmp/openal-soft-frostpunk/build-x86 --parallel 4
cmake --install /tmp/openal-soft-frostpunk/build-x86

file /tmp/openal-soft-frostpunk/install-x86/lib/libopenal.1.25.2.dylib
# libopenal.1.25.2.dylib: Mach-O 64-bit dynamically linked shared library x86_64

x86_64. То что нужно.

Патч бинарника: подмена зависимости

Теперь нужно сказать Frostpunk: не грузи /System/Library/Frameworks/OpenAL.framework, грузи нашу библиотеку. Для этого есть инструмент install_name_tool — он встроен в macOS и позволяет менять пути к динамическим библиотекам прямо в бинарнике.

Codex не трогал оригинальную игру в /Applications — создал тестовую копию и патчил её:

bash копировать
app='/Users/a/Applications/Frostpunk-nosound.app'
exe="$app/Contents/MacOS/Frostpunk"
fw="$app/Contents/Frameworks"

# Сохранить оригинальный бинарник
cp -p "$exe" "$exe.apple-openal-backup-$(date +%Y%m%d-%H%M%S)"

# Скопировать нашу библиотеку внутрь приложения
cp /tmp/openal-soft-frostpunk/install-x86/lib/libopenal.1.25.2.dylib \
  "$fw/libopenal.1.25.2.dylib"
ln -sf libopenal.1.25.2.dylib "$fw/libopenal.1.dylib"
ln -sf libopenal.1.dylib      "$fw/libopenal.dylib"

# Сказать библиотеке, как она называется внутри бандла
install_name_tool -id \
  '@executable_path/../Frameworks/libopenal.1.dylib' \
  "$fw/libopenal.1.25.2.dylib"

# Сказать бинарнику: вместо Apple OpenAL грузи нашу
install_name_tool -change \
  '/System/Library/Frameworks/OpenAL.framework/Versions/A/OpenAL' \
  '@executable_path/../Frameworks/libopenal.1.dylib' \
  "$exe"

После этого Codex переподписал изменённые файлы ad-hoc подписью (иначе macOS откажется запускать):

bash копировать
codesign --force --sign - "$fw/libopenal.1.25.2.dylib"
codesign --force --deep --sign - "$app"

Проверка — зависимость поменялась:

bash копировать
otool -L "$exe" | grep -i openal
# @executable_path/../Frameworks/libopenal.1.dylib

Системный Apple OpenAL больше не подключается. Вместо него — наш собранный OpenAL Soft 1.25.2.

Результат

bash копировать
open -n '/Users/a/Applications/Frostpunk-nosound.app'
# Процесс жив. Новых crash report нет.

Frostpunk запустился. Прошёл момент проигрыша — тот самый, где раньше вылетал каждый раз. Не упал.

## Что сделал Codex самостоятельно

Если перечислить шаги, которые агент выполнил без участия человека:

  • Прочитал crash report и определил точный компонент падения
  • Сформулировал поисковый запрос для диагностики
  • Установил и протестировал BlackHole (гипотеза 1)
  • Обнаружил несовместимость архитектур (arm64 vs x86_64)
  • Клонировал репозиторий OpenAL Soft и собрал x86_64 версию
  • Нашёл и исправил ошибку компилятора в CMakeLists.txt
  • Создал тестовую копию приложения (не трогая оригинал)
  • Применил install_name_tool для подмены зависимости
  • Переподписал приложение
  • Проверил результат

Ни один шаг не требовал объяснений или уточнений. Я только говорил «упало» и «готово».

Почему это важно

Патч динамических библиотек, install_name_tool, сборка под конкретную архитектуру через CMake — это задачи, которые раньше требовали либо глубокого опыта в системном программировании на macOS, либо нескольких часов поиска на Stack Overflow и 4PDA. Большинство пользователей просто удалили бы игру.

Codex прошёл этот путь за один сеанс, включая отладку ошибки компилятора в чужом коде. Это уже не ассистент — это агент, который берёт задачу и идёт до конца.

Тот же подход работает для любой старой игры или приложения, которое падает из-за несовместимости системных библиотек на новом macOS. Рецепт:

  1. Найти в crash report имя упавшей библиотеки.
  2. Найти её open-source замену.
  3. Собрать под нужную архитектуру.
  4. Подменить через install_name_tool.

Codex сделает это за вас.


Связанный кейс: Codex подключился к телевизору и починил мультики — как агент нашёл закрытый WebSocket-протокол и через него диагностировал телевизор.

$ cd ../ ← назад к Новости