Crash Doctor 2.1.0.0 — девять новых защит
Девять новых защит, честный счётчик предотвращённых вылетов, разбор дампов и свой расширенный стек в отчёте. Одна установка на Bannerlord 1.2 / 1.3.15 / 1.4.x.
Коротко
- Девять новых защит — от смены дня из-за предмета прошлой кампании до казни без палача на 1.5+
- Исправлен собственный баг на 1.2.10: Доктор ломал расчёт жалованья и считал это «предотвращёнными вылетами»
- Отчёт: свой расширенный стек и разбор нативных вылетов из дампа
- Вкладка «Моды» сканирует в фоне и предупреждает о проблемах до запуска
Уже в Steam Workshop — обновится само. Через лаунчер прилетит автоматически. Всё, что сделано с 29 августа, одним релизом. Bannerlord 1.2 / 1.3.15 / 1.4.x — одна установка на все версии.
⚠️ Сначала о нашем собственном баге
На Bannerlord 1.2.10 Доктор сам ломал расчёт жалованья. Защита, поставленная в главном меню, запускала кусок кода игры слишком рано — игра запоминала сбой навсегда, и жалованье каждого отряда читалось как ноль до перезапуска. А мод при этом считал последствия как 94 332 «предотвращённых вылета». Чистая 1.2.10 с одним Harmony и Доктором; без Доктора всё было в порядке.
Починено на уровне устройства мода: так рано защиты больше не ставятся вообще, и это стережёт отдельный тест. Такой сбой теперь сообщается один раз и честными словами — не «предотвращён вылет», а что сломано и до каких пор.
Ещё две правки в ту же сторону: защита меню столкновения больше не крутится в петле (в одном логе — 3 223 срабатывания за две минуты, каждое считалось спасением; теперь повтор распознаётся и сообщается один раз), а две защиты, глотавшие любую ошибку, заявляют предотвращённый вылет только для своей.
🛡 Девять новых защит
Включены по умолчанию, у каждой свой выключатель на вкладке «Фиксы крашей».
- Смена дня из-за предмета с категорией из прошлой кампании. Раз в сутки игра продаёт товары с рынков и ищет категорию каждого предмета в таблице спроса, не проверяя, что строка есть. Строки нет ровно у одного вида предметов — тех, что мод придержал из предыдущей кампании в том же запуске игры. Совет, закрывающий весь класс: перезапускайте игру перед загрузкой сейва.
- Первая волна подкреплений, когда мод добавил команду после начала боя. Планы расстановки строятся один раз в начале боя, а на каждой волне ищутся вживую — у поздней команды плана нет, и игра падает на ней каждый тик. Защита достраивает план так же, как построила бы сама игра.
- Значок знамени над бойцами с общим знаменем. Игра ищет материал в кэше по одной текстуре, а сохраняет под другой; группа с общим знаменем (например, расстановка на осаду) убивала тик.
- Отправка каравана торговцем — регрессия самой игры с морского обновления: четыре значения читаются без единой проверки. Вылет повторялся через минуту после каждой загрузки, потому что тот же торговец приходит каждый день.
- Поселение без клана-владельца. Добавленное в игру после создания сейва поселение остаётся бесхозным навсегда — вместе со своим ополчением, которое роняло карту каждый тик. Владельца защита не назначает: это сменило бы хозяина города посреди кампании.
- Казнь без палача (Bannerlord 1.5+). Метку «казнён, палач неизвестен» оставляет мод, казнящий героев без имени палача; система кровной вражды читает клан палача без проверки — вылет через секунды после каждой загрузки.
- Роды у родителя без данных о внешности. Прежняя защита подставляла значение первому читателю и оставляла объект битым — вылет переезжал на две строки ниже, откат сейва не помогал. Новая чинит семью целиком.
- Начало осады: состав, где счётчик числит бойцов, а список пуст. Такое оставляет мод, правящий составы в обход API. Счётчик пересчитывается по реальным записям, как при загрузке сейва.
- Текстура знамени, прилетевшая на броню, уничтоженную вместе с бойцом. Отменить фоновую отрисовку знамени в конце боя нечему, и первый вызов на мёртвой модели — нарушение доступа к памяти, которое никто не поймает. Защита не накладывает текстуру, когда боя уже нет, и ловит форму «посреди боя» (мод переодел бойца при спавне).
📄 Отчёт о вылете
- Свой расширенный стек: для каждого кадра — позиция внутри метода, ближайший вызов и владельцы всех патчей на этом методе. Это то, что отличает два одинаковых броска в одном методе. Сторонний сборщик отчётов больше не нужен.
- Нативные вылеты читаются из дампа: вердикт по упавшей библиотеке — драйвер видеокарты, оверлей (Steam / Discord / RTSS / Nahimic), звуковой движок или нативная DLL мода. Заодно выяснилось, почему это не работало раньше: мод сам удалял дамп, не читая.
- Папки вылетов сопоставляются с записью мода в любом часовом поясе — движок называет их по UTC, и вне UTC+0 запись со стеком к папке не цеплялась.
- Список модулей называет id модов, а не имена папок; отчёт перечисляет пары модов, объявленные авторами несовместимыми; войска с незагрузившимися данными называют виновный мод.
🔎 Вкладка «Моды»
- Сканирует в фоне с прогрессом и помнит результат, пока файлы не изменятся (раньше вешала игру на всё время анализа).
- Манифесты читаются так же, как их читает игра — заодно впервые заработала проверка файлов по хешу из базы совместимости.
- До запуска сообщаются: модуль, записанный в порядке загрузки дважды (убивает игру до меню), манифест, который игра не прочитает, перевод, стоящий выше своего мода, и пожелание автора по порядку загрузки, которому порядок противоречит.
- Игра больше не обвиняется в пропаже собственных DLL для PlayStation и Game Pass.
🧰 Интерфейс и мелочи
- Кнопка кэша шейдеров трогает только генерируемый кэш — никогда файлы игры или модов. Совет в диагнозе, который велел их удалять, переписан.
- Фикс, ждущий игровой сессии, показывается как «Отложен», а не «Не требуется».
- Длинные тексты (анализ сейва, подробности настройки) прокручиваются, а не сжимаются до нечитаемого кегля.
- Вкладка «Предотвращено» сворачивает повторы в одну строку и переключается вместе с языком.
- Окно «Что нового» появляется сразу, как построилось меню.
- Починены французские строки, которые молча падали в английский.
Вылет? Нажмите «Открыть папку» на карточке и пришлите оба файла: report.txt и crashdoctor_at_crash.log.
