Оптимизация кода на Lua для мобильных игр

Как сделать игру на Lua быстрой и плавной? Разбираем основные приёмы оптимизации кода для мобильных устройств.

РазработкаLua

6 мин

Мобильные устройства ограничены по CPU/GPU и памяти. Поэтому скриптовая логика на Lua должна быть предельно лёгкой: минимум аллокаций, меньше работы в каждом кадре, разумная работа со строками и таблицами, бережное отношение к сборщику мусора (GC). Ниже — «скелет» оптимизаций, с которых стоит начать.

1. Профилируем, а не гадаем 🧭

Измеряйте, где теряется время кадра: используйте профайлер вашего движка (Defold, Solar2D/Corona и др.) и внутренние таймеры. Определите горячие функции и оптимизируйте их в первую очередь.

local clock = os.clock
local function bench(fn, iters)
  local t0 = clock()
  for i=1,iters do fn() end
  return (clock()-t0)*1000
end
print("ms:", bench(updateEnemies, 1000))

2. Работа с памятью и GC 🧹

  • Переиспользуйте таблицы вместо частого создания новых.

  • Избегайте аллокаций в update() и коллизиях.

  • Соберите «пулы объектов» (entity pooling) для снарядов/частиц.

-- Пул на таблицах
local pool = {}
local function acquire()
  return table.remove(pool) or {x=0,y=0,vx=0,vy=0,alive=false}
end
local function release(obj)
  obj.alive=false; obj.x=0; obj.y=0; obj.vx=0; obj.vy=0
  pool[#pool+1]=obj
end

3. Быстрые переменные и модули ⚙️

  • locals быстрее globals: кэшируйте часто используемые функции.

  • Сохраняйте ссылки на функции модулей в локальные переменные.

-- Было (медленнее из-за глобальных поисков):
function tick(dt) math.sin(dt); math.cos(dt) end

-- Стало (быстрее благодаря локальным ссылкам):
local sin, cos = math.sin, math.cos
function tick(dt) sin(dt); cos(dt) end

4. Строки и конкатенация 🧵

Строки неизменяемы: каждая конкатенация создаёт новую строку. Накапливайте части в таблице и используйте table.concat.

-- Плохо:
local s = ""
for i=1,1000 do s = s .. i end

-- Хорошо:
local t = {}
for i=1,1000 do t[i]=i end
local s = table.concat(t, ",")

5. Циклы и итераторы 🔁

  • Предпочитайте числовой for там, где это возможно.

  • ipairs удобен, но числовой for i=1,#t зачастую быстрее.

  • pairs оставьте для ассоциативных таблиц и не в горячих местах.

-- Быстро:
for i=1,#arr do local v = arr[i]; -- обработка end

6. Метатаблицы и ООП 💼

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

ТОП ошибок начинающих разработчиков Lua

Ошибка ❌

Почему плохо 🐌

Как исправить ✅

Создание новых таблиц каждый кадр

GC-спайки, микролаги

Пул объектов, очистка и переиспользование

Конкатенация строк в циклах

Много аллокаций

table.concat

Глобальные вместо локальных

Доступ медленнее

Кэшируйте в local

pairs в горячем коде

Непредсказуемый порядок/затраты

Числовой for и массивы

Тяжёлая логика в update()

Просадки FPS

Вынесите расчёты, разбейте задачи, кэшируйте

Подгрузка ассетов «на лету»

Фризы при I/O

Предварительная загрузка, атласы, стриминг аудио

Пример «до/после»

-- До: много мусора и глобальных обращений
function spawnBullets(n)
  for i=1,n do
    local b = {x=0,y=0,vx=0,vy=0,alive=true}
    table.insert(bullets, b)
  end
end

-- После: пулы + локальные ссылки
local insert = table.insert
function spawnBullets(n)
  for i=1,n do
    local b = acquire()  -- из пула
    b.alive=true; b.x=0; b.y=0; b.vx=0; b.vy=0
    insert(bullets, b)
  end
end

Оптимизация Lua на мобильных — это дисциплина: профилируем, исключаем лишние аллокации, кэшируем функции в local, аккуратно работаем со строками и циклами, используем пулы и атласы. Начните с измерений — и целенаправленно «снимайте» узкие места.

Кодик помогает прокачать навыки оптимизации: мини‑уроки, практические задачи, проверки и подсказки прямо в приложении.

А ещё у нас есть активный telegram-канал, где мы обсуждаем крутые идеи, делимся опытом и вместе разбираем задачи — учиться становится не только полезно, но и весело.

💬 Какой приём оптимизации дал вам самый заметный прирост FPS? Напишите коротко, какой кейс и какой выигрыш получили.

Комментарии