Est-il raisonnable d'écrire un moteur de jeu en C? [fermé]

53

Même si C ++ semble être roi, d'après ce que l'on m'a dit, C est encore largement utilisé dans les jeux, en particulier sur les consoles. Cependant, l'écriture d'un moteur de jeu entier en C serait-elle déraisonnable aujourd'hui? Quels sont, le cas échéant, certains avantages du C par rapport au C ++? Pourquoi quelqu'un voudrait-il éventuellement utiliser C sur C ++?

Slurps Mad Rips
la source
1
Les jeux de console utilisent c ++ FYI!
Alan Wolfe
Je pense en fait que C serait plus facile d’écrire des jeux jusqu’à une certaine échelle, disons des dizaines de milliers de LOC, notamment parce que cela vous permet de vous concentrer sur les bits et les octets sans types de données complexes et de construire très rapidement par rapport au C ++. Mais après une certaine échelle (atteignant des centaines de milliers de LOC), je voudrais commencer à rechercher le C ++ où je commencerais à vouloir des types de données complexes, davantage de sécurité de type, peut-être des exceptions, des modèles et une taille encore plus grande. scale (disons des millions), pour combiner des éléments autres que C ++ avec le code C et C ++.
C a aussi l’avantage supplémentaire d’être très portable, même pour ABI. Il est donc assez facile de prendre votre code C existant et de commencer à l’utiliser dans d’autres langues, par exemple, d’une FFI. Le C ++ est un peu plus délicat avec la manipulation de noms, l'impossibilité de passer outre les limites des modules, les représentants de vtable n'étant pas les mêmes parmi les compilateurs, les implémentations de bibliothèques standard différentes d'un fournisseur à l'autre, etc. sortir du style, mais il faut plus de temps pour écrire quelque chose d'échelle avec elle.

Réponses:

49

Cependant, l'écriture d'un moteur de jeu entier en C serait-elle déraisonnable aujourd'hui?

C'est raisonnable, mais la question est: que vous achète-t-il? Vous n'avez probablement pas besoin de la portabilité extrême proposée par C, et il est dommage d'abandonner toutes les fonctionnalités offertes par C ++, à moins que vous ne vous y opposiez vraiment.

Quels sont, le cas échéant, certains avantages du C par rapport au C ++?

Meilleur temps de compilation?

Pourquoi quelqu'un voudrait-il éventuellement utiliser C sur C ++?

Je pense que c'est surtout un choix esthétique. Beaucoup de gens aiment C parce que c'est simple et minimal et qu'il se sent propre. Le C ++ a beaucoup de fonctionnalités intéressantes (les espaces de noms le rendent intéressant à utiliser), mais il est également volumineux et désordonné.

munificent
la source
3
Jusqu’à Id Tech 4
opticien le
9
@Josh: Plus facile à déboguer!? Les programmes C sont notoirement difficiles à déboguer, principalement à cause des pointeurs et de la gestion de la mémoire. Les programmes C ++ (lorsque vous utilisez de vrais idiomes de programmation C ++, qui tendent à éviter les pointeurs et la gestion de la mémoire autant que possible) sont beaucoup plus faciles à déboguer de plusieurs ordres de grandeur .
BlueRaja - Danny Pflughoeft
14
C peut être compris par de simples mortels. C ++ semble avoir de nombreuses fonctionnalités et les programmeurs chevronnés découvrent même après une décennie d'utilisation quotidienne.
Jari Komppa le
13
Le C ++ est un grand langage, mais sa réputation redoutable est principalement transmise par des personnes qui viennent de lire des histoires d'horreur et qui n'ont pas pris le temps de les apprendre. Il y a beaucoup à apprendre, mais vous en retirez beaucoup. C ++ vous permet d'exprimer beaucoup de choses que C ne peut tout simplement pas.
magnifique
2
@ BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x)et vous êtes en train de déboguer la mémoire. Avec C ++, vous ne savez jamais ce qui sera alloué quand, car il y a tant de façons d'allouer de la mémoire (new, constructeurs de classe, malloc, classe, etc.)
YoYoYonnY le
59

J'ai beaucoup travaillé avec un moteur de jeu en pur-C qui a livré plusieurs produits, c'est donc tout à fait possible. Voici mon expérience personnelle de travail dans les deux moteurs C vs C ++:

  1. L'utilisation de structures en pur-C vous permet de tirer parti des connaissances relatives à l'alignement des structures. Vous pouvez ensuite utiliser ces informations pour créer vos couches de persistance et de sérialisation des objets. Le moteur avec lequel je travaillais avait quelques analyseurs d'en-tête simples qui créeraient automatiquement ces métadonnées sur les structures et rendaient certains types d'opérations de données triviaux. L'analyse de fichiers d'en-tête C ++ arbitraires est en principe impossible, et dès que vous ajoutez l'héritage et les fonctions virtuelles, vous perdez la possibilité de savoir exactement où se trouvent les éléments en mémoire.
  2. Le temps de compilation est considérablement réduit car vous pouvez conserver des fichiers d’en-tête très compacts et tirer parti des déclarations en aval des structures.
  3. Le débogage peut être amélioré car, sans l'utilisation de modèles et d'héritage, il est très facile de comprendre exactement ce qu'est un objet et ce qu'il fait.

Tous ces avantages pourraient également être obtenus tout aussi facilement en utilisant du code restreint c ++ qui évite d'utiliser des modèles et l'héritage sur des objets sérialisés, mais le CTO a décidé qu'il serait plus facile d'appliquer la simplicité si les éléments les plus confus du C ++ n'étaient pas gênants. disponible.

Personnellement, je pense que c’était un peu extrême, car j’ai vraiment manqué la possibilité de déclarer de manière saine les variables dans les boucles for et les nombreuses utilisations tout à fait légitimes de la succession. Mais cela ne nous a vraiment pas coûté beaucoup de productivité à la fin, tout compte fait

Ben Zeigler
la source
5
Rien ne vous empêche vraiment de mettre en œuvre l'héritage en C. Et si vous utilisez C99, vous pouvez déclarer des variables dans les boucles for.
Jsimmons
15
Ne pas être d'accord avec le point 3. Il est tout aussi facile d'écrire du code compliqué et difficile à déboguer en C que dans C ++. Mieux déboguer n’est pas inhérent au langage C.
Dan Olson
7
Même le code propre peut être plus difficile à comprendre en C ++ - avec la surcharge, les modèles, les fonctions virtuelles et les exceptions, il est beaucoup plus difficile de voir d'un coup d'œil exactement ce que sera le flux de contrôle réel.
Kylotan
6
@ Dan: Simplement en ayant plus de choses, C ++ est plus difficile à déboguer. Vous pouvez bien sûr vous restreindre à l’utilisation de ces éléments. Dans ce cas, il devient aussi facile de déboguer que C - car il devient C.
La raison pour laquelle j’aime bien le moins, c’est en fait moins. Par exemple, dans CI, vous pouvez simplement copier des bits et des octets avec un memcpypour rien, car le système de types n’autorise pas les choses telles que les copieurs et les dépositaires. Je peux écrire du code en sachant que je n'aurai pas à annuler les effets secondaires sur presque n'importe quelle ligne de code, car je ne peux pas implicitement quitter une fonction à moins d'en sortir explicitement. il n'y a pas d'exception à lancer. Tout cela facilite grandement l’écriture de structures de données: en C ++, écrire une application conforme à la norme vectorprend beaucoup de temps, surtout si vous voulez le rendre ...
18

Je suis en train de réécrire un moteur de jeu 2D écrit en C ++ et Lua en C et Lua. Jusqu'à présent, l'expérience a été plutôt bonne. Évidemment, les opérations sur les vecteurs et les matrices ne sont pas aussi agréables en C. Mais à part cela, j'ai trouvé l'expérience très rafraîchissante après avoir passé plus de 10 ans en tant que développeur C ++.

C présente de nombreux avantages par rapport au C ++:

  1. Le compilateur s'assurera qu'aucun code n'est exécuté au moment de l'initialisation statique. Cela rend totalement sûr d'allouer statiquement des données globales telles que des chaînes utilisées comme clés, par exemple
  2. Transparence. En C, l'affectation ou l'attribution ou la définition d'une variable ne va pas entraîner l'exécution de charges de code. C ++ générera automatiquement des constructeurs de copie pour que vous ayez moins de contrôle sur ce qui est exécuté lors de l'affectation.
  3. Il peut être plus facile de déboguer beaucoup car les noms de fonction ne sont pas mutilés
  4. Il est généralement acceptable d’utiliser memcpy en C, mais cela causera facilement des problèmes en C ++, car les constructeurs de copie ne seront pas exécutés. Étant donné que memcpy est beaucoup plus rapide que std :: copy, cela compte.

En dehors de cela, il y a un certain nombre d'avantages à entrer dans la façon de penser de C. En C ++, je suis souvent en train de rendre les choses un peu trop générales et abstraites. Dans CI, supprimez généralement des méthodes telles que get-set et préallouez souvent des tableaux de taille fixe plutôt que d’utiliser des tableaux dynamiques. Souvent, je me retrouve avec un code plus court et plus facilement débogué en C. Les structures de données sont généralement plus plates et plus faciles à visualiser dans un débogueur.

Pour être juste, je ne ferais jamais une application exclusivement en C. La raison pour laquelle cela fonctionne c'est que je la combine avec un langage de niveau supérieur comme Lua, qui peut très bien compléter le C si C n'est pas si fort.

Le logiciel Id écrit la plupart de leurs moteurs dans CI, vous pouvez regarder Return to castle Wolfenstein qui a été écrit en C.

J'ai écrit sur une partie de mon expérience concernant l' évolutivité de C vs C ++ et les inconvénients du vecteur STL par rapport aux tableaux ordinaires.

Erik Engheim
la source
11
Pour votre information, dans chaque cas que j’ai vérifié (c’est-à-dire darwin gcc et vc2008), std :: copy compilera simplement un appel à memcpy si les deux types sont POD.
Braffle
3
En outre, RE: STL vector vs plain arrays, pourquoi ne pas utiliser les belles parties de vector et utiliser des pointeurs C normaux au lieu d’itérateurs, si vous ne les aimez pas? Vous pouvez simplement faire & myvector [N]. C'est comme le meilleur des deux mondes, en supposant que votre code C attribue la mémoire de la même manière. Ou, dans les boucles, consultez BOOST_FOREACH. C'est encore plus simple que C.
Braffle
1
Merci pour le conseil sur std :: copy memcpy. Je ne savais pas ça. Quand Alexandrescu a traité cela il y a quelques années, ce n'était pas le cas. À propos des itérateurs C ++. Il s’agit principalement de philosophie; j’essaie de montrer comment le C ++ était censé être un programme destiné à la fois aux personnes avec lesquelles je travaille et aux avantages de ses fonctionnalités. Il a été principalement fait remarquer que certaines améliorations de C ++ telles que les conteneurs STL ne sont pas toujours meilleures que de le faire à l'ancienne.
Erik Engheim
7

Comme quelqu'un l'a fait remarquer, le C ++ apporte l'avantage des larges épaules sur lesquelles vous pouvez vous appuyer (BOOST, STL, etc.). En fin de compte, c'est un choix personnel, mais je choisirais le C ++ en raison des ressources disponibles. Si vous ne souhaitez pas utiliser certaines fonctionnalités de C ++, ne les utilisez pas.

utilisateur266
la source
1
Notez que 99% des moteurs de jeux commerciaux et internes s'éloignent de Boost et de STL pour diverses raisons (garantie de performances, capacité de débogage, sécurité des threads, contrôle).
Kaj
42
Et 99% des statistiques sont constituées.
Braffle
Je pense qu'il devrait être en quelque sorte une règle de citer toutes les statistiques.
Matt Jensen
3

Je ne pense pas que quiconque utilise le C exclusivement ces jours-ci, il est généralement mélangé avec un langage de niveau supérieur.

La programmation en C présente certains avantages par rapport à la programmation en C ++. C ++ peut faire beaucoup de choses invisibles pour l'utilisateur, ce qui peut nuire aux performances si vous ne faites pas attention. C ++ peut aussi être terrible en ce qui concerne l'utilisation du cache, ce qui peut encore nuire à vos performances.

Il peut donc être avantageux d’écrire les parties critiques du jeu d’un point de vue du C, plutôt que du C ++ traditionnel. Je n'ai jamais entendu parler de personne, ces dernières années, écrivant un jeu entier en C cependant.

Sur certaines plates-formes, comme l'iPhone, l'utilisation de C ++ peut augmenter la taille de votre exécutable avec une certaine quantité de kilo-octets (j'ai oublié combien, désolé), ce qui explique pourquoi certains développeurs iPhone choisissent d'écrire leur code dans un mélange de C et Objective. -C.

Sander van Rossen
la source
3

Je vais vous donner deux autres raisons pour lesquelles il serait déraisonnable d'écrire un moteur de jeu en C au lieu de C ++ aujourd'hui: STL et BOOST.

Je ne peux pas imaginer à quel point il serait utile d'écrire une autre listimplémentation lorsque vous pouvez utiliser un code qui fonctionne immédiatement (et que vous n'avez pas à écrire!)

Loris
la source
1
Est-ce qu'un grand studio utilise réellement boost? Même l’utilisation du format STL fait toujours l’objet d’un débat en raison de sa portabilité. Au moins pour les moteurs de console.
slicedlime
2
Personnellement, j'utilise Boost.FunctionTypes pour l'interaction c ++ / lua (voir gamedev.net/reference/programming/features/CPPLuaExport/… ) et la bibliothèque de nombres aléatoires Boost pour la génération de nombres aléatoires uniformes (pour les systèmes de particules). En outre, Boost.Foreach est soigné. BTW, qui se soucie si les grands studios n'utilisent pas BOOST? Ils ont la main-d'œuvre pour écrire leurs propres bibliothèques STL à partir de zéro, pas moi.
Loris
1
Oui, mais réalisons également qu'il existe des bibliothèques similaires pour C également.
Jsimmons
2
Je crois que beaucoup de gens utilisent boost dans les jeux. Mais c'est loin d'être une exigence (ou même souhaitable) pour beaucoup d'entre nous.
Dan Olson
6
Les gens, ce que vous croyez est sans importance: soit vous savez, soit vous ne savez pas .
o0 '.
3

Ecrire un moteur de jeu en C est raisonnable. C'est rapide et peut être porté sur plusieurs systèmes. Par exemple, vous pouvez utiliser pour Android (avec l’utilisation du NDK). Vous pouvez l'utiliser pour l'iPhone (Objective c n'est qu'une extension de c). Vous pouvez également l'utiliser pour et des systèmes d'exploitation principaux tels que Linux, Mac ou Windows. Si vous vous sentez à l'aise avec c, je vous suggère de l'essayer!

Luke Taylor
la source
2

Bien sûr que c'est raisonnable. Personnellement, je ne le ferais pas, et la plupart des fans de C que je connais ne font qu’écrire du code de type C dans des fichiers .cpp. Mais les langues sont assez similaires à l'endroit où cela n'a pas d'importance.

En ce qui concerne la raison pour laquelle quelqu'un choisirait de faire cela, je pense que c'est principalement dû à la philosophie anti-C ++. Personnellement, je ne pense toujours pas que ce soit une bonne raison de choisir C plutôt que "C-style C ++". La folie typedef struct est une raison suffisante pour éviter C, et il en existe plusieurs autres.

Malheureusement, le C et le C ++ sont des langages assez terribles quand on y arrive. C'est une des raisons pour lesquelles les gens ont essayé de faire beaucoup de leur code dans un script ces dernières années.

Si vous recherchez des exemples de personnes travaillant en C, vous pouvez ignorer id. Je me souviens d'avoir lu qu'elles avaient abandonné C depuis longtemps. Cryptic Studios (Star Trek Online) fait tout son développement moteur en C, cependant. Autant que je sache, oui, c'est davantage à cause de la philosophie que de tout avantage tangible.

Dan Olson
la source
0

Oui et non. Oui, je l’ai fait il ya quelques années, mais j’avais besoin que mon jeu fonctionne en 3D sur un serveur distant 64 bits unix (et non pas Linux) avec les lecteurs sur des terminaux muets. C'était non trivial. C peut être sympa si vous voulez intégrer LUA, mais j’ai finalement eu à travailler avec C ++, alors je dirais que c’est possible, mais ne le faites pas.

Jeff
la source
0

Une bonne réponse possible pourrait-elle être "utiliser les deux"?

Lorsque j'ai entendu dire que les projets panda3d pourraient être optimisés, éliminer les goulets d'étranglement en utilisant du cython ou en recodant ces parties.

La plupart du temps, les parties qui doivent être optimisées sont celles qui comportent de nombreuses itérations et imbrications ou beaucoup d’informatique numérique. Je suppose donc que le meilleur choix est qu’un compromis raisonnable consisterait à utiliser les deux langages, en utilisant C pour les parties qui incluent beaucoup de programmation de bas niveau, vous ne pouvez donc pas utiliser abusivement le langage C ++ pour la partie qui nécessite de la vitesse, et le C ++ pour le reste du jeu.

Idéalement, vous faites la partie rapide du moteur en gardant à l’esprit le niveau élevé, puis vous utilisez un langage de script ou C ++ qui utilise beaucoup moins de boucles imbriquées / nid.

Bien sûr, vous ne pourriez jamais créer un tel moteur qui conviendrait à tous les développeurs de jeux, sauf si vous dédiez votre moteur à un type de jeu spécial ...

Mais ne prenez pas mes conseils pour acquis, car je ne suis ni développeur de jeux ni expérimenté ... Je pense que C vous oblige à écrire du code rapide, tout en écrivant du code C ++ bon et rapide pour un projet aussi gros qu'un jeu est une chose différente ...

jokoon
la source
0

C a travaillé pour John Carmack , l’utilisation de C pourrait vous procurer de nombreux avantages, mais tant que vous n’y arriverez pas pour en tirer parti, il vous faudra peut-être un peu de temps.

Vous trouverez ici une liste de moteurs de jeu. Certains d’entre eux sont écrits en C, vous pouvez peut-être vous expliquer comment utiliser un moteur de jeu C en consultant leur code source.


la source
0

Le code C est normalement un code C ++ valide.

Les principaux problèmes avec C ++ l'utilisent de manière incorrecte ( Linus Torvalds le déteste pour cette raison , il avait également d'autres problèmes avec la portabilité des bibliothèques et, par conséquent, il travaille au niveau des systèmes d'exploitation et doit pouvoir exécuter des tâches de manière aléatoire. chip out là-bas).

Par exemple, l'utilisation d'un tableau cstyle [] par rapport à un c ++ std :: vector <> (ou un conteneur similaire) ne présente presque aucun avantage.

Les vecteurs sont typés et peuvent être vérifiés (vous pouvez accéder aux éléments avec get () ou [], même si vous n'utilisez pas la méthode array check, vous pouvez toujours interroger la taille plutôt que de la transporter avec le pointeur).

Mais les vecteurs peuvent être plus lents si, par exemple, vous ne déclarez pas la taille par défaut dans le constructeur. De plus, l'ajout d'éléments à un vecteur peut provoquer des ralentissements s'il nécessite un redimensionnement. C ++ 11 ajoute également de nombreux avantages, tels que l'initialisation uniforme (vous pouvez maintenant déclarer et initialiser des vecteurs en utilisant la même syntaxe) et certains constructeurs de déplacement peuvent vous permettre d'éviter la copie. Vous pouvez même créer vos propres initialiseurs personnalisés (si vous vouliez faire autre chose que d’utiliser malloc pour une raison quelconque).

Bien sûr, si vous avez besoin de redimensionner des éléments, les vecteurs sont toujours plus faciles à utiliser, vous n'avez pas à vous soucier de malloc, de copier manuellement des éléments, etc.

C ++ vous donne un code orienté objet. Une fois compilé, il sera tout aussi efficace car il s’agit en réalité d’une simple abstraction pour les utilisateurs du code. Bien que des choses comme les constructeurs puissent ralentir la création d’objets. Mais vous aurez besoin soit du constructeur pour définir les valeurs par défaut, soit vous pouvez initialiser des objets sans utiliser le constructeur (en laissant de côté les ()).

Mais l'orientation des objets facilite beaucoup la programmation des jeux . Les jeux traitent souvent d'objets.

David C. Bishop
la source