quarta-feira, 2 de agosto de 2017

Mas Java? C++ não é a melhor linguagem para jogos? E C#?

Repost de https://www.programandojogosandroid.top/java-vs-c++-para-desenvolvimento-jogos

Se você está lendo este artigo, pelo menos está considerando a possibilidade de programar jogos em Java em detrimento à escolha padrão da indústria, C++. E está com dúvidas se ao fazer isto você está perdendo o seu tempo. Lhe adianto que não. Mesmo que C++ seja a linguagem padrão para fazer os famigerados jogos AAA, você, que está começando a programar jogos não vai ter 1/1000 das preocupações que essas pessoas precisam ter.
Vou lhe dizer porque Java é uma excelente escolha, lhe mostrar os casos de sucesso e apontar quais são as vantagens e desvantagens de C++ vs Java. Também vou abordar brevemente C#, outra linguagem que ficou muito popular no mundo do desenvolvimento de jogos.
Como dito na introdução, os jogos AAA de hoje tem certas características simultâneas como:
  • 60fps 
  • 2kk+ de polígonos na tela 
  • IA
  • Física
  • Partículas
  • Lag compensation
  • Art asset streaming
Não que os seus jogos não vão ter estas características também, mas em geral não é preciso exigir tanto da máquina como em jogos AAA. E pra isto, para se chegar no topo do topo da performance, C++ ainda é a escolha fácil e adequada. 
Outras alternativas como Rust estão chegando ao mercado, mas ainda são muito incipientes e não são compatíveis com todos os consoles, além de que a indústria já se acostumou com C++, é mais fácil contratar e os programadores mais experientes (sofreram bastante, lhe garanto) conseguem dobrar a linguagem para todo tipo de uso.
Pra começar a puxar a sardinha pro lado do Java, é importante ressaltar que pouquíssimos jogos são feitos 100% em C++, quase todos os jogos utilizam alguma linguagem de script como Lua (orgulho nacional) para ganhar flexibilidade e velocidade na implementação do código de gameplay.

Mas você não precisa acreditar em mim. Confira os jogos mais famosos feitos com Java para tirar de vez a dúvida que é possível fazer jogos de alta performance e grande popularidade com a linguagem.

Runescape™
Runescape™
Wurm Online™
Wurm Online™
Spiral Knights™
Spiral Knights™
Altitude™
Altitude™
Operation Storm Front™
Operation Storm Front™
Age of Conquest III™
Age of Conquest III™
Minecraft™
Minecraft™
Para quem precisa de um caminho um pouco mais técnico, vamos ver alguns benchmarks em relação ao uso de CPU, memória e tempo de execução de alguns programas (no sentido do dicionário) clássicos.
Benchmarks Java vs C++
Benchmark Java vs C++
Nestes 4 programas, vemos que Java ganha em tempo de execução em apenas um, mas isso mostra que mesmo a linguagem sendo considerada mais lenta, dependendo do jeito que é utilizada, a JVM pode ter um desempenho excelente. Fonte dos benchmarks.

Existem alguns problemas de performance que costumam acontecer com frequência, são os chamados performance bottlenecks, ou em português, os famosos gargalos. 

Em um típico pipeline gráfico, a geometria é armazenada em algum lugar do disco, é carregada e mínimamente processada pela CPU e despachada para a GPU, mesmo que exista uma ligação direta entre a RAM e a GPU, a CPU costuma se envolver nesse processo de alguma maneira. Depois que os dados chegaram na GPU, em teoria, não importa mais a linguagem de programação que está sendo usada, já que agora ta mão dos shaders, da placa e do driver responsável pelas operações gráficas. E é neste momento que sim, é preciso muitos truques para não deixar Java te atrapalhar, pois quando estamos lidando com buffers nativos de memória, Java realmente não lhe da o controle completo que você pode precisar. Para mais detalhes acesse este artigo da intel sobre o assunto e este artigo sobre NIO Buffers em Java. 
Um outro problema, também relacionado a memória, é a presença do coletor de lixo (garbage collector), isso é um problema e ao mesmo tempo uma grande vantagem da linguagem já que você não precisa se preocupar tanto assim em fazer a limpeza dos seus objetos depois de criados. Porém, isto não costuma ser verdade para o desenvolvimento de jogos, você vai querer sim ter um controle sobre os recursos e libera-los a medida que não forem usados, fazer reciclagem de objetos e vários outros tipos de técnica para evitar de precisar alocar mais memória e evitar que o GC tenha que trabalhar.

Antes de atacar C++ é importante lembrar os motivos da linguagem estar sendo usada até hoje. 

Primeiro de tudo, ela é o padrão da indústria. Estúdios grandes sabem gerenciar projetos C++, eles sabem avaliar candidatos C++, eles tem muita tecnologia feita em C++, existem gazilhões de linhas de código feitas em C++, toda a indústria AAA gira em torno de C++, quebrar esse ciclo é muito difícil.
E o que existe de tão ruim e difícil em C++? Muitos diriam que o gerenciamento de memória é o que torna C++ tão difícil, mas eu não tenho essa opinião, para mim, existem algumas técnicas em C++ como o uso correto de construtores e destrutores (também conhecido, bizarramente, como RAII) alocando sua memória na pilha sempre que puder, caso precise usar a heap, o uso do unique_ptr (C++11) é bem efetivo. 
Uma característica que costuma tirar as pessoas do sério no uso de C++ é a sua falta de um sistema de pacotes como o npm do node.js ou até mesmo o Maven do Java, ter que manter arquivos de header também é algo extremamente improdutivo e o tratamento pobre e confuso de strings. Para entender o que estou querendo dizer com as strings dê uma olhada na resposta mais votada do stackoverflow em uma pergunta sobre fazer o split de uma string.
istringstream iss(sentence);
copy(istream_iterator(iss),
     istream_iterator(),
     ostream_iterator(cout, "\n"));
Na minha opinião, isto é um sofrimento muito grande para fazer uma coisa tão comum. Compare com Java ou Javascript
str.split(“…”);
É claro que não fiz um exame minucioso sobre todas as operações mais comuns em strings e um de para de C++ para outras linguagens, mas creio que fica claro que seria interessante poder importar facilmente bibliotecas de string em C++ para resolver esses problemas. Só que importar bibliotecas em C++ não é fácil. A coisa é tão chata que um estilo de bilbioteca, single header file libs, foi criado.
Enfim, com o tempo, e em um projeto maior, esses problemas que levantei vão sendo amortizados, mas para quem está apenas estudando programação de jogos ou quer atacar um projeto pequeno, essa perda de produtividade de C++ é realmente um problema que não pode ser ignorado.
Falamos sobre a linguagem em si e um possível sistema de pacotes, mas e o resto ferramental? Esta também é uma área que C++ peca bastante. Com a recente chegada de CLion da Jetbrains isso está mudando de figura, mas Java oferece IDEs mais amigáveis há bastante tempo como o eclipse que realmente te ajudam em tarefas como refatorações. Os compiladores C++ também costumam emitir mensagens de erro ininteligíveis, principalmente se você estiver trabalhando com templates. 
Para não ser cretino, todos esses problemas que eu levantei do C++ estão sendo atacados pelos comitês que a dirigem. Em alguns anos, 5, 8? É possível que C++ realmente chegue a um nível de produtividade em questão de expressividade da linguagem e ferramental impressionantes, mas até lá… Quem precisar usar C++ vai ter que aprender todos as suas mãnhas.

Um outro elefante branco na sala das discussões de qual linguagem usar para programar jogos é o C#. 

Desde que introduzida nesta área pela Microsoft com o XNA (agora falecido) ela vem tomando espaço. Com a chegada da Unity, a popularidade da linguagem explodiu. Em termos de linguagem, C# é realmente uma linguagem moderna e não sofre de nenhum mal dos que eu citei para C++. O problema realmente é do ambiente que a hospeda. Unity é uma ferramenta fantástica, mas se você está apenas começando, quer fazer jogos 2D, e quer ter mais controle sobre o seu programa em execução, Unity não é a ferramenta adequada. Eu diria que frameworks como Libgdx vão lhe ajudar muito mais para aprender os fundamentos de maneira profunda do que a Unity.

Com isso tudo, vou dizer pra vocês

É claro, sendo um artigo de opinião que desde o título já mostra suas intenções, que Java é uma linguagem de programação perfeitamente adequada para se programar os mais variados tipos de jogos, principalmente se você estiver começando e não quer perder seu tempo lidando com todas as idiossincrasias de C++. E nos dias de hoje, onde temos bibliotecas e frameworks excelentes como a Libgdx, pode seguir tranquilo com o Java.


Perguntas/Queries relacionadas
  • Java vs C++?
  • C# vs Java
  • Da para fazer jogos em Java?
  • Exemplos de jogos feitos em Java