LEMBRE-SE DE NÃO DESPERDIÇAR SUA MEMÓRIA - tradução do post feito por Ashley

3

Stats

415 visits, 533 views

Tools

Translations

This tutorial hasn't been translated.

License

This tutorial is licensed under CC BY 4.0. Please refer to the license text if you wish to reuse, share or remix the content contained within this tutorial.

Published on 3 Oct, 2023.

Esse tutorial é apenas uma tradução do post feito por Ashley

Ocasionalmente, somos questionados coisas como "Eu quero fazer um jogo com níveis enormes, todos feitos de arte de azulejos desenhados exclusivamente. O Construct 2 pode lidar com isso?" Alternativamente, os usuários prosseguem projetando níveis com azulejos de alta resolução e, em seguida, descobrem que dispositivos móveis não conseguem lidar com isso. Em seguida, eles podem até acusar o Construct 2 de ter suporte fraco para dispositivos móveis porque não conseguem criar um jogo com todas essas imagens. Mas isso não é exatamente o caso!

Isso acontece com frequência suficiente para que eu ache que merece uma postagem de blog para abordar com mais detalhes. O Construct 2 é ótimo para pessoas não técnicas entrarem facilmente no design de jogos e facilita o processo de adicionar muito conteúdo ao seu jogo. No entanto, ainda é necessário conhecer os limites dos sistemas típicos de desktop e dispositivos móveis. Computadores não têm recursos infinitos, e você precisa projetar seu jogo de acordo com isso.

NENHUM FRAMEWORK PODE LIDAR COM ISSO

Se você planeja usar muitas imagens grandes, muitas vezes acontece que nenhum mecanismo ou framework pode lidar com isso. Isso está relacionado à quantidade de memória disponível, que é uma limitação de hardware. Mesmo que você escrevesse seu mecanismo de forma super eficiente em C++, provavelmente ainda não funcionaria. Vamos investigar por que isso acontece.

As imagens são compostas por pixels. Se pegarmos um azulejo de tamanho HD medindo 1920x1080 pixels, isso totaliza 2.073.600 pixels. É impressionante quando pensamos que os monitores de computador comumente têm esse número de pixels físicos!

Cada pixel em uma imagem ocupa quatro bytes para os canais de vermelho, verde, azul e alfa (permitindo 256 valores possíveis para cada canal). Para calcular o tamanho da imagem na memória, cada pixel ocupa quatro bytes, então multiplicamos o número de pixels por 4. Isso significa que nosso azulejo de 1920x1080 ocupa 2.073.600 x 4 = 8.294.400 bytes, ou cerca de 8 megabytes.

Também devo salientar que as imagens são totalmente descompactadas na memória. Se você tiver uma textura sólida preta de tamanho 1920x1080, ela provavelmente será salva em um pequeno arquivo PNG com apenas alguns kilobytes. Isso significa que ela faz o download rapidamente. No entanto, as imagens não podem ser renderizadas na tela a partir de um arquivo comprimido. Elas são descompactadas para o tamanho completo na memória para renderização, o que significa que seu arquivo PNG de 5 KB de preto sólido ainda ocupa cerca de 8 MB na memória. Portanto, mexer nos formatos de imagem, como usar PNG-8 ou JPEG em vez de PNG-32, afeta apenas o tamanho do download - não afeta o uso de memória.

Muitos sistemas móveis não suportam imagens que não tenham tamanho de potência de dois (por exemplo, 32x32, 64x64, 128x128...). Para contornar isso, as imagens serão colocadas na memória em uma textura de tamanho de potência de dois grande o suficiente para acomodá-las. Nesse caso, a imagem de 1920x1080 será colocada em uma textura de tamanho 2048x2048 na memória! Isso significa que ela usa 16 MB de memória - cerca de o dobro, em sistemas com limites de memória ainda mais apertados! O Construct 2 agrupa automaticamente imagens menores na exportação para economizar memória, mas imagens tão grandes não se beneficiam disso.

LIMITAÇÕES COMUNS DE COMPUTADORES DE MESA

"Qual é o problema?" você pergunta. "A maioria dos computadores tem 4 GB ou mais de memória hoje em dia." Isso é verdade, mas os dispositivos de mesa geralmente têm memória de vídeo separada (VRAM) para renderização. Para obter o máximo desempenho, todas as imagens devem ser capazes de caber na VRAM. Em alguns casos, o sistema pode colocar imagens na memória principal, mas isso é mais lento.

Uma placa de vídeo barata ou antiga pode ter 256 MB de VRAM. Isso significa que, para ainda obter o desempenho máximo, você pode encaixar um máximo de 32 de seus grandes azulejos na memória de vídeo e mais nada. Na realidade, você nem pode usar o tamanho total da memória, porque o sistema operacional estará usando parte dela para a exibição atual e outras aplicações também podem estar usando parte dela. E então não se esqueça de que você tem as imagens para o resto do seu jogo! Você só pode contar com talvez metade dessa memória, o que deixa espaço para apenas 16 azulejos.

Alguns sistemas novos e baratos não têm VRAM e usam exclusivamente a memória do sistema para as imagens. Isso não é necessariamente melhor. Geralmente é muito mais lento acessar imagens da memória principal, e o uso de muitos azulejos grandes é susceptível de sobrecarregar rapidamente o sistema e reduzir as taxas de quadros.

LIMITAÇÕES COMUNS DE DISPOSITIVOS MÓVEIS

Assim como nos sistemas de mesa mais baratos, a maioria dos dispositivos móveis não possui VRAM dedicada e usa a memória do sistema para tudo. Além disso, a memória do sistema geralmente também é limitada. É possível que um dispositivo móvel tenha apenas 60-100 MB de memória livre disponível. Devido à limitação de tamanho de potência de dois, é provável que cada azulejo realmente use 16 MB de memória. Supondo que seu jogo usará metade da memória livre para tudo que não são planos de fundo, você pode ter espaço para dois azulejos de plano de fundo, ou quatro se tiver sorte. Isso não é mais um nível muito grande!

Como espero que esteja começando a ficar óbvio, não há como você projetar realisticamente um jogo assim.

O MODO MELHOR: COMPOSIÇÃO

Na prática, ninguém desenvolve jogos com grandes azulejos de imagem - nem mesmo desenvolvedores profissionais. Seu artista pode querer desenhar níveis enormes e expansivos como imagens únicas gigantes, mas a realidade é que você não pode criar um jogo rápido que funcione em todos os lugares dessa forma.

Em vez disso, use planos de fundo com azulejos para cobrir grandes áreas com imagens repetidas. Em seguida, use sprites e outros planos de fundo com azulejos para cenários e decorações para quebrar a repetitividade. O Construct 2 permite dimensionar e girar arbitrariamente esses objetos, o que pode fazer muito para evitar uma aparência repetitiva. Por exemplo, uma grande pedra pode ser reutilizada como pequenas pedras; uma floresta pode ser feita apenas com três ou quatro tipos diferentes de árvores; montanhas distantes podem ser compostas pelos mesmos objetos que compõem o chão próximo; e se seu jogador tiver 20 armas, faça da arma um objeto separado posicionado pelo jogador para evitar ter que reanimar o jogador 20 vezes (o que usaria 20 vezes mais imagens). Essa reutilização de arte existente é a chave para jogos eficientes com baixo uso de memória - e é uma verdadeira arte em si mesma, poder compor mundos detalhados a partir de um pequeno conjunto de peças.

Se você tiver 10 planos de fundo com azulejos repetindo imagens de 512x512 e 30 sprites diferentes de decoração de 512x512, isso usará cerca de 40 MB de memória. Você provavelmente pode usar os mesmos objetos para criar vários níveis únicos, e ele ainda rodará mesmo nos telefones celulares com recursos mais limitados. Além disso, é provável que funcione com uma taxa de quadros muito melhor em sistemas de mesa com VRAM dedicada. Além disso, existem benefícios de jogabilidade, como a capacidade de criar e destruir partes dinamicamente ou animar partes do nível. Virtualmente todos os jogos projetados profissionalmente adotam essa abordagem.

EXEMPLO: RAYMAN ORIGINS

Aqui está um bom exemplo de reutilização de imagens em um jogo profissional. Eu peguei uma imagem de Yann nos fóruns (desculpe!) onde algumas imagens reutilizadas foram destacadas:

Yann fez apenas uma breve tentativa de destacar alguns exemplos óbvios, e se você olhar de perto, verá que há muito mais reutilização de imagens do que foi marcado. Yann também observou que não ficaria surpreso se as montanhas distantes reutilizassem algumas das imagens de grama do primeiro plano, e que níveis posteriores reutilizam algumas plantas com uma tonalidade (o que você pode fazer no Construct 2 com o efeito de sombreamento de tonalidade). Observe como escala, ângulo e sobreposição evitam uma aparência repetitiva, o que também é fácil de fazer na visualização de layout do Construct 2.

Eu acho que este é um jogo lindamente projetado, tanto artisticamente quanto tecnicamente. A impressão do nível é de uma cena de floresta orgânica e detalhada, mas olhando de perto, você pode ver muitas imagens reutilizadas para manter o uso de memória baixo. Também é fácil para os designers de níveis criar níveis muito mais longos e detalhados, uma vez que estender o nível não requer mais azulejos e mais memória. Ao animar ou mover objetos individuais (por exemplo, usando o comportamento Seno) e adicionar camadas de paralaxe, você pode criar ambientes cheios de vida e movimento - impossível de alcançar com azulejos pré-renderizados.

Isso é o que os profissionais fazem. Na verdade, minha opinião é que a reutilização de imagens quase certamente tornou Rayman um jogo melhor e mais emocionante, uma vez que eles não foram limitados pelas restrições de uso de memória e puderam projetar níveis expansivos e detalhados. Reutilizar imagens não significa que um jogo tenha que parecer repetitivo - provavelmente isso o torna ainda melhor!

UMA PALAVRA SOBRE O CARREGAMENTO DE TEXTURAS

No Construct 2, as imagens são carregadas layout por layout. Isso significa que, quando um layout começa, todos os objetos no layout são carregados imediatamente na memória. Isso é feito para evitar pausas no meio do jogo enquanto as texturas são carregadas sob demanda. Quando o layout termina, ele liberará todas as imagens na memória que não são usadas pelo próximo layout e carregará quaisquer novas imagens que o próximo layout usar. Isso significa que o uso máximo de memória do seu jogo é baseado apenas no layout com mais imagens, em vez de todas as imagens no projeto. Portanto, você pode ter algo como quatro "mundos" diferentes, por exemplo, floresta, neve, deserto e espaço, todos usando conjuntos diferentes de imagens - e o "mundo" da "neve" não fará com que os níveis da "floresta" usem mais memória.

O Construct 2 exibe uma estimativa de uso de memória na barra de status. Você deve ficar de olho nisso. A estimativa é baseada no uso de memória de imagem do layout maior, mais a memória usada por duas imagens do tamanho da janela (que provavelmente serão necessárias pelo sistema operacional ou pelo sistema de renderização do motor). Com uma boa reutilização de imagens, deve ser fácil manter isso abaixo de 60-80 MB.

SOBREDESENHO EM DISPOSITIVOS MÓVEIS

Já que estamos falando sobre limitações de dispositivos móveis, vale a pena mencionar que alguns dispositivos móveis só conseguem desenhar cada pixel na tela 3 vezes por quadro (frame) e ainda atingir 60 FPS. Em outras palavras, se você tiver quatro imagens do tamanho da janela na tela, não poderá atingir 60 FPS em um dispositivo assim. (Observe que o Construct 2 renderiza as cenas de trás para a frente, então quatro objetos sobrepostos ainda são todos renderizados.) Surpreendentemente, isso inclui pixels transparentes. A GPU processa o retângulo completo de uma textura, independentemente do conteúdo, e um pixel transparente ainda consome seu orçamento de desenho, portanto, quatro imagens transparentes do tamanho da janela ainda não atingiriam 60 FPS. Da mesma forma com o uso de memória, essa é uma limitação de hardware do dispositivo e você terá a mesma limitação com qualquer framework.

A solução aqui é novamente preferir o uso de imagens pequenas em vez de grandes. Uma imagem grande consumirá muito do orçamento de desenho do dispositivo móvel de uma só vez, enquanto é mais fácil para ele renderizar vários objetos menores espalhados. Por exemplo, um sprite do tamanho da janela para adicionar bordas ao redor da tela é muito ineficiente, já que os pixels transparentes no meio ainda consomem o orçamento de desenho; usar quatro sprites separados para cada borda da tela seria muito mais rápido.

CONCLUSÃO

Você precisa projetar jogos móveis com muito cuidado para aproveitar ao máximo o hardware muitas vezes muito limitado. Todos os bons desenvolvedores móveis fazem isso, mesmo ao escrever aplicativos nativos, usando todo tipo de truques inteligentes para evitar ter muitos objetos na tela ou imagens na memória enquanto ainda alcançam uma aparência visual semelhante. Você também deve ter cuidado com os jogos do Construct 2. Só porque o Construct 2 torna fácil arrastar e soltar muitas obras de arte não significa necessariamente que seja uma boa ideia.

Como sempre, você deve garantir que obtenha um dispositivo móvel semelhante ao que pretende usar para jogar o jogo e testar regularmente nele. Isso facilita muito a detecção de uma mudança específica que reduziu o desempenho ou usou muita memória e, em seguida, encontrar outra solução. Se você simplesmente portar um jogo de mesa completo para dispositivos móveis e ele não funcionar bem, terá um tempo muito difícil tentando descobrir exatamente qual é o problema.

O desenvolvimento de jogos em qualquer plataforma ou framework muitas vezes envolve truques e ilusões para obter o máximo benefício artístico com requisitos de hardware mínimos. Com o mesmo conhecimento e criatividade, você pode projetar jogos do Construct 2 da mesma maneira.

  • 0 Comments

Want to leave a comment? Login or Register an account!