– Придёт день, и вы столкнетесь с ситуацией, к которой окажетесь полностью неподготовлены как физически, так и эмоциально. Тогда вы и узнаете, какие из вас врачи, насколько вы подвержены страху и как хорошо вы выучились.
Лекция одного преподавателя на Риннале
Джо Шрайбер, "Звёздные Войны: Солдаты Смерти"





Сколько глобус ни крути, там Fess-Style не найти...
Сайт Fess'a » ОПТИМИЗАЦИЯ - нафиг? - Форум
[ Новые сообщения · Участники · Правила форума · Поиск ]
  • Страница 1 из 1
  • 1
Форум » Форум Редакторов » Редактор ARMA » ОПТИМИЗАЦИЯ - нафиг?
ОПТИМИЗАЦИЯ - нафиг?
FessДата: Среда, 13.11.2013, 23:40 | Сообщение # 1

Добрый админ
Сообщений: 2339
Статус:
В чем разница?

Честно говоря, данную тему стоит начать с простого вопроса: в чем разница между хорошим программистом (а если вы пишете скрипты для редактора ARMA, то вы тоже, в какой-то степени, программист) и плохим программистом?

Не буду загадывать вам загадки и сразу выдам ответ: хороший программист сможет написать такой алгоритм, который будет работать в несколько... миллионов раз быстрее. Как так? А вот. Оптимизация.

Ладно, отбросим абстрактные размышления в сторону и давайте сразу подумаем, где нам может пригодится оптимизация в редакторе ArmA? Я более чем уверен, что большинство скриптов, которые вы пишите (я надеюсь, что вы пишите, вы ведь пишите, правда?), довольно простые, и компьютер с ними справляется на ура.

Очень плохие вещи в ваших скриптах

Например, я недавно писал скрипт, который превращает обычную гранату в очень мощную. Сейчас я напишу слабые места этого скрипта.

Во-первых, это EventHandler. Для тех кто не знает, объясняю на пальцах - это такой цикл, который проверяет, не совершил ли объект, на котором висит хэндлер, определенного действия.

[ Пофантазируем. Пусть процессору надо узнать, что вы чихнули. Чтобы это узнать, процессор будет задавать вам этот вопрос примерно 75 раз в секунду. "Вы чихнули? Нет? А сейчас? ... А сейчас?". Естественно, что в определенный момент вы все же чихнете, и процессор узнает об этом. Примерно так же работают хендлеры. ]

Я повесил хэндлер типа "FIRED", то есть "определенное действие" в данном случае - это выстрел или бросок гранаты. При обнаружении определенного действия хэндлер обращается к специальной процедуре execVM, которая в свою очередь вызывает .sqf скрипт. Это если разжевывать.

player addEventHandler ["Fired", {as = [_this] execVM "granata.sqf";}];

Как видим, действий выполняется достаточно много, да еще и в цикле. Запомните: циклы - это плохо. Но в этот раз я использовал цикл - и все хорошо, FPS не упал, игра работает плавно, граната взрывается, норм. То есть один цикл\эвентхандлер - это не смертельно.

А теперь приведу такой пример из практики.

Делал я как-то зомби-миссию с радиацией, торговлей, аптечками - все дела. При этом на каждом зомби у меня висело по хендлеру с условием "УБИТ" - ибо по задумке за каждого убитого зомби игроку начислялись деньги, которые он мог потратить на патроны\оружие т.д. Почему так делал - потому что хендлер типа "УБИТ" имеет возвращаемое значение "убийца", т.е. я проверял условие < if (убийца == игрок) > и если да, то тогда начислял деньги.

Все вроде круто. А теперь представьте - у меня 140 зомби на карте. Естественно вдруг РЕЗКО проседает FPS (со 120 до 18), а все потому, что огромное количество эвентхандлеров бомбят процессор бессмысленными запросами, в итоге проц не справляется, создаётся большая очередь команд, как следствие, падение FPS и заторможенная работа скриптов. Например, убиваешь зомби, а хендлер срабатывает только спустя 10 секунд. Представьте, какая очередь была, ведь проц. способен обрабатывать миллионы операций в секунду!

Какой из этого можно сделать вывод? Первый: эвентхандлеры - это плохо. Второй: такой способ никуда не годится, реализовывать подсчет нужно как-то по-другому. Но как?

Немного оптимизируем

Самый простой вариант: давайте не будем вешать хендлеры на каждого зомби, а будем реализовывать подсчет через массив allUnits, при этом будем обращаться не один раз за фрейм (то есть 75 раз в секунду, если у вас в игре 75 FPS), а один раз в СЕКУНДУ. Ведь, в сущности, нам не важно, чтобы деньги начислялись на счет именно в момент прохождения пули сквозь череп бедного зомби.

Код
_price = 10; // пусть цена одного зомби будет $10
player_balance = 0; // это начальный баланс игрока, обратите внимание, написал без черточки _

while {true} do       
{
         _before = {alive _x && _x == "ЗОМБИ"} count allUnits;       
         sleep 1;
         _after = {alive _x && _x == "ЗОМБИ"} count allUnits;

         if(_before != _after) then       
         {
            player_balance = player_balance + _price*abs(_before - _after); // иначе говоря прибавляем кол-во убитых умноженное на цену одного зомби
         };
};


Так как этот скрипт в ДЕСЯТКИ раз меньше загружает процессор (при 140 зомби у вас было бы не 140, а >10500 обращений в секунду), вы освободите ему приличное количество времени, чтобы он попинал балду. Кстати, на освобожденные ресурсы вы сможете заспавнить еще зомби.

Теперь проблемы. Этот скрипт сработает в случае смерти зомби, не обязательно от рук игрока. То есть если бедняга где-то на краю карты упадет со скалы вниз головой в море - денежки придут к игроку на счет. Фигня, а неприятно, правда? Ну да ладно, игра стоит свеч.

Хорошо, про это поговорили. Теперь реально полезный совет.

Зачем ставить статус: нет?

Когда вы ставили юнитов в редакторе, вы ведь видели там где-то строчку СТАТУС: В СТРОЮ ? И вероятно, даже знаете, за что она отвечает? Ну если не знаете, то статус "В ПОЛЕТЕ" ставить нужно вертолетам, если вы хотите, чтобы они появились сразу в воздухе; статус "В СТРОЮ" стоит ставить тогда, когда вам надо, чтобы юниты отряда появлялись не так, как вы их расставили, а согласно позициям в построении "КЛИН". Короче говоря при запуске миссии они сразу будут стоять клином, даже если вы их по-другому ставили. Чтобы этого не было - ставьте "СТАТУС: НЕТ", тогда они появятся на нужных местах, (но после этого все равно клином построятся).

Так вот. А вы видели, что у неодушевленных предметов эта строчка тоже имеется, причем по умолчанию там В СТРОЮ? Обычно люди так и оставляют, не обращая на нее внимания. А игра тем временем старательно просчитывает место, который данный чайник должен занять в своем собственном построении клином. На это у процессора уходят что? Правильно, силы и нервы, то есть операции в секунду.

А если у вас вся карта заполнена такими объектами? Например, вы решили построить стену, продублировав один большой мешок с песком <высота_стены * длинна_стены> раз? например стена 3*10 - это уже тридцать мешков. Тридцать пузатых ворюг сил вашего процессора.

То есть суть мысли в том, что у неодушевленных предметов ставьте "НЕТ" - так вы сэкономите ресурсы. А чем больше у проца ресурсов, тем лучше для вас - это сказывается еще как на скорости работы скриптов, так и на FPS.
 
FessДата: Среда, 13.11.2013, 23:54 | Сообщение # 2

Добрый админ
Сообщений: 2339
Статус:
Со временем, может быть, допишу эту статью, а вот - выучите английский и прочитайте http://community.bistudio.com/wiki/Code_Optimisation .
 
Форум » Форум Редакторов » Редактор ARMA » ОПТИМИЗАЦИЯ - нафиг?
  • Страница 1 из 1
  • 1
Поиск: