Competindo com C ++ para programação de jogos


21

Estou curioso para saber por que o C ++ é tão popular no desenvolvimento de jogos, e não em outras linguagens. Eu sei que você pode criar código muito rápido com ele, mas o que exatamente o torna popular?

É só porque é rápido? Existe algum outro recurso na linguagem, como o paradigma OO ou a portabilidade? É por causa de todas as bibliotecas que foram criadas ao longo do tempo? Ou alguma combinação de todas essas (e outras) razões?

Se alguém pudesse me informar sobre isso, eu ficaria muito feliz. :-)


7
A velocidade é motivo suficiente para mim, especialmente porque as queixas de todos sobre o idioma não fazem realmente sentido para mim.
22711 Benjamin Lindley

Um palpite rápido: a maioria dos jogos é escrita para Windows. As linguagens C e C ++ são altamente suportadas pela Microsoft. E, finalmente, o C ++ é preferido por causa da OOP e da metaprogramação de modelos.

@ Matt Obrigado, não sabia que existia. Posso mover o tópico para lá ou devo excluir este e recriá-lo por lá?

Isso já foi solicitado várias vezes.
Zan Lynx

1
@ Benjamin: Então, ouso dizer que você não escreveu o suficiente em C ++, ou nunca usou uma linguagem mais expressiva como Python (ou mesmo C # com LINQ). No entanto, mesmo que por algum motivo louco você prefira escrever código de 20 linhas para o que muitas outras linguagens podem fazer em 1, a gramática extremamente ruim do C ++ significa que os programas levam muito mais tempo para serem compilados do que deveriam e as ferramentas IDE adequadas (refatoração, etc.) são mais difíceis, se não impossíveis, de criar.
BlueRaja - Danny Pflughoeft

Respostas:


29

Inúmeras razões:

  • O que você perdeu: é portátil, simplificando as portas do seu mecanismo de jogo para iOS, XBOX, PS3, qualquer que seja
  • É rápido
  • Todos os SDKs o suportam nativamente
  • Muitas bibliotecas disponíveis
  • Todo mundo que escreve jogos sabe disso, por isso é fácil contratar desenvolvedores de jogos experientes para sua equipe
  • É trivial incorporar uma linguagem de script de mecanismo de jogo como Lua

Tudo bem, obrigado por suas respostas a todos, você cobriu tudo o que eu precisava, eu acho. :-)
KasMA1990

14

Há algumas razões que eu gostaria de mencionar além do que o @Graham trouxe.

  • Código legado - muitos estúdios têm muito código C ++, e você menciona as bibliotecas.
  • O C ++ é realmente um montador de alto nível e tem acesso direto ao hardware (o mais direto possível para rodar em cima de um sistema operacional) e é bastante rápido. Se você quiser, em C ++, você pode entrar diretamente na linguagem assembly para controlar o nível de instrução (não que seja sempre sábio, apenas não é possível com Java, C #, Python, etc.)
  • O DirectX e o OpenGL oferecem suporte nativo a C ++, a maioria das outras linguagens possui "ligações" às bibliotecas subjacentes por meio de camadas intermediárias, isso não quer dizer que não seja rápido ou não possa fazer as mesmas coisas, mas adiciona uma camada de software entre seu jogo e o hardware.
  • Como o @Graham menciona, muitos programadores o conhecem, por isso é fácil encontrar desenvolvedores experientes e também bastante portáteis, em comparação com o C # que está preso no .NET Framework (existe o Mono, mas geralmente fica uma geração atrás da implementação da Microsoft .)

Você não quer dizer baixo nível?
Jhocking 13/04

5
C ++ é uma low-levellinguagem; mas um high-levelmontador, IMO.
Nate

3
Discordo. C ++ é uma linguagem de alto nível, com o recurso interno de recorrer ao C (que é uma linguagem de baixo nível).
foo

7
C ++ é uma linguagem de alto nível, assim como C. O assembly é de baixo nível. Agora, C ++ é mais alto que C, assim como C # é maior que C ++ e Ruby / Python é maior que C #.
AA Grapsas

4
Por que o código legado deve ser preterido (não preterido)? "Código legado" significa apenas que é antigo, não que seja ruim.

8

A velocidade bruta é o principal motivo, mas, na verdade, não é uma decisão de escolha ou não, então muitas empresas de jogos estão começando a usar outros idiomas para partes do jogo. Certas tarefas exigem que o computador funcione o mais rápido possível (por exemplo, rotinas principais de renderização), mas muitas tarefas no código de jogo não precisam ser executadas com tanta rapidez (por exemplo, abrindo a porta quando o jogador clica nele), o que significa que é inteligente usar uma linguagem muito mais simples (e, portanto, mais rápida para escrever programas) para essas partes. É por isso que muitos mecanismos de jogo são escritos em C ++, mas incorporam uma linguagem de script como Lua para escrever código de jogo.

O mais complicado de entender é que, ao escolher as linguagens de programação, existe uma troca geral entre eficiência para o computador e eficiência para o programador. Ou seja, o que é mais importante para você, com que rapidez o computador executa o código ou com que rapidez o programador grava o código?


3

No C ++, você pode alocar variáveis ​​locais que desaparecem após o término da função. Geralmente, eles são alocados em uma pilha.

As variáveis ​​de pilha não contribuem para os problemas de alocação de memória dinâmica de fragmentação e sobrecarga. Alocar espaço na pilha é rápido e fácil (apenas ajustando um ponteiro). A alocação dinâmica de memória geralmente envolve procurar em um contêiner um bloco de memória adequado, marcando a memória e marcando-a como ocupada. A desalocação envolve adicionar o bloco de memória a um contêiner e possivelmente mesclá-lo aos blocos existentes. Muito mais sobrecarga do que apenas mudar um ponteiro.

Java e C # alocam memória dinamicamente, exceto para tipos primitivos. Esses idiomas dependem de um ambiente de tempo de execução que marcará uma variável a ser excluída e, em seguida, execute um coletor de lixo em intervalos aleatórios (não programados) para recuperar a memória. Em geral, o programador não tem controle sobre quando a variável será marcada para exclusão nem quando será recuperada (recuperação de memória usada é um tópico avançado que a maioria dos programadores de C ++ e Java não possui).

A velocidade do C ++ deve-se principalmente à sua tradução direta para código executável. Java e C # são compilados para um código intermediário que é então interpretado por uma máquina virtual. Em geral, os idiomas interpretativos têm desempenho mais lento que os idiomas traduzidos diretamente.


1
-1 (se eu pudesse) - primitivas locais são alocadas na pilha em Java e C #, e em C # você pode criar alocação de pilha structs. Mais ao ponto, extremamente extremamente pequeno aumento na velocidade Este redes você não é quase o suficiente para justificar uma língua sobre a outra. O verdadeiro motivo é afirmado pelo @Graham Perks: é o que os desenvolvedores de jogos devem saber, é o que os novos desenvolvedores aprendem e para que novos SDKs são direcionados. Há uma abundância de idiomas (ex. Ir) que são tão ou mais rápido, e não quase tão inconveniente para escrever para.
BlueRaja - Danny Pflughoeft

C ++ não é muito bom na alocação de pilha; de fato, é muito difícil alocar objetos compatíveis com STL na pilha. Por exemplo, o último mecanismo grande em que trabalhei foi em C, e tínhamos uma string na qual você poderia iniciar a pilha em um tamanho fixo (geralmente 1K). Se passasse do ponto de vista transparente, passaria para a pilha. Você pode fazer coisas semelhantes com os alocadores personalizados std :: string em C ++, mas o código é muito mais difícil de corrigir.

1
@ Joe Wreschnig: O C ++ é excelente na alocação de pilha, basta despejar uma listagem em linguagem assembly. No entanto, a maioria dos fornecedores de compiladores não aloca uma quantidade enorme de memória para a pilha. Um entendimento comum dos programadores experientes em C ++ é que objetos enormes são alocados dinamicamente (heap) e não armazenamento local (pilha). Objetos enormes na pilha podem invadir a pilha em algumas plataformas, à medida que a pilha e a pilha crescem uma em direção à outra.
Thomas Matthews

1
Um entendimento comum dos programadores C ++ mais experientes, especialmente aqueles em consoles de jogos, é que tudo o que não excede a pilha é alocado ou pré-alocado. C facilita isso porque o alocador não faz parte do tipo estrutural do objeto. Isso também possibilita liberar algo incorretamente, mas, na minha experiência, esse é um problema raro em comparação com alguém que estraga as implementações / compatibilidade de alocadores compatíveis com stdlib. Existem também alguns truques com posicionamento novo, mas novamente, que é mais complicado do que o equivalente em C.

2
Não. O benefício da velocidade do C ++ se deve à sua capacidade de usar seu próprio gerenciador de memória de gravação personalizada para alocações de heap . Todo idioma sensato aloca locais na pilha.
o Nevermind

3

Os jogos foram escritos em linguagem de máquina, porque tinham hardware exótico para o qual não havia compilador. O hardware também não possuía recursos que os programadores C consideram garantidos, como matemática matemática eficiente de 16 bits.

Depois que os jogos se estabeleceram em hardware familiar, os compiladores C ficaram disponíveis e em pouco tempo todos os jogos foram escritos em C.

C ++ parecia uma boa idéia ao mesmo tempo, e a maioria dos jogos é C ++ hoje, mas os engenheiros estão agora resmungando sobre um retorno ao C, e isso pode realmente acontecer. Eu adoraria trabalhar em um jogo em C, assim como muitos colegas de trabalho. Não há nenhum recurso novo no C ++ que eu acho que melhore os jogos.

Parece que agora que os computadores são 1000x mais rápidos do que alguns anos atrás, uma linguagem de alto nível reduziria o tempo de desenvolvimento ($) tornando C obsoleto.

Isso não aconteceu porque os compradores de jogos sabem que o hardware é 1000x melhor e desejam trocar seus dólares por um jogo com aparência e som 1000x melhores. Isso remove a folga do sistema que um idioma de alto nível consumiria.

Os requisitos de desempenho nos jogos são brutais. Um novo quadro de gráficos deve ser renderizado em menos de 33ms (ou 16ms!) Sem falha. Tudo o que o hardware faz deve ser contabilizado, para que esse orçamento possa ser cumprido. Qualquer linguagem que apague e faça algo com o hardware que o programador não entende ou espera, tornará muito difícil cumprir esse orçamento. Este é um sinal de menos automático contra qualquer coisa de alto nível.

Os programadores de jogos não apenas trabalham em uma linguagem de baixo nível, mas também evitam estruturas e algoritmos de dados de alto nível. Os jogos normalmente não têm listas vinculadas e raramente têm árvores. Há um movimento para evitar ponteiros sempre que possível *. Qualquer algoritmo com mais de O (N) tempo ou O (1) espaço tende a não encontrar amplo uso.

* Se um ponteiro não causa falta de cache, por que gastar 32 bits para armazená-lo? Se um ponteiro causar falta de cache, é melhor se livrar dessa falta de cache.


1
"Não há nenhum recurso novo no C ++ que eu acho que melhore os jogos". RI MUITO? OOP? Uma classe humancom derivados playere enemy?
orlp

2
@ nightcracker: A herança básica de is-a funciona bem em C; o relacionamento que você descreve é ​​melhor implementado usando has-a por razões de desempenho e limpeza de qualquer maneira.

3
Há um consenso crescente de que os recursos de POO do C ++ não são apropriados para jogos, porque esses recursos operam em suposições hostis ao desempenho do cache.
precisa saber é o seguinte

Mesmo se você acredita que o C ++ não oferece vantagens sobre o C, você certamente deve reconhecer que um retorno ao C também não oferece vantagens sobre o C ++.
Dan Olson

@Dan Um retorno ao C oferece a vantagem de que "práticas recomendadas", como não usar modelos ou OOP, são aplicadas por erros em tempo de compilação, em vez de perseguir programadores juniores com um palito. Além disso, como a linguagem é mais simples, presumivelmente, a manutenção do compilador e depurador também é mais barata.
precisa saber é o seguinte

3

Todas as linguagens de programação têm pontos fortes e fracos em vários fatores. Exemplos desses fatores são:

  • Velocidade em uma plataforma específica
  • Uso de memória em uma plataforma específica
  • Que funcionalidade expõe mais facilmente
  • Em quais plataformas ele existe
  • Que considerações um programador deve levar a bordo

Um dos fatores mais importantes com os quais um programador de jogos se importa é o desempenho. Eles querem produzir uma experiência interativa, o que significa que deve ser reativo e capaz de gerar o máximo possível de dados úteis (ou interessantes). Você quer saber quanta saúde você tem a qualquer momento e não quer esperar por isso. E se você clicar em um botão, espera que uma arma seja disparada ou que seu personagem pule quando você diz. Um pequeno atraso pode interferir nessa interatividade, portanto você precisa de desempenho.

Outro fator importante é preferir programar no idioma do problema, e não no idioma da implementação. Um programador de jogos quer lidar com humanos, orcs e carros de corrida, não com o registro de memória ED0. Eles ainda querem a opção de mergulhar nos detalhes da implementação, se precisarem de desempenho, mas seria ótimo que, na maior parte do tempo, eles possam lidar com o nível das entidades em seu mundo de jogo. Eles têm o suficiente para se preocupar em simular o mundo do jogo sem precisar se preocupar sempre com o funcionamento de uma lista vinculada.

O C ++ se encaixa muito bem nesses dois fatores principais. Você pode ter os benefícios de desempenho de montagem ou código C com a expressividade de objetos. Para ver por que isso é adequado para jogos, compare com outras opções de idioma:

  • Montagem: Isso é poder bruto. O que você escreve é ​​basicamente o que a CPU faz. Mas em todos os estágios, você precisa saber o que está acontecendo com os registros e o efeito disso, e nunca se parece com as entidades do seu mundo de jogo. O programador precisa fazer a correspondência mental do que o código faz versus o que acontece no jogo. Isso pode ser uma sobrecarga mental.
  • C: Aqui temos um bom desempenho, mas podemos aproveitar a experiência dos gurus para fazer coisas padrão (como alocar memória, operar em cadeias de caracteres e usar funções matemáticas padrão). Aqui nos aproximamos da expressividade, mas a linguagem o força mais ou menos a se concentrar na implementação, porque você pode realmente operar apenas em tipos de dados normais. Tudo é realmente um caractere, um int ou algo parecido. estruturas, ponteiros e matrizes podem manter as coisas unidas, mas ainda precisam pensar nos elementos internos.
  • Java: saltamos sobre C ++ e chegamos a Java. O Java se afasta ainda mais dos detalhes da implementação. De fato, na maioria das vezes você não tem acesso aos níveis mais baixos. O Java abstrai muitos detalhes da implementação (por exemplo, qual CPU ou SO você está usando) pelo motivo de querer ser multiplataforma. Você não pode acessar os detalhes porque eles não estão lá. Você não programa para o computador, programa para a plataforma (a plataforma Java, que existe na maioria dos computadores). Além disso, o Java possui uma linguagem significativamente melhor para lidar com a linguagem do problema do que o C ++. A desvantagem é que você não pode otimizar para um computador específico. Se isso faz uma diferença prática ou não, isso se resume às especificidades do programa e do computador.
  • Linguagem de script do jogo: com isso quero dizer algo como UnrealScript , ou linguagens de script personalizadas amarradas a um mecanismo de jogo. Nestas, você não tem acesso ao mecanismo subjacente. Você delega considerações de desempenho ao mecanismo, deixando-se livre para se preocupar em criar um jogo. É mais fácil escrever o jogo, mais difícil otimizar seu desempenho.
  • Haskell (ou sua linguagem obscura favorita): qualquer linguagem de programação completa de Turing é equivalente a qualquer outra. Portanto, enquanto você pode escrever qualquer programa em qualquer idioma, você faz trocas, algumas objetivas, outras subjetivas. Uma linguagem como Haskell está mais focada em trabalhar com espírito matemático. Os problemas a que se destina são um pouco diferentes dos problemas enfrentados nos jogos. Isso não significa que não possa ou não deva ser usado em jogos, apenas não é adequado para ele.

O último ponto é que parte disso é histórico e político. Muitas guerras de chamas foram travadas entre as diferentes linguagens de programação. O C #, por exemplo, pode ser igualmente adequado ao desenvolvimento de jogos, mas veio depois do C ++. Ou as pessoas não gostam que seja da Microsoft. Algumas pessoas mudaram para C #, outras não. Algumas pessoas ainda programam jogos no BASIC, Pascal e C. Quaisquer que sejam os programadores que se sentirem confortáveis, eles seguirão. Os programadores de jogos geralmente se sentem à vontade com C ++, possivelmente porque cresceram com C e C ++, e isso atendeu às suas necessidades. Se a indústria de computadores estiver em um estado em que o desempenho e a aceitação de Java satisfaçam um número suficiente de pessoas, talvez Java seja a linguagem padrão de desenvolvimento de jogos padrão.


2

Legado e impulso.

Era uma vez um código que foi escrito no assembler para o melhor desempenho. À medida que a energia de computação aumentou, as linguagens compiladas se tornaram mais viáveis, e C ofereceu o melhor compromisso entre energia e produtividade, em um nível muito básico, sendo pouco mais que um macro assembler.

C ++ foi apenas o sucessor natural de C. Você não joga fora nenhum código ou conhecimento anterior, mas tem o potencial de se expandir para novas metodologias. O C ++ é, no final das contas, muito flexível, e ainda estou vendo um paradigma de design que não pode ser pelo menos simulado em C ++, enquanto é capaz de manter quase o controle total sobre o desempenho.


2

Se você está desenvolvendo para os consoles, não tem escolha: os SDKs profissionais são fornecidos apenas em versões C ++. Geralmente eles também têm acesso C à maioria das coisas.

Como muitos desenvolvedores são Consoles + PC, faz sentido fazer todo o trabalho no PC no mesmo idioma e compartilhar diretamente a tecnologia.

Como é aí que a indústria profissional mora, e a maioria das pessoas quer fazer parte disso, a maioria dos programadores de jogos é C ++.

Como tudo isso acontece, a maioria dos desenvolvedores de mecanismos também é C ++; portanto, ao avaliar mecanismos de nível profissional, quase todas as suas opções serão C ++.

É tudo um grande motor auto-sustentável. A interrupção exigiria mais do que apenas avanço técnico.


2

FWIW: C # está ganhando popularidade no desenvolvimento de jogos. Veja o post de Miguel de Icaza . Leitura muito interessante, IMHO.


2
Como sempre, Miguel pressiona suas tecnologias favoritas (geralmente marginais) enquanto ignora as maneiras pelas quais o C # realmente se tornou um grande participante na indústria, como o XNA.

2

Embora eu seja bastante anti-C, C & C ++, a única coisa que eles têm e que poucas outras linguagens têm é o controle completo da plataforma em que está rodando, você pode ter certeza exatamente do que estará acontecendo o tempo todo, não GC, sem falhas.

Hoje em dia, isso não é tão importante, mas pode ser para plataformas com pouca potência.

No PC / Mac / Linux, é provavelmente a linguagem menos portátil que você encontrará hoje em dia, e o bônus de velocidade não faz mais tanta diferença - o Minecraft (Java) é suave e funciona em plataformas mínimas (e em qualquer sistema operacional) com um único executável - ainda não vi um aplicativo C / C ++ de baixa mão de obra com tanta funcionalidade e poucos bugs, quanto mais trabalhar em três plataformas.

Então, neste momento, eu diria que a maior parte é inércia e a concepção de que jogos reais sempre são feitos em C / C ++, embora a capacidade de "portar" para o iPhone e os consoles seja significativa (embora eu tenha certeza de que a maioria da interface do usuário dos jogos exige muito esforço para portar, exceto entre Windows e XBox).


1
Ah, não sei se isso é importante apenas para plataformas "pouco poderosas". A outra maneira de analisar isso é que os jogos estão sempre na vanguarda do desempenho em qualquer plataforma: qualquer novo poder é imediatamente consumido. Se estamos falando de desenvolvimento profissional de jogos, o desempenho é praticamente a principal preocupação: você não escreve a Unreal sem maximizar cada último ciclo que a máquina tem a oferecer. Cada; solteiro; ciclo. Em todos os níveis, desde o mecanismo gráfico e o acesso ao disco até o loop da interface do usuário.
Chris Subagio

@ Chris: A melhor maneira que eu encontrei para descrevê-lo para programadores que não são de jogos é que os jogos são um domínio em que a velocidade é uma vantagem competitiva. Se o seu processador de texto iniciar em 5 segundos, quando o MS Word leva 10, ou refletir em 0,1 segundos, em que o Word leva 0,2, isso é inútil. Mas se o seu jogo conseguir bombear ainda mais 10% de fragmentos ou mostrar um personagem mais detalhado, isso pode ser uma enorme vantagem competitiva.

Então não seria bobo codificar alguma coisa além de montagem? Certamente seria pelo menos 10% mais rápido. Há um ponto em que você faz uma chamada para trocar o desempenho por manutenção e velocidade de desenvolvimento. Geralmente esse ponto é C ++ atualmente. Seria bom se a capacidade de ir para várias plataformas como o Minecraft tivesse mais peso.
Bill K

Ah, mas é uma falácia que a codificação em montagem seja mais rápida: os chips atuais são complexos o suficiente para que seja difícil para um programador superar um compilador de forma consistente. Somente em domínios mais restritos, como SPUs no PS3, loops e shaders de física interna nas GPUs ainda existem vantagens claras. Atualmente, o C ++ é realmente o ponto ideal, com a ressalva de que o OOP nem sempre é a melhor escolha: a discussão sobre Struct of Arrays vs Array of Structs não é exatamente uma discussão de linguagem, mas o C ++ claramente leva você ao AoS naturalmente; Às vezes ... você realmente quer apenas C.
Chris Subagio

A etapa na eficiência do programador entre assembler e C / C ++ também é uma ordem de magnitude maior que a etapa na eficiência do programador entre C e C ++, ou C ++ e C # / Java. Fred Brooks apontou isso há 25 anos.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.