2021-03-12 11:48:47
Сегодня я перескажу вам прекрасную история про двери и Half-Life — последнюю неделю в геймдев-твиттере только и разговоров, что о дверях.
Однажды разработчики Half-Life 2 решили добавить в игру VR (в 2012-13 годах, когда анонсировали первый Oculus Rift). Дело шло хорошо — оставалось только разобраться с компенсацией движения во время езды на машине, чтобы игрокам не становилось плохо.
Один из разработчиков по имени Том (автор треда) решил полностью пройти игру в VR, без скипов и читов, и посмотреть, как она играется. Выйдя из поезда, он пошел за охранником — помните тот сиквенс, где Барни ведет вас в комнату охраны в первый раз? Где-то в этот момент Барни должен постучать в дверь и ему должны открыть. На новом билде дверь открывалась и...закрывалась снова, а NPC оставались стоять на месте.
Скрипт, который ждал полного открытия двери, не срабатывал. А скрипта, чтобы она открылась второй раз, не было. В чем же могла быть проблема? Может что-то с физикой или скриптами? Том задумался: скорее всего изменения в рендере что-то сломали. Начался бинарный поиск проблемы — реверт всех изменений, накатывание половины изменений, тестирование и т.д. В какой-то момент Том ожидал, что найдет тот самый чейндж, сломавший игру (не самый эффективный способ отладки, но все мы так делали хоть раз).
Но даже со всеми откатанными изменениями ванильный билд Half-Life все еще содержал этот странный баг с дверью. Как такое может быть? В нее же играли миллионы людей — как это могло пройти мимо? Никак. Теперь это стало багом в категории «Да как это вообще раньше работало?».
Том решил спросить тех, кто писал оригинальный код — и все они растерялись, и тоже начали свои расследования.
Выяснилось, что проблема была не в коде, а в... компиляторе. Оказывается, что Том компилировал старый код новым компилятором. Старый компилятор использовал 8087 (такой набор инструкций) для обработки математических вычислений, а новый — SSE. Оба набора инструкций использовали разную точность для вычислений, но почему это вообще спровоцировало баг?
Когда дверь в этой сцене открывается охранником, она становится физическим объектом и, доходя до финальной точки, лочится (и физика на ней больше не обрабатывается). Но охранник, который открывал дверь изнутри, стоял недостаточно далеко от нее, и самый дальний уголок его bounding box касался края двери (и, соответственно, происходила коллизия).
В x87-версии билда у двери хватает массы, чтобы оттолкнуть охранника и прокрутить его, чтобы дверь смогла открыться и залочиться. Но в SSE-версии билда математические расчеты говорят «Нет, у тебя нет такой массы, закрывайся обратно».
Такая вот поучительная и интересная история. Том же вывел из этого свою собственную мораль: «Doors suck. Even old reliable doors that have been working for decades suck. Friends don't let friends implement doors».
314 views08:48