ALAO
ALAO (Anomaly Lua Auto Optimizer) — попытка сумрачных гениев моддинга заставить S.T.A.L.K.E.R. работать быстрее, чем слайд-шоу на бабушкином калькуляторе. Представляет собой написанную на богомерзком Питоне утилиту, которая берет ваши (или чужие, что вероятнее) кривые скрипты, разбирает их на атомы через AST (абстрактное синтаксическое дерево), ужасается увиденному и пересобирает обратно, но уже с претензией на оптимизацию.
Суть проблемы[править]
Как известно, движок X-Ray — это памятник человеческому упорству и архитектурному безумию. Скриптовая часть там крутится на Lua, и если ванильные скрипты писались людьми, которые хотя бы слышали слово алгоритм, то народное творчество в сборках вроде Anomaly или GAMMA (где количество модов перевалило за 600) напоминает Вавилонскую башню из костылей и синей изоленты.
Васян-моддер, желая добавить в игру фичу пердеж с подливой при ранении, пишет код, от которого у Гарбодж Коллектора (сборщика мусора) случается инфаркт. Он создает строки в циклах, дергает глобальные функции по сто раз в секунду и использует `table.insert` там, где это нафиг не нужно. Результат предсказуем: микрофризы, статтеры и FPS, стремящийся к отрицательным величинам. ALAO призвана бороться именно с этим дерьмом, не заставляя автора мода учить матчасть.
Внутренности[править]
В отличие от примитивных найди и замени регекспами, которые ломают код в 50 % случаев, сабж работает по-взрослому. Он парсит код в дерево (AST), понимает контекст, области видимости и структуру блоков. Это позволяет проводить хирургические вмешательства без риска превратить скрипт в тыкву (хотя бэкапы делать все равно надо, ибо safety first).
Инструмент проходится по файлам и ищет паттерны, за которые в приличных компаниях бьют линейкой по рукам:
- Оптимизация таблиц
Вместо каноничного, но медленного вызова функции вставки:
table.insert(t, v)
Инструмент заменяет это на прямой доступ к памяти через индекс, что для LuaJIT является манной небесной:
t[#t+1] = v
Разница в скорости на больших объемах данных может достигать космических масштабов, так как мы избавляемся от оверхеда вызова функции.
- Математика для самых маленьких
Многие любители скриптов обожают использовать `math.pow(x, 2)` для возведения в квадрат, потому что в школе так учили. ALAO, хихикая в кулак, меняет это на банальное `x*x`. То же самое касается кубов и квадратных корней (`x^0.5` превращается в православный `math.sqrt(x)`). Процессор говорит спасибо.
- Глобальный кэш
Если в функции десять раз вызывается `math.floor` или, упаси Монолит, `db.actor`, то каждый раз виртуальная машина лезет в глобальную таблицу искать эту переменную. ALAO видит это непотребство и создает локальную переменную в начале блока:
local floor = math.floor
...
x = floor(y)
Это снижает нагрузку на лукап переменных, что в горячих циклах (вроде `actor_on_update`) дает прирост производительности.
- Экспериментальный угар
Для самых смелых есть флаг `--experimental`. Он включает режим берсерка и лезет исправлять конкатенацию строк в циклах. Вместо того чтобы порождать миллион временных строковых объектов, забивая память мусором:
local s = ""
for i=1,100 do s = s .. "a" end
Код превращается в элегантное создание таблицы с последующей склейкой:
local parts = {}
for i=1,100 do parts[#parts+1] = "a" end
local s = table.concat(parts)
Это снижает сложность алгоритма с квадратичной до линейной. ГК отдыхает, фризы пропадают.
Борьба с вылетами[править]
Отдельной строкой идет фича `--fix-nil`. В Сталкере половина вылетов происходит из-за того, что скрипт пытается дернуть метод у объекта, который уже ушел в астрал (стал `nil`). ALAO умеет автоматически оборачивать такие вызовы в проверки:
local obj = level.object_by_id(id)
if obj then -- ALAO заботливо добавил эту проверку
obj:set_visual("stalker_hero_3")
end
Производительность это не сажает (проверка на `nil` в процессоре стоит копейки), зато количество CTD (Crash To Desktop) уменьшается в разы.
Как этим пользоваться[править]
Поскольку целевая аудитория — люди, способные хотя бы запустить консоль, графического интерфейса не завезли. Все делается через командную строку, как в старые добрые времена. Для работы нужен Python 3.8+ и пара библиотек.
Запуск выглядит примерно так:
python stalker_lua_lint.py "C:\Games\Anomaly\gamedata\scripts" --fix --fix-yellow --cache-threshold 3
Ключи говорят сами за себя: `--fix` правит безопасные вещи, `--fix-yellow` лезет туда, где нужен глаз да глаз, а `--fix-debug` выпиливает (комментирует) тонны отладочного мусора вроде `printf` и `log`, которые моддеры забыли убрать и которые засирают лог и диск.
Утилита параноидальна и по дефолту делает бэкапы (`.alao-bak`) рядом с каждым файлом. Есть даже опция `--backup-all-scripts`, пакующая всё в архив перед началом экзекуции, чтобы потом не было мучительно больно за бесцельно прожитые часы отладки.
Итог[править]
Это костыль. Но это высокотехнологичный, титановый костыль с гидравликой и подсветкой, который позволяет хромому движку X-Ray бежать марафон чуть бодрее. Чудес ждать не стоит: если мод написан ногами, растущими из тазобедренного сустава, никакая AST-оптимизация не превратит его в конфетку. Однако, снять лишнюю нагрузку с процессора и убрать микрофризы при подгрузке алайфа утилита вполне способна. Автор (Priler) заслужил свою банку тушенки.
Ссылки[править]
- github.com/Priler/anomaly_alao — исходники, гайды и кнопка скачать для самых маленьких.