27 June 2020

Loading, please wait...

Довелось мне малость поиграть в XCOM 2 на Switch, в игру, которая была портирована на платформу с очень серьезными проблемами в области производительности. Сам по себе жанр -- пошаговая тактика -- штука вроде как весьма толерантная к скорости работы, но в случае XCOM 2 дела обстоят настолько плохо, что желание разбить консоль о стену возникает даже у самых терпеливых игроков.

Одна из замеченных мною проблем игры -- неприлично длинное время загрузки сохранений. Вот ты играешь, сохраняешься, делаешь пару ходов, где-то ошибаешься или что-то идет сильно не так, и ты хочешь загрузить save, которой откатит состояние текущий миссии на несколько шагов назад. Простая же вещь, но игрок сидит и больше минуты наслаждается экраном загрузки, вспоминая бесцельно прожитые годы.


Оставим в стороне вопрос этики -- мол, разве честно играть в таком стиле, постоянно перезапуская уровень для того, чтобы добиваться нужных тебе результатов? Мне хочется поговорить о технических аспектах такого вот неприятного поведения.
У меня имеются следующие соображения (и я полагаю, что они работают для абсолютного большинства современных игр): если заглянуть в оперативную память игры во время ее работы, то минимум 95% занятого объема будут составлять ассеты, загруженные с диска, и очень малую часть будет занимать текущее состояние игры. Под ассетами я понимаю любые ресурсы, загруженные с диска -- карта уровня, модели, текстуры, звуки etc., причем очевидно, что иногда эти ресурсы неким образом трансформируются перед загрузкой в память (например, декомпрессируются).
Если бы формат сохранений для игры типа XCOM 2 делали бы рукастые ребята из 90-х, полагаю, что они полное состоянии текущего уровня вполне могли бы уложить в пару килобайт (экипировка и статус полдюжины спецназовцев, статус пары десятков пришельцев-врагов, плюс некий статус триггеров и скриптов на уровне). Окей, давайте тоже самое проделают намного менее рукастые программисты XXI века, но даже если они это будет делать сильно не оптимально, разумеется, с обильным применением формата JSON, очень вряд ли они получат объем данных, превышающий мегабайт. И если бы архитектура игры с самого начала была бы написана оптимальным образом, то при загрузке другого состояния для текущего уровня (т.е. мы говорим о ситуации, когда абсолютное большинство статичных данных уровня УЖЕ находится в памяти) вряд ли требовалось бы больше пары секунд. Разумеется, при этом я учитываю и некие временные данные, которые нужны для работы, но которые не являются частью формата сохранения, и я понимаю, что нужно восстанавливать связи между желаемым состоянием уровня и пребывающим в памяти тем самым набором статических ресурсов, которые мы не трогали для ускорения загрузки.


***

Единственный известный мне способ выпускать хорошо оптимизированные игры -- закладывать правильный набор требований в области производительности на самых ранних этапах разработки, а потом неукоснительно следить за их соблюдением.
Обычно на этих самых ранних этапах зарождения практически любого программного продукта у создателей болит голова за вопросы выбора инструментов, библиотек и фреймворков, которые, в первую очередь, должны позволять максимально быстро получать результаты, делать быстрые итерации продукта, чтобы как можно раньше понимать, в правильную ли сторону этот продукт движется, какие идеи в нем хорошо работают, а какие -- не очень. Если на этом этапе выбранные технологии не проходят жесткий отбор с точки зрения требований к производительности получаемого с их помощью продукта, то в релиз уходит программа, которая требует максимально производительного железа и даже на нем не демонстрирует чудес быстродействия. Как известно, если программистов постоянно не бить по рукам, они даже самую примитивную программу напишут так, что она будет тормозить на топовых конфигурациях.

Я уже писал о проблемах игры Bloodstained, которую выпустили на Switch в совершенно удручающем виде. Для меня очевидно, что практически все время разработка велась под "большие" платформы, а когда за пару месяцев до релиза кто-то сказал "а чо, может давайте соберем игру под Switch и глянем как она там работает?" оказалось уже слишком поздно что-то исправить. Да, вы можете на этапе финальных оптимизаций выжать дополнительные 20-30% производительности, но когда вам нужно выжать 200-300% все заканчивается тем, что 60 fps игра становится 30 fps игрой и вместо Full HD вы активируете динамическое разрешение, которое стабильно загоняет игру в 480p, известное как "ну здравствуй мыло!".
Уверен, что если бы на самых ранних этапах разработки Bloodstained программисты были бы поставлены в условия, что версия для Switch это обязательные Full HD и 60 fps, то так оно бы и было. Причем совсем не обязательно, что игра при этом выглядела бы сильно хуже текущей версии на "больших" платформах или сильно дольше бы разрабатывалась.

Когда имеешь дело с продуктом, в котором нужные приоритеты были правильно выставлены с самого начала, это видно сразу. Посмотрите вон, с какой скоростью грузятся save'ы в Doom Eternal!
А что касается XCOM 2... ну так он, блин, умудряется тормозить даже на топовых ПК с SSD диском.





No comments:

Post a Comment