Surgidos a mais ou menos três décadas, os jogos digitais - ou games para os íntimos - viraram uma febre mundial, ganhando lugar cativo na casa e nos corações de pessoas no mundo todo. Naturalmente, com o passar dos anos essa mídia passou por várias atualizações em seu formato, ficando cada dia mais bonita, mais realista e mais interessante, mas você sabia (ou lembra) que os games na verdade são softwares?
esqueceram-de-mim2
Eu sei, eu sei...Quando estamos em uma jornada épica em Journey, ou lutando com todas as forças para sobreviver em Uncharted, ou mesmo dormindo tranquilamente em um chão qualquer enquanto passarinhos pousam em “nosso” nariz italiano em Mario Odyssey, é difícil lembrar que aquilo na verdade é um software, e que tudo aquilo foi programado e desenhado para causar essas sensações em nós.

Mas não fique chateado e tenha certeza que atrás de cada grande ou pequeno game existe uma equipe de programadores, analistas, designers, testers e outros empenhando-se ao máximo para saciar as necessidades desses softwares e causar essas sensações em você.

Bem, mas agora você pode está se perguntando “Quais necessidades um software pode ter?”. Bem, quando se fala de necessidades de um software estamos falando na verdade de seus requisitos funcionais e não funcionais (caso queira ver mais sobre requisitos funcionais e não funcionais dá uma olhadinha no texto), quais devem ser devidamente atendidos pelo padrão de arquitetura de software aplicado, a fim garantir o perfeito funcionamento desse software.

Se você é desenvolvedor, deve conhecer alguns padrões de arquitetura de software populares, tais como MVC, MVP, N-tier, Pipeline, entre outros, contudo quando se trata de padrões de arquitetura de software específico para games, não é comum um número tão grande de padrões populares. Visando essa demanda, no final de 2017 apresentei, junto a um colega de faculdade, meu trabalho de conclusão de curso, com uma proposta de padrão de arquitetura de software para jogos digitais que visa ser genérica o suficiente para ser aplicado nas plataformas mais comuns presentes hoje no mercado. Nasceu assim a Layered Architecture for Games ou apenas LAG.

lag

Layered Architecture for Games

Como qualquer padrão de arquitetura de software, a LAG expressa a estrutura organizacional de um software, nesse caso de um game, segregando-o em subsistemas e especificando responsabilidades para seus componentes. Além disso, o padrão leva em consideração as especificidades desse tipo de sistema e requisitos não funcionais como manutenibilidade, escalabilidade, interoperabilidade, modularidade, testabilidade e reusabilidade.

O padrão é baseado no padrão de arquitetura de camadas relaxadas, permitindo que qualquer camada utilize os serviços de quaisquer camadas inferiores, consistindo basicamente em uma estrutura de camadas sobrepostas de acordo ao seu nível de abstração. É disposto da seguinte forma:

aislan-txt

Objetos do jogo: A primeira camada, como o nome sugere, é destinada aos objetos do jogo, que por sua vez compõem as cenas fazendo parte da camada que é visualizada e manipulada pelo jogador. Assim, todo elemento que de alguma forma ocupa lugar na cena como objetos do cenário, inimigos, botões e afins, estarão nessa camada;
Serviços de objetos: Nessa camada se encontram elementos destinados a realizar tarefas ligadas aos objetos do jogo de forma a não modificar seu comportamento na cena, porém podem desencadear eventos que acarretam em tais mudanças. Em outras palavras, serviços que serão chamados pelos objetos do jogo e não modificaram nada na cena diretamente. Dada a natureza de dependência que os elementos dessa camada podem vir a manter com os elementos da sua subcamada - modificadores de objetos, uma relação de injeção de dependência é bem vinda aqui;
Modificadores de objetos: Essa subcamada da camada serviço de objetos é responsável por abrigar elementos que são capazes de modificar o comportamento de objetos do jogo mediante os eventos ocorridos, tais como comandos do jogador, colisões de objetos do jogo, entre outros, alterando assim o comportamento dos objetos do jogo dentro da cena;
Serviços: A essa camada são pertencentes elementos que prestam algum tipo de serviço que não estão diretamente relacionados com os objetos do jogo, mas com outros aspectos do sistema. Assim, elementos do tipo utilitários e serviços básicos estarão presentes nessa camada;
Persistência: Camada destinada à abstração relacionada à persistência de dados, sendo assim uma camada que pode apresentar uma variação grande de elementos a depender do projeto e dos tipos de persistências aplicadas;
Infraestrutura: Sendo a última camada do padrão, a camada de infraestrutura provê de forma encapsulada subsídios para o funcionamento das demais camadas, fornecendo interfaces que abstraem configurações, protocolos, esquemas, bibliotecas específicas, dados e métodos necessários para comunicação com servidores, bancos de dados ou mesmo com o meio no qual o sistema está inserido.

Justificativa da estrutura proposta pelo Padrão LAG

Um dos principais problemas no desenvolvimento de jogos digitais é a estruturação de seus elementos lógicos, problema esse que é agravado pela existência de diversas plataformas de desenvolvimento que trazem abordagens diferentes referentes a esses elementos.

Para dirimir esse problema, o padrão LAG estrutura os elementos de acordo a suas funcionalidades, criando camadas com funcionalidades específicas e únicas. Essa característica, além de facilitar a estruturação lógica do projeto, auxilia na modularidade e manutenibilidade.

Um dos elementos mais ímpares dos jogos digitais são os objetos do jogo, pois atuam de forma única nos games, sendo através destes que os jogadores iniciam processos, executam comandos e, de fato, jogam. Devido a tal característica, esses elementos ocupam a primeira camada no padrão, o que permite que seus elementos se comuniquem com os elementos das camadas inferiores, funcionando como gatilho de processos.

Outro ponto importante sobre os objetos do jogo é que comumente eles são capazes de realizar diversas tarefas, sobretudo quando atuam como protagonistas das cenas. Em termos de software, pode implicar em elementos grandes e complexos. Para evitar a instalação desse quadro, a camada serviços de objetos foi criada, a fim de segregar as tarefas dos elementos de cena dos seus respectivos objetos do jogo, criando elementos menores e mais simples.

Contudo, ao separar os elementos de cena de seus serviços, é possível criar uma camada de objetos do jogo mais simples, mas é possível também a criação de uma camada de serviço de objetos muito extensa, uma vez que poderia haver diversas tarefas para cada elemento. Como nem toda tarefa afeta o comportamento dos objetos na cena, esse critério foi utilizado para determinar a criação da subcamada "modificadores de objetos", que é responsável por mudanças no comportamento dos objetos do jogo, possibilitando uma melhor segregação dos elementos.

As três últimas camadas do padrão LAG foram concebidas para suprir as necessidades básicas inerentes a qualquer software, uma vez que essas lidam mais diretamente com o sistema e com a execução do software, do que com sua jogabilidade ou com a interação com o jogador. Tais camadas devem ser pensadas e adequadas para cada projeto respeitando suas funcionalidades e seus relacionamentos com as demais camadas.

Hora de Testar...

funciona
Claro que não dá para falar sobre proposta de padrão de arquitetura de software sem verificar se ao menos funciona :P

Então, para testar a aplicabilidade do padrão LAG, foi desenvolvido um pequeno projeto baseado no clássico Arkanoid, utilizando o motor gráfico Unity e a linguagem C#.

O resultado pode ser visto aqui:
https://github.com/ThisAislan/Lagnoid

E o protótipo jogável aqui:
http://lagnoid.herokuapp.com/

Resposta: funciona!
oh-yeah

Considerações Finais

Que jogos são softwares, acho que agora não dá mais para esquecer, e nem que eles têm necessidades que devem ser atendidas pelo padrão de arquitetura de software que neles são aplicados. Nesse aspecto, o padrão LAG vem ajudar a suprir a carência de um padrão de arquitetura de software voltado para jogos digitais e suas respectivas particularidades.

De maneira geral o padrão mostrou-se plausível, trazendo benefícios organizacionais que ajudaram no desenvolvimento de um projeto melhor estruturado, com maior modularidade, manutenibilidade, escalabilidade, navegabilidade e reusabilidade, sob um custo pequeno do aumento da complexidade do mesmo devido a seu pequeno porte. Característica essa que já é esperada na aplicação de qualquer padrão baseado em camadas.

Claro que se faz necessário uma melhor validação do padrão proposto, e sim, há espaço para melhorias e evoluções, aplicar em projetos maiores e mais robustos, onde o potencial do padrão poderá ser melhor avaliado, como também suas possíveis limitações e problemas de implementação poderão ser identificados. Então fique a vontade para dar pitacos, questionar, criticar, avaliar e ajudar a melhorar, afinal de contas a vida é multiplayer! ;)