group-telegram.com/hyperduh/1042
Last Update:
Прочитал про раскопки одного из самых странных багов в истории видеоигр – исчезновение гидроплана из GTA San Andreas после… обновления Windows 11 24H2? Как обновление винды смогло что-то поломать в игре двадцатилетней давности? Почему именно исчезающий гидроплан? На самом деле, это история про категории, самоисправление систем и строгость с любопытными перспективами.
Автор популярного семейства патчей для серии GTA – SilentPatch – примерно с октября 2024 года начал получать на гитхабе жалобы на “исчезнувший гидроплан” Skimmer. Исчез он только в San Andreas, вне зависимости от того, модфицировали игру или нет. Из исходных данных в анамнезе был только один общий факт – гидроплан всегда пропадал после установки обновления 24H2. Причем транспорт нельзя было заспавнить даже с помощью скриптов – скрипт срабатывает, но гидроплана не видно.
Тогда Silent использовал скрипт, чтобы заспавнить гидроплан и сразу посадить в него аватар игрока. Оказывается, самолет все же появлялся, просто на первом же кадре он взлетал на высоту в 1087 квадриллионов световых лет даже без включения двигателя (выходит, что в каком-то смысле гидроплан даже прокачался).
Silent детально описывает проблему (очень советую прочитать), я постараюсь упростить. Дело в том, что во время создания самолетов игра обращается к данным о размерах передних и задних колес...
Которых у гидроплана нет. И значений переменных под размер колес у гидроплана тоже нет.
В GTA эти параметры не задаются для лодок, и поэтому в Vice City с гидропланами нет проблем – они принадлежат классу лодок, а не самолетов. Но в San Andreas их перенесли именно в класс самолетов, у которых колеса уже должны быть. И если внести новые параметры колес в описание гидроплана ручками, ничего подозрительного в San Andreas не возникает. Но при чем тут Windows 11 и обновление, что именно ломается?
Если кратко, то раньше в игре пустые строки заполнялись автоматически самой игрой, и размер “колес” гидроплана менялся на 0.7. На Win11 24H2 – на невозможные числа: 7.84421263e+33 и 4.54809690e-38.
Проблема частично оказалась в самой Windows – в 24H2 изменилось стэковое пространство, занимаемое функционалом Critical Section Objects. Что это значит? В программном коде есть участки, называемые “критическими секциями” – они не могут быть использованы более чем одним потоком выполнения одновременно; другим потокам нужно подождать разблокировки. Код разблокировки критической секции — функция LeaveCriticalSection — в 24H2 занимает немного больше стэкового пространства.
В случае с San Andreas переменные, которые отвечали за размер колес, не попадали в критическую секцию кода, который спавнил гидроплан. Сам исполнительный файл видел пустоту в параметрах и выставлял значения для колес "по умолчанию", повторяя параметр от транспорта выше по файлу (грузовика Topfun с колесами на 0.7) – поэтому гидроплан спавнился нормально. "Нет данных по колесам гидроплана? Спишем с позиции выше".
Теперь же адреса, где должны быть данные по колесам, дают кучу мусора. Откуда берется мусор? На месте пустых данных "колес" теперь оказывается вызов "разросшейся" функции LeaveCriticalSection — вот и наш "новый размер". Сначала игра грузит объект — наш гидроплан — через функцию LoadVehicleObject, а после исполнения этой функции освобождает пространство для LeaveCriticalSection. Размеры у них схожие, вызов последней не переписывал значения "колес" по соседству. А теперь LeaveCriticalSection занимает больше места и куском влазит в пустоту неопределенных переменных. Этот кусок и превращается в размеры колес — в числа 7.84421263e+33 и 4.54809690e-38. На Xbox этот баг, кстати, тоже был, и Rockstar правили его патчем, "прописыв колеса"; но все компьютерные версии игры полагались на авось.
Полезных выводов из этой истории два. Во-первых, как советует автор, нужно валидировать данные и не надеяться, что ошибки сами исправятся стандартными значениями. Ну а во-вторых, чудо, что игры вообще запускаются.
UPD. На хабре есть перевод на русский.
BY Гипермда

Share with your friend now:
group-telegram.com/hyperduh/1042