BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Artigos Migrando um editor de games no navegador com o WebAssembly

Migrando um editor de games no navegador com o WebAssembly

Pontos Principais

  • O WebAssemly, está sendo desenvolvido ativamente e podemos dizer que ainda está em estado bruto, mas maduro o suficiente para migrar uma aplicação complexa, como um editor de jogos para a Web;

  • Os benefícios de migrar o software desktop para o WebAssembly incluem a entrega de plataforma cruzada do software portado, possivelmente atingindo um público-alvo maior;

  • As estruturas e ferramentas de front-end permitem um desenvolvimento simplificado da interface do usuário com um ciclo de feedback mais curto em relação às aplicações desktop nativas;

  • A web oferece novas possibilidades, como links diretos e acesso a um rico ecossistema de UI, com o potencial de melhorar consideravelmente a experiência do usuário;

  • Os desenvolvedores devem prestar atenção especial ao gerenciamento de memória, testes e digitação para reduzir os problemas de portabilidade.

Florian Rival, engenheiro de software do Google, criador do editor de games GDevelop, apresentou uma palestra no ReactiveConf 2019 em Praga, na qual discutiu as lições aprendidas ao migrar um editor de games de mesa nativo para o navegador com o WebAssembly.

O InfoQ perguntou a Rival sobre os desafios técnicos encontrados, os benefícios derivados da portabilidade e dicas para os desenvolvedores que pensam em portar aplicações desktop para o WebAssembly.

InfoQ: Vamos começar descrevendo o GDevelop. Qual é o público-alvo, e qual é a proposta de valor do GDevelop? Quais dores ele soluciona para os criadores de jogos?

Florian Rival: A ideia do GDevelop é tornar a criação de jogos acessível a qualquer pessoa, desde iniciantes até desenvolvedores de jogos experientes. O GDevelop permite que os desenvolvedores criem a lógica do jogo usando eventos visuais, compostos de condições e ações. Podemos criar os objetos do jogo compondo comportamentos predefinidos e personalizados.

Isso significa que a barreira de entrada para aprender a sintaxe e expressões de uma linguagem de programação foi completamente removida. Para pessoas que não são desenvolvedoras, é uma maneira de começar a criar rapidamente com uma interface intuitiva. Muitas pessoas adoram jogos de sandbox, e o GDevelop é uma, mas é ilimitado com o que podemos fazer com essa ferramenta.

Para desenvolvedores de jogos experientes, temos um ambiente de desenvolvimento integrado que torna a criação de jogos bastante rápida, eficiente e extensível (os eventos são transformados em código "real").

Por fim, quando olhamos com foco em uma equipe, é uma maneira de envolver a todos, desenvolvedores, artistas, gerentes de projetos, designers de jogos, em uma interface comum, promovendo a criatividade de todos.

Obviamente, a educação e os workshops relacionados à criação de jogos podem se beneficiar muito com o uso do GDevelop com os alunos. Podemos começar a alterar um jogo em poucos segundos, e ensinar conceitos de programação por meio de eventos e até mesmo criando extensões.

InfoQ: O que o motivou a portar o editor de jogos para o WebAssembly? O que a migração para a Web oferece que não se pode ter ou é difícil de se conseguir no desktop?

Rival: O editor costumava ser um aplicativo de desktop criado em C++ nativo. Enquanto funcionava bem, estava tudo bem, mas não havia nada de mais. Ele estava começando a falhar em alguns pontos: O suporte ao macOS e Linux era difícil de se conseguir da maneira correta, devido a falhas constantes no pacote de ferramentas da interface do usuário, e o trabalho na interface era bastante lento, devido ao processo longo de feedback "faça uma alteração > compile > execute > repita", além de ter componentes limitados e desatualizados de interface do usuário. Isso também assustava os novos colaboradores.

Depois de trabalhar um pouco com o React e com estruturas relacionadas como o React Native para aplicativos móveis, eu entendi que o paradigma do componente, associado à "interface do usuário como uma função de estado", era uma maneira realmente poderosa e escalável de criar interfaces.

Estava sentindo falta dessa velocidade de desenvolvimento e da excelente arquitetura que ela permite nativamente!

De maneira geral, comecei a me perguntar se as tecnologias web poderiam ajudar a criar uma aplicação melhor.

Nesse ponto, olhei para o WebAssembly, usando o Emscripten, como uma maneira conveniente de migrar essa grande base de código C++ existente para os navegadores e mecanismos JS em geral, como o Node.js.

Minha ideia era que, mudando o núcleo para o WebAssembly, e usando JavaScript e React, ou outra estrutura front-end para a interface, teria uma aplicação portátil para quase todas as plataformas existentes, trabalhando de forma consistente entre dispositivos e isso criaria novas oportunidades que na época, nem podíamos sonhar. Como ter uma aplicação que podemos iniciar em alguns segundos para testá-la, ou uma aplicação que pode ser executada de maneira inalterada em telefones e tablets.

InfoQ: Falando sobre a portabilidade, foi mencionado na palestra a seguinte arquitetura:

Sendo um editor de jogos, entendo que os dois módulos principais são uma interface do usuário rica e interativa que manipula a parte de edição e uma parte mais transacional, que seria a algorítmica, vinculada aos mecanismos de regras e à geração do código do jogo. Como isso se traduz na nova arquitetura ao migrar para o WebAssembly?

Rival: A migração para o WebAssembly começou separando claramente, na base do código C++ original, o núcleo da aplicação (a "lógica de negócios", que no caso, são as classes que descrevem a estrutura de um jogo e as classes que as manipulam, incluindo a geração do código do jogo) da interface do usuário. Esta é a parte "principal" que é compilada no WebAssembly, quase inalterada, exceto por algumas abstrações no sistema de arquivos.

Depois que tivermos essa base de código em execução no navegador, a próxima etapa foi começar a expor parte dela no JavaScript escrevendo as ligações. O que usamos depende da nossa linguagem. No caso do C++ com Emscripten, foi usado o WebIDL para escrever as ligações.

Por fim, eu podia finalmente começar a escrever uma nova interface, usando o React, que está usando o código, assim como qualquer outra biblioteca.

InfoQ: Quais foram os principais desafios encontrados? Que dicas daria para os desenvolvedores que desejem migrar de maneira semelhante o software existente em desktop para a web com o WebAssembly?

Rival: Uma familiaridade com a base de código existente é obviamente uma enorme vantagem para começar. É uma boa ideia ver como o código nativo está sendo executado e como está sendo utilizado, caso seja uma biblioteca.

Um grande desafio está no gerenciamento de memória. Enquanto os objetos JavaScript são coletados pelo coletor de lixo (garbage collector), os objetos que criamos no "mundo do WebAssembly" não são. Portanto, se chamarmos uma função para criar um objeto que está armazenado na memória do WebAssembly e, posteriormente, fizermos a referência no JavaScript, acabamos vazando a memória. Por isso, precisamos nos certificar de excluir o que criamos, até que o Emscripten/wasm chame algum coletor de lixo.

Outro desafio está relacionado ao uso adequado da biblioteca compilada do WebAssembly. Se passarmos um parâmetro do tipo errado ou tentarmos chamar do JavaScript o método de um objeto que excluímos da memória no código C++, estaremos em um território desconhecido, em relação ao comportamento indefinido no C++, e provavelmente iremos obter uma "falha" dentro do nosso módulo wasm. E é improvável que possamos recuperá-lo, enquanto o JavaScript pode ser um pouco mais indulgente, continuando o trabalho se uma exceção for detectada em uma parte não crítica da aplicação.

Escrever em JavaScript, usando Flow e Typecript, pode ajudar. Infelizmente ainda não há uma maneira de converter automaticamente os tipos do C++ para os tipos do Flow ou do Typecript.

A depuração também pode ser mais difícil. Recomendo ter um conjunto de testes extensos para biblioteca wasm, para verificar se tudo está funcionando corretamente. Isso ajudará no caso de mudarmos a implementação para outra linguagem e também servirá como uma excelente documentação viva de como utilizar corretamente a biblioteca.

InfoQ: Como você acabou empacotando e distribuindo a aplicação web e por quê?

Rival: Como o acesso ao sistema de arquivos ainda era um componente essencial da aplicação e as pessoas preferiam poder trabalhar com jogos offline, empacotei toda a aplicação como sendo uma aplicação Electron que pode funcionar no Windows, macOS e Linux. Está funcionando muito bem em todas as plataformas e, embora o Electron possa ser um pouco pesado em termos de tamanho de pacote, aceito esse contraponto porque os usuários estão baixando um editor de jogos completo.

Dito isto, é importante ter uma aplicação web autônoma, para que possa ser experimentada e usada no ambiente online. Existem algumas limitações em relação à aplicação desktop que removo constantemente quando a web oferece APIs equivalentes ou quando há retrabalho para utilizar alternativas.

InfoQ: Quanto tempo levou para obter um editor migrado e minimamente viável, em relação a interface do usuário e ao desempenho, e quão fácil diria que a experiência foi?

Rival: Certamente houve altos e baixos durante a migração. Depois de obter uma versão funcional do núcleo dos navegadores, juntamente com alguns amigos, começamos a trabalhar em uma nova interface de usuário baseada na web para a aplicação. Levamos apenas algumas semanas para que algo funcionasse, e posteriormente o reiniciei do zero, mas o protótipo era uma prova de que os navegadores podiam suportar a aplicação e executá-la corretamente.

Tive que refazer as ligações, em alguns momentos, e atualizar para versões mais recentes do Emscripten nem sempre é algo fácil. Ainda não estou na versão mais recente, porém, é apenas uma questão de investir algum tempo para concluí-la.

Certamente não é fácil, mas as arestas que estavam presentes no início estão sendo melhoradas. A compilação do Emscripten costumava ser super longa, e agora não é mais.

InfoQ: Percebi que foi mencionado que a aplicação web migrada é melhor que a original. Poderia elaborar as melhorias específicas trazidas pela aplicação web?

Rival: Curiosamente, o tempo de inicialização foi melhorado e acho que poderia ser ainda mais rápido.

O que mais me satisfaz é a possibilidade de criar esse tipo de link.

Clique ali e em alguns segundos, mais ou menos de acordo com a velocidade da internet e quão rápido é o dispositivo, já temos um editor de jogos funcionando, podemos modificar o jogo, executar uma pré-visualização e começar a mudá-lo. Era impossível alcançar isso no passado.

Em termos de experiência em desenvolvimento, o trabalho na parte do C++ da aplicação é basicamente o mesmo que antes, mas a interface do usuário é realmente mais rápida de se desenvolver. Ferramentas como o Storybook permitem desenvolver componentes da aplicação de maneira isolada, sem nem mesmo executá-la. Passamos de um ciclo de feedback de alguns minutos a alguns segundos ao desenvolver na interface do usuário. O Storybook também permite visualizar estados incomuns dos componentes da aplicação, como estados de erro, e ter confiança, depois de fazer alterações, de que tudo está funcionando. Eu os vejo como casos de teste não automatizados, mas ainda sim, são super úteis.

As peculiaridades entre navegadores web são inevitáveis, mas, em geral, o suporte para várias plataformas é muito mais fácil de obter do que com os pacotes de ferramentas de interface de usuário de plataformas cruzadas mais antigos que tentei implementar com o C++.

Embora a interface da aplicação não seja feita através de widgets nativos, ainda podemos usar alguns, especialmente se estivermos usando o Electron, que permite tirar proveito de coisas como menus de contexto nativos e barras de menus nativas.

A arquitetura limpa, orientada a componentes, é possível usando o React, é uma enorme vantagem em termos de modularidade e manutenção de uma base de código limpa, o que está melhorando a eficiência do desenvolvimento. No final, isso se traduz em uma interface melhor, porque a arquitetura limpa se traduz em componentes consistentes e bem projetados. Por exemplo, é mais fácil obter capacidade de resposta de maneira consistente com os componentes. Era difícil imaginar fazer uma interface de usuário responsiva com a interface antiga.

InfoQ: O que você vê projetado em termos de recursos futuros para o editor?

Rival: Muitas, muitas coisas! A comunidade está sempre sugerindo novidades. A interface está sendo aprimorada para encontrar o equilíbrio certo entre intuitividade e integridade. Gostaria de criar um ecossistema e uma comunidade mais completos em torno do software. Novamente, tenho várias ideias para tornar a criação de jogos mais acessível e mais rápida para literalmente qualquer pessoa. O mecanismo do jogo pode ser aprimorado com novas extensões, trazendo novos recursos ou aprimorando o desempenho, retrabalhando algumas partes sensíveis no desempenho do próprio WebAssembly!

O GDevelop é um mecanismo de jogo open source, multiplataforma, que está disponível no repositório GitHub.

O ReactiveConf é uma conferência anual voltada para desenvolvedores, com palestras abordando as mais recentes tecnologias e tendências no desenvolvimento de software. O ReactiveConf 2019 foi a quinta edição desta conferência.

Sobre o entrevistado

Florian Rival é engenheiro de software do Google, autor do GDevelop, um software de criação de jogos opensource baseado em WebAssembly e JavaScript. Também criou o Hello Earth do Lil BUB, um jogo de 8 bits estrelado pelo gato sensação da Internet, disponível em computadores e dispositivos móveis, 100% feito com o GDevelop. De um modo geral, gosta de abordagens inovadoras para ultrapassar os limites do que podemos fazer com aplicações, aplicativos móveis e jogos.

 

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT