This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Перш ніж оптимізувати гру, щоб вона працювала зі стабільно високою частотою кадрів, потрібно знати, де її вузькі місця. Що насправді займає найбільше часу в кадрі вашої гри? Рендеринг? Ігрова логіка? Граф сцени? Щоб з’ясувати це, рекомендовано використовувати вбудовані інструменти профілювання. Скористайтеся екранним або вебпрофайлером, щоб виміряти продуктивність гри, а потім вирішити, чи потрібна оптимізація та що саме оптимізувати. Коли ви краще зрозумієте, на що витрачається час, можна починати розв’язувати проблеми.
Скорочувати час виконання скриптів потрібно, якщо профайлер показує високі значення в області Script. Загалом, звісно, слід намагатися виконувати якомога менше коду в кожному кадрі. Виконання великого обсягу коду в update() та on_input() у кожному кадрі, імовірно, впливатиме на продуктивність гри, особливо на малопотужних пристроях. Ось кілька рекомендацій:
Не перевіряйте постійно наявність змін, якщо можете отримати зворотний виклик. Не анімуйте щось вручну й не виконуйте завдання, яке можна доручити рушію (наприклад, використовуйте go.animate)() замість анімації вручну).
Якщо ви створюєте багато об’єктів із коротким часом існування, як-от таблиць Lua, у кожному кадрі, це зрештою запустить збирач сміття Lua. Це може проявлятися як невеликі затримки/стрибки часу кадру. Повторно використовуйте таблиці, де це можливо, і намагайтеся уникати створення таблиць Lua всередині циклів та подібних конструкцій.
Якщо ви обробляєте багато повідомлень або подій введення, рекомендовано заздалегідь хешувати рядки. Розгляньте цей фрагмент коду:
function on_message(self, message_id, message, sender)
if message_id == hash("message1") then
msg.post(sender, hash("message3"))
elseif message_id == hash("message2") then
msg.post(sender, hash("message4"))
end
end
У наведеному прикладі хешований рядок створюватиметься заново щоразу, коли надходить повідомлення. Це можна поліпшити, створивши хешовані рядки один раз і використовуючи їхні хешовані версії під час обробки повідомлень:
local MESSAGE1 = hash("message1")
local MESSAGE2 = hash("message2")
local MESSAGE3 = hash("message3")
local MESSAGE4 = hash("message4")
function on_message(self, message_id, message, sender)
if message_id == MESSAGE1 then
msg.post(sender, MESSAGE3)
elseif message_id == MESSAGE2 then
msg.post(sender, MESSAGE4)
end
end
Передавати повідомлення або в інший спосіб адресувати ігровий об’єкт (game object) чи компонент (component) можна, задавши ідентифікатор як рядок, хеш або URL. Якщо використано рядок чи хеш, усередині рушія його буде перетворено на URL. Тому рекомендовано кешувати URL, які використовуються часто, щоб досягти якнайкращої продуктивності системи. Розгляньте такий приклад:
local pos = go.get_position("enemy")
local pos = go.get_position(hash("enemy"))
local pos = go.get_position(msg.url("enemy"))
-- do something with pos
У всіх трьох випадках буде отримано позицію ігрового об’єкта з ідентифікатором enemy. У першому та другому випадках ідентифікатор (рядок або хеш) перед використанням буде перетворено на URL. Отже, для якнайкращої продуктивності краще кешувати URL і використовувати кешовану версію:
function init(self)
self.enemy_url = msg.url("enemy")
end
function update(self, dt)
local pos = go.get_position(self.enemy_url)
-- do something with pos
end
Скорочувати час рендерингу кадру потрібно, якщо профайлер показує високі значення в областях Render і Render Script. Ось кілька речей, які варто врахувати, коли ви намагаєтеся скоротити час рендерингу кадру:
builtins/materials), і вибрати нижчу точність там, де шейдеру не потрібна highp. У кроскомпільованих шейдерах GLSL ES для значень із рухомою крапкою за замовчуванням використовується mediump, а для цілих чисел — highp; ці значення за замовчуванням можна змінити в розділі Shader налаштувань проєкту. Явно задані кваліфікатори для окремих змінних мають пріоритет. Див. документацію про точність шейдерів.Зменшувати складність графа сцени потрібно, якщо профайлер показує високі значення в області GameObject, а точніше — для вимірювання UpdateTransform. Ось що можна зробити:
disable або enable кожному ігровому об’єкту.Скрипт рендерингу може автоматично пропускати рендеринг компонентів ігрових об’єктів, які перебувають за межами визначеного обмежувального паралелепіпеда (піраміди видимості). Докладніше про відсікання за пірамідою видимості (frustum culling) читайте в посібнику з конвеєра рендерингу.
Android Dynamic Performance Framework — це набір API, які дають змогу іграм безпосередніше взаємодіяти із системами керування живленням і температурою пристроїв Android. Можна відстежувати динамічну поведінку систем Android та оптимізувати продуктивність гри на рівні, який можна підтримувати тривалий час без перегрівання пристроїв. Використовуйте розширення Android Dynamic Performance Framework, щоб відстежувати й оптимізувати продуктивність вашої гри на Defold для пристроїв Android.