É razoável escrever um mecanismo de jogo em C? [fechadas]

53

Mesmo que o C ++ pareça rei, pelo que me disseram, o C ainda é amplamente usado em jogos, especialmente nos consoles. No entanto, escrever um mecanismo de jogo inteiro em C seria irracional hoje? Quais são, se houver, algumas vantagens que C tem sobre C ++? Por que alguém possivelmente desejaria usar C sobre C ++?

Slurps Mad Rips
fonte
11
Jogos de console usam c ++ FYI!
Alan Wolfe
Na verdade, acho que C seria mais fácil escrever jogos em uma certa escala, digamos dezenas de milhares de LOC, mais ou menos, principalmente porque permite focar em bits e bytes sem tipos de dados complexos e cria super rápido em comparação com o C ++. Mas, depois de uma certa escala (digamos, atingir centenas de milhares de LOC), eu começaria a procurar o C ++, onde realmente desejaria tipos de dados complexos, mais segurança de tipo, possivelmente exceções, modelos e aumentaria ainda mais em escala (digamos milhões), para outras coisas que não C ++ para combinar com o código C e C ++.
O C também possui essa vantagem de ser amplamente portátil, mesmo para a ABI, tornando-se muito fácil pegar o código C existente e começar a usá-lo em outros idiomas a partir de, por exemplo, uma FFI. C ++ é um pouco mais estranho com a troca de nomes, incapacidade de passar com segurança pelos limites dos módulos, os representantes da vtable não são os mesmos nos compiladores, implementações de bibliotecas padrão diferentes entre fornecedores etc. Geralmente, acho que as bibliotecas C que escrevo duram mais sem a necessidade de alterações e ficando fora de moda, embora demore mais para escrever algo em escala com ele.

Respostas:

49

No entanto, escrever um mecanismo de jogo inteiro em C seria irracional hoje?

É razoável, mas a questão é: o que você compra? Você provavelmente não precisa da portabilidade extrema que o C oferece, e é uma pena renunciar a todos os recursos que o C ++ oferece, a menos que você esteja realmente filosoficamente contra isso.

Quais são, se houver, algumas vantagens que C tem sobre C ++?

Melhor tempo de compilação?

Por que alguém possivelmente desejaria usar C sobre C ++?

Eu acho que é principalmente uma escolha estética. Muitas pessoas gostam de C porque é simples e minimalista e se sente limpo. O C ++ possui muitos recursos interessantes (apenas espaços para nome valem a pena ser usados), mas também é grande e confuso.

maravilhoso
fonte
3
Até Id Tech 4
oculista
9
@ Josh: Mais fácil de depurar !? Os programas C são notoriamente difíceis de depurar, principalmente devido a ponteiros e gerenciamento de memória. Programas C ++ (ao usar idiomas de programação C ++ verdadeiros, que tendem a evitar ponteiros e gerenciamento de memória sempre que possível) são várias ordens de magnitude mais fáceis de depurar.
BlueRaja # Danny Pflughoeft 1/10/10
14
C pode ser entendido por meros mortais. O C ++ parece ter muitos recursos e casos avançados que os programadores experientes aprendem, mesmo após uma década de usá-lo todos os dias para viver.
Jari Komppa 14/01
13
C ++ é uma linguagem grande, mas sua reputação temível é disseminada principalmente por pessoas que acabaram de ler histórias de terror e não tiveram tempo para aprender. Há muito a aprender, mas você recebe muito valor em troca disso. O C ++ permite expressar muitas coisas que o C simplesmente não pode.
munificent
2
@ BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x)e agora você está depurando a memória. Com C ++ você nunca sabe o que vai ser alocado quando, porque há tantas maneiras de alocar memória (novo, malloc, construtores de classe, etc.)
YoYoYonnY
59

Eu trabalhei extensivamente com um mecanismo de jogo C puro que vendeu vários produtos, por isso é absolutamente possível. Aqui está minha experiência pessoal com o trabalho em ambos os mecanismos C vs C ++:

  1. O uso de estruturas C puro permite que você tire proveito do conhecimento sobre o alinhamento de estruturas e, em seguida, você pode usar essas informações para criar as camadas de persistência e serialização de objetos. O mecanismo com o qual trabalhei tinha alguns analisadores de cabeçalho simples que criariam automaticamente esses metadados sobre estruturas e tornaram triviais certos tipos de operações de dados. A análise de arquivos de cabeçalho C ++ arbitrários é essencialmente impossível e, assim que você adiciona herança e funções virtuais, perde a capacidade de saber exatamente onde as coisas estão na memória
  2. O tempo de compilação é significativamente menor, porque você pode manter os arquivos de cabeçalho muito compactos e tirar proveito das declarações de estruturas avançadas.
  3. A depuração pode ser aprimorada porque, sem o uso de modelos e herança, é muito fácil descobrir exatamente o que é um determinado objeto e o que ele está fazendo.

Todos esses benefícios também poderiam ser alcançados com a mesma facilidade usando o código c ++ restrito que evita o uso de modelos e herança em objetos serializados, mas a decisão do CTO era de que seria mais fácil reforçar a simplicidade se os elementos mais confusos do C ++ não fossem acessível.

Pessoalmente, acho que isso foi um pouco extremo, pois realmente perdi a capacidade de declarar variáveis ​​dentro de loops e os muitos usos completamente legítimos da herança. Mas, no final, não nos custou muita produtividade

Ben Zeigler
fonte
5
Não há realmente nada que o impeça de implementar a herança em C. E se você usar o C99, poderá declarar variáveis ​​para loops.
jsimmons
15
Discordando do ponto 3. É tão fácil escrever código desarrumado e difícil de depurar em C quanto em C ++. Melhor depuração não é algo inerente à linguagem C.
Dan Olson
7
Mesmo código limpo pode ser mais difícil de entender em C ++ - com sobrecarga, modelos, funções virtuais e exceções, é muito mais difícil ver rapidamente exatamente qual será o fluxo de controle real.
Kylotan
6
@ Dan: Simplesmente por ter mais coisas, o C ++ é mais difícil de depurar. Pode, claro, restringir-se de usar algum desse material, caso em que se torna tão fácil de depurar, como C - porque se torna C.
Na verdade, menos coisas é a razão pela qual eu gosto de C. Por exemplo, no CI, é possível copiar bits e bytes com a memcpypara qualquer coisa, porque o sistema de tipos não permite coisas como copiar ctors e dtors. Posso escrever código sabendo que não precisarei reverter os efeitos colaterais em quase qualquer linha de código, pois não posso sair implicitamente de uma função, a menos que eu a devolva explicitamente; não há exceções sendo lançadas. Tudo isso faz da escrita estruturas de dados muito mais fácil - em C ++ apenas escrevendo a-padrão compatível vectoré muito, especialmente se você quiser torná-lo demorado ...
18

Estou reescrevendo um mecanismo de jogo 2D escrito em C ++ e Lua em C e Lua. Até agora, a experiência tem sido muito boa. Obviamente, fazer operações vetoriais e matriciais não acaba com uma aparência agradável em C. Mas, além disso, eu achei a experiência bastante refrescante depois de passar mais de 10 anos como desenvolvedor de C ++.

C tem várias vantagens sobre o C ++:

  1. O compilador garantirá que nenhum código seja executado no momento da inicialização estática. Isso torna completamente seguro alocar estaticamente dados globais como strings usadas como chaves, por exemplo
  2. Transparência. Na atribuição C ou na alocação ou definição de uma variável, não haverá execução de cargas de código. O C ++ gerará automaticamente construtores de cópia para você, para que você tenha menos controle sobre o que é executado ao fazer a atribuição.
  3. Pode ser mais fácil fazer muita depuração devido a não obter nomes de funções mutilados
  4. Geralmente, não há problema em usar o memcpy em C, mas será fácil causar problemas no C ++, porque os construtores de cópia não serão executados. Dado que o memcpy é muito mais rápido que o std :: copy que importa.

Além disso, há uma série de vantagens em entrar no modo de pensar C. Em C ++, muitas vezes me vejo tornando as coisas um pouco generalizadas e abstratas. No IC, geralmente recortam coisas como métodos get-set e geralmente pré-alocam matrizes de tamanho fixo em vez de usar matrizes dinâmicas. Freqüentemente, acabo com um código menor e mais fácil de depurar em C. As estruturas de dados geralmente são mais planas e mais fáceis de visualizar em um depurador.

Para ser justo, eu nunca faria um aplicativo exclusivamente em C. A razão pela qual funciona é que eu o combino com uma linguagem de nível superior, como Lua, que pode complementar C muito bem, caso C não seja tão forte.

Id software escreve a maioria de seus mecanismos em CI acredita, você pode olhar para Return to castle Wolfenstein, que foi escrito em C.

Eu escrevi sobre algumas das minhas experiências em escalabilidade de C vs C ++ e desvantagens do vetor STL em comparação com matrizes simples.

Erik Engheim
fonte
11
Para sua informação, em todos os casos que verifiquei (que são, penso eu, darwin gcc e vc2008), o std :: copy será compilado apenas para uma chamada para o memcpy se os dois tipos forem POD.
BRaffle
3
Além disso, RE: STL vector vs matrizes simples, por que não usar as partes agradáveis ​​do vetor e usar ponteiros C normais em vez de iteradores, se você não gosta deles? Você pode fazer & myvector [N]. É como o melhor dos dois mundos, assumindo que o código C faça a alocação de memória da mesma maneira. Ou, para loops, confira BOOST_FOREACH. Torna ainda mais simples do que C.
BRaffle
11
Obrigado pela dica sobre std :: copy memcpy. Eu não sabia disso. Quando Alexandrescu tratou isso há alguns anos, não era o caso. Sobre os iteradores do C ++. É principalmente sobre a filosofia, tento programar como o C ++ deveria ser programa tanto para o bem das pessoas com quem trabalho quanto para tirar proveito dos recursos do C ++. Foi feito principalmente para salientar que algumas melhorias de C ++, como contêineres STL, nem sempre são melhores do que fazê-lo da maneira C antiga.
Erik Engheim
7

Como alguém apontou, o C ++ traz a vantagem de grandes ombros sobre os quais você pode se apoiar (BOOST, STL etc.). No final, é uma escolha pessoal, mas eu escolheria C ++ por causa dos recursos disponíveis. Se houver recursos em C ++ que você não deseja usar, não os use.

user266
fonte
11
Observe que 99% dos motores de jogos comerciais e internos se afastam do Boost e do STL por vários motivos (garantia de desempenho, depuração, segurança de threads, controle).
Kaj
42
E 99% das estatísticas são compostas.
BRaffle
Eu sinto que deveria ser uma regra citar todas as estatísticas.
Matt Jensen
3

Não acho que alguém use C exclusivamente hoje em dia, geralmente é misturado a um idioma de nível superior.

A programação em C tem alguns benefícios sobre, digamos, a programação em C ++. O C ++ pode fazer muitas coisas invisíveis para o usuário, o que pode prejudicar o desempenho se você não tomar cuidado. O C ++ também pode ser terrível quando se trata de uso de cache, o que novamente pode prejudicar seu desempenho.

Portanto, pode trazer alguns benefícios para escrever as partes críticas de desempenho de um jogo em modo C, em vez de em C ++ tradicional. Eu nunca ouvi falar de alguém, nos últimos anos, realmente escrevendo um jogo inteiro em C.

Em algumas plataformas, como o iPhone, o uso do C ++ pode aumentar o tamanho do seu executável com um certo pedaço de kilobytes (esqueci quanto, desculpe), razão pela qual alguns desenvolvedores do iPhone optam por escrever seu código em uma combinação de C e Objective -C.

Sander van Rossen
fonte
3

Vou lhe dar mais algumas razões pelas quais não seria razoável escrever um mecanismo de jogo em C em vez de C ++ hoje: STL e BOOST.

Não consigo imaginar como valeria a pena escrever mais uma listimplementação quando você pudesse confiar no código que funciona imediatamente (e que você não precisa escrever!)

Loris
fonte
11
Algum grande estúdio realmente usa impulso? Até o uso do STL ainda está em debate, devido à portabilidade. Pelo menos para os mecanismos de console.
Slicedlime 16/07/10
2
Pessoalmente, estou usando Boost.FunctionTypes para interação c ++ / lua (consulte gamedev.net/reference/programming/features/CPPLuaExport/… ) e a biblioteca de números aleatórios Boost para geração uniforme de números aleatórios (para sistemas de partículas). Além disso, o Boost.Foreach é elegante. BTW, quem se importa se os grandes estúdios não estiverem usando o BOOST? Eles têm mão de obra para escrever suas próprias bibliotecas STL do zero, não tenho.
Loris
11
Sim, mas também percebemos que existem bibliotecas semelhantes para C também.
jsimmons
2
Muitas pessoas usam impulso nos jogos, acredito. Mas está longe de ser um requisito (ou mesmo desejável) para muitos de nós.
Dan Olson
6
Gente, o que você acha que é irrelevante: você sabe ou não .
o0 '.
3

Escrever um mecanismo de jogo em C é razoável. É rápido e pode ser portado para vários sistemas. Por exemplo, você pode usar para Android (com o uso do NDK). Você pode usá-lo para o iPhone (o objetivo c é apenas uma extensão de c). Você também pode usá-lo para e do sistema operacional principal, como Linux, Mac ou Windows. Se você se sentir confortável com c, sugiro que tente!

Luke Taylor
fonte
2

Claro que é razoável. Eu pessoalmente não faria isso, e a maioria dos fãs de C que conheço na verdade apenas escreve código semelhante a C em arquivos .cpp. Mas os idiomas são semelhantes o suficiente para onde realmente não importa.

Quanto ao motivo pelo qual alguém escolheria fazer isso, acho que se deve principalmente à filosofia anti-C ++. Pessoalmente, ainda não acho que essa seja uma boa razão para escolher C em "C-style C ++". a loucura do typedef struct é uma razão suficientemente boa para se afastar de C, e existem vários outros.

Infelizmente, C e C ++ são linguagens terríveis quando chegamos a esse ponto. Essa é uma das razões pelas quais as pessoas têm tentado fazer muito do código em script nos últimos anos.

Se você está procurando exemplos de pessoas que trabalham em C, pode ignorar o id, já que lembro de ler que elas abandonaram C há muito tempo. Porém, a Cryptic Studios (Star Trek Online) faz todo o desenvolvimento de seus motores em C. Pelo que sei, sim, é mais por causa da filosofia do que por qualquer vantagem tangível.

Dan Olson
fonte
0

Sim e não. Sim, eu fiz isso alguns anos atrás, mas eu precisava do meu jogo para rodar em 3D em um servidor remoto unix (não linux) de 64 bits com os jogadores em terminais burros. Não foi trivial. C pode ser legal é que você deseja integrar o LUA, mas eu finalmente consegui lua para trabalhar em C ++, então eu diria que sim, é possível, mas não o faça.

Jeff
fonte
0

Uma possível boa resposta pode ser "use both"?

Como ouvi dizer que os projetos do panda3d poderiam ser otimizados, eliminando gargalos usando algum cython ou recodificando essas partes.

Na maioria das vezes, as partes que precisam ser otimizadas são aquelas com muitas iterações e aninhamentos ou com muita computação numérica, então meu palpite (selvagem) é que um compromisso justo seria usar os dois idiomas, usando C para partes que incluem muita programação de baixo nível; portanto, você não pode fazer mau uso da linguagem C ++ para a parte que precisa de velocidade e C ++ para o restante do jogo.

Idealmente, você faz a parte rápida do mecanismo mantendo o alto nível em mente e depois usa uma linguagem de script ou C ++ que usará muito menos nest / loops.

É claro que você nunca poderia criar um mecanismo que fosse adequado para todos os desenvolvedores de jogos, exceto se você o dedicasse a um tipo especial de jogo ...

Mas não tome meu conselho como garantido, já que não sou desenvolvedor de jogos nem desenvolvedor experiente ... Acho que C obriga você a escrever código rápido, enquanto escreve código C ++ bom e rápido para um projeto tão grande quanto um jogo é uma coisa diferente ...

jokoon
fonte
0

O código C é normalmente um código C ++ válido.

Os principais problemas do C ++ são usá-lo incorretamente ( Linus Torvalds o odeia por esse motivo , ele também teve outros problemas com a portabilidade de bibliotecas e, por isso, compra ele está trabalhando no nível de sistemas operacionais e deve ser capaz de executar as coisas de forma aleatória chip lá fora).

Por exemplo, quase não há vantagem em usar uma matriz cstyle [] em vez de um c ++ std :: vector <> (ou recipiente semelhante).

Os vetores são tipicamente seguros e podem ser verificados dentro dos limites (você pode acessar os elementos usando get () ou [], mesmo se você não usar o método de matriz marcada, ainda poderá consultar o tamanho em vez de carregá-lo com o ponteiro.

Mas os vetores podem ser mais lentos se, por exemplo, você não declarar o tamanho padrão no construtor. A adição de itens a um vetor pode causar lentidão se for necessário redimensionar. O C ++ 11 também oferece muitas vantagens, como inicialização uniforme (agora você pode declarar e inicializar vetores usando a mesma sintaxe) e existem construtores de movimentação que permitem evitar a cópia. Você pode até criar seus próprios inicializadores personalizados (se quiser fazer algo diferente de usar o malloc por algum motivo).

Ou, é claro, se você precisar redimensionar as coisas, os vetores ainda serão mais fáceis de fazer, você não precisará mexer com o malloc, copiar manualmente as coisas e assim por diante.

C ++ fornece código orientado a objeto. Quando compilado, será igualmente eficiente, pois é apenas uma abstração para os humanos que trabalham com o código. Embora coisas como construtores possam retardar a criação de objetos. Mas você precisará do construtor para definir os valores padrão ou poderá inicializar objetos sem usar o construtor (deixando de fora os ()).

Mas a orientação a objetos facilita muito a programação de jogos . Os jogos costumam lidar com objetos.

David C. Bishop
fonte