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
Antes de tentar otimizar um jogo com o objetivo de fazê-lo rodar com uma taxa de quadros alta e estável, você precisa saber onde estão os gargalos. O que realmente consome a maior parte do tempo em um frame do seu jogo? É a renderização? É a lógica do jogo? É o grafo de cena? Para descobrir isso, recomenda-se usar as ferramentas de profiling integradas. Use o perfilador na tela ou web para amostrar o desempenho do seu jogo e então decidir se deve otimizar e o que otimizar. Depois de entender melhor o que consome tempo, você pode começar a tratar os problemas.
Reduzir o tempo de execução de scripts é necessário se o perfilador mostrar valores altos para o escopo Script. Como regra geral, é claro que você deve tentar executar o mínimo de código possível a cada frame. Executar muito código em update() e on_input() a cada frame provavelmente impactará o desempenho do seu jogo, especialmente em dispositivos de baixo desempenho. Algumas diretrizes:
Não faça polling por mudanças se você puder receber um callback. Não anime algo manualmente nem execute uma tarefa que possa ser entregue à engine (por exemplo, go.animate() em vez de animar algo manualmente).
Se você cria muitos objetos de vida curta, como tabelas Lua, a cada frame, isso acabará acionando o coletor de lixo do Lua. Quando isso acontece, pode se manifestar como pequenas travadas/picos no tempo de frame. Reutilize tabelas sempre que possível e tente realmente evitar criar tabelas Lua dentro de loops e construções semelhantes.
Se você lida com muitas mensagens ou tem muitos eventos de entrada para tratar, é recomendado pré-calcular os hashes das strings. Considere este trecho de código:
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
No cenário acima, a string com hash seria recriada toda vez que uma mensagem fosse recebida. Isso pode ser melhorado criando as strings com hash uma vez e usando as versões com hash ao tratar mensagens:
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
A passagem de mensagens, ou outras formas de endereçar um objeto de jogo ou componente, pode ser feita fornecendo um id como string ou hash, ou como uma URL. Se uma string ou hash for usado, internamente ele será traduzido para uma URL. Portanto, é recomendado fazer cache das URLs usadas com frequência para obter o melhor desempenho possível do sistema. Considere o seguinte:
local pos = go.get_position("enemy")
local pos = go.get_position(hash("enemy"))
local pos = go.get_position(msg.url("enemy"))
-- faz algo com pos
Em todos os três casos, a posição de um objeto de jogo com id enemy seria obtida. No primeiro e no segundo caso, o id (string ou hash) seria convertido em uma URL antes de ser usado. Isso nos diz que é melhor fazer cache de URLs e usar a versão em cache para obter o melhor desempenho possível:
function init(self)
self.enemy_url = msg.url("enemy")
end
function update(self, dt)
local pos = go.get_position(self.enemy_url)
-- faz algo com pos
end
Reduzir o tempo necessário para renderizar um frame é necessário se o perfilador mostrar valores altos nos escopos Render e Render Script. Há várias coisas a considerar ao tentar reduzir o tempo necessário para renderizar um frame:
builtins/materials) e reduzir a precisão dos shaders para ganhar alguma velocidade em dispositivos de baixo desempenho. Todos os shaders usam precisão highp, e uma mudança para, por exemplo, mediump pode em alguns casos melhorar ligeiramente o desempenho.Reduzir a complexidade do grafo de cena é necessário se o perfilador mostrar valores altos no escopo GameObject e, mais especificamente, na amostra UpdateTransform. Algumas ações a tomar:
disable ou enable para cada objeto de jogo.O script de renderização pode ignorar automaticamente a renderização de componentes de objetos de jogo que estejam fora de uma caixa delimitadora definida (frustum). Saiba mais sobre Frustum Culling no manual do Pipeline de Renderização.
Android Dynamic Performance Framework é um conjunto de APIs que permite que jogos interajam mais diretamente com os sistemas de energia e temperatura dos dispositivos Android. É possível monitorar o comportamento dinâmico em sistemas Android e otimizar o desempenho do jogo em um nível sustentável que não superaqueça os dispositivos. Use a extensão Android Dynamic Performance Framework para monitorar e otimizar o desempenho do seu jogo Defold em dispositivos Android.