En concurrence avec C ++ pour la programmation de jeux

21

Je suis curieux de savoir pourquoi C ++ est si populaire pour le développement de jeux, et pas d'autres langages à la place. Je sais que vous pouvez créer du code très rapidement avec lui, mais qu'est-ce qui le rend populaire?

Est-ce juste parce que c'est rapide? Est-ce une autre fonctionnalité du langage, comme le paradigme OO ou la portabilité? Est-ce à cause de toutes les bibliothèques qui ont été créées au fil du temps? Ou une combinaison de toutes ces raisons (et d'autres)?

Si quelqu'un pouvait me renseigner là-dessus, je serais très heureux. :-)

KasMA1990
la source
7
La vitesse est une raison suffisante pour moi, d'autant plus que les plaintes de tous sur la langue n'ont pas vraiment de sens pour moi.
Benjamin Lindley
Une supposition rapide: la plupart des jeux sont écrits pour Windows. Les langages C et C ++ ont été fortement pris en charge par Microsoft. Enfin, le C ++ est préféré en raison de la POO et de la métaprogrammation des modèles.
@ Matt Merci, je ne savais pas qu'il existait. Puis-je déplacer le sujet là-bas, ou dois-je supprimer celui-ci et le recréer là-bas?
Cela a déjà été demandé à plusieurs reprises.
Zan Lynx
1
@Benjamin: Alors j'ose dire que vous n'avez pas assez écrit en C ++, ou que vous n'avez jamais utilisé un langage plus expressif comme Python (ou même C # avec LINQ). Cependant, même si pour une raison folle vous préférez écrire du code de 20 lignes pour ce que de nombreux autres langages peuvent faire en 1, la grammaire extrêmement pauvre de C ++ signifie que les programmes prennent beaucoup plus de temps à compiler qu'ils ne le devraient, et les outils IDE appropriés (refactoring, etc.) sont plus difficiles, sinon impossibles, à créer.
BlueRaja - Danny Pflughoeft

Réponses:

29

De nombreuses raisons:

  • Grand que vous avez manqué: il est portable, simplifiant les ports de votre moteur de jeu vers iOS, XBOX, PS3, peu importe
  • C'est rapide
  • Tous les SDK le supportent nativement
  • Beaucoup de bibliothèques disponibles
  • Tout le monde écrit des jeux le sait, il est donc facile d'embaucher des développeurs de jeux expérimentés pour votre équipe
  • Il est trivial d'intégrer un langage de script de moteur de jeu comme Lua

la source
Très bien, merci pour vos réponses à tous, vous avez couvert tout ce dont j'avais besoin, je pense. :-)
KasMA1990
14

Il y a plusieurs raisons que j'aimerais mentionner en plus de ce que @Graham a évoqué.

  • Legacy Code - de nombreux studios ont beaucoup de code C ++, va à votre mention de bibliothèques.
  • C ++ est vraiment un assembleur de haut niveau, et a un accès direct au matériel (aussi direct que possible au moins sur un système d'exploitation) et est assez rapide. Si vous le souhaitez, en C ++, vous pouvez descendre directement dans le langage d'assemblage pour le contrôle du niveau d'instruction (pas que ce soit toujours sage, ce n'est tout simplement pas possible avec Java, C #, Python, etc.)
  • DirectX et OpenGL supportent nativement C ++, la plupart des autres langages ont des "liaisons" aux bibliothèques sous-jacentes via des couches intermédiaires, cela ne veut pas dire qu'ils ne sont pas rapides ou ne peuvent pas faire beaucoup des mêmes choses, mais il ajoute une couche de logiciel entre votre jeu et le matériel.
  • Comme @Graham le mentionne, de nombreux programmeurs le savent, il est donc facile de trouver des développeurs expérimentés et il est également assez portable, par rapport à C # qui est bloqué sur le .NET Framework (il y a Mono, mais il est généralement à la traîne d'une génération derrière l'implémentation de Microsoft .)
Nate
la source
Vous ne voulez pas dire de bas niveau?
jhocking le
5
C ++ est un low-levellangage; mais un high-levelassembleur, l'OMI.
Nate
3
Je ne suis pas d'accord. C ++ est un langage de haut niveau, avec la fonction intégrée pour se replier sur C (qui est un langage de bas niveau).
foo
7
C ++ est un langage de haut niveau, tout comme C. L'assemblage est de bas niveau. Maintenant, C ++ est de niveau supérieur à C, tout comme C # est supérieur à C ++ et Ruby / Python sont supérieurs à C #.
AA Grapsas
4
Pourquoi le code hérité devrait-il être déprécié (non amorti)? «Code hérité» signifie simplement qu'il est ancien, pas qu'il soit mauvais.
8

La vitesse brute est la principale raison, mais en fait, ce n'est pas une décision ou alors de nombreuses sociétés de jeux commencent à utiliser d'autres langues pour certaines parties du jeu. Certaines tâches nécessitent que l'ordinateur fonctionne le plus rapidement possible (par exemple, les routines de rendu de base), mais de nombreuses tâches dans le code de gameplay n'ont pas à s'exécuter aussi rapidement (par exemple, ouvrir la porte lorsque le joueur clique dessus), ce qui signifie que est intelligent d'utiliser un langage beaucoup plus simple (et donc plus rapide pour écrire des programmes) pour ces parties. C'est pourquoi de nombreux moteurs de jeu sont écrits en C ++ mais intègrent un langage de script comme Lua pour écrire du code de gameplay.

La chose délicate à comprendre est que lors du choix des langages de programmation, il y a un compromis global entre l'efficacité pour l'ordinateur et l'efficacité pour le programmeur. Autrement dit, ce qui est plus important pour vous, à quelle vitesse l'ordinateur exécute le code ou à quelle vitesse le programmeur écrit-il le code?

jhocking
la source
3

En C ++, vous pouvez allouer des variables locales qui disparaissent après la fin de la fonction. Habituellement, ceux-ci sont alloués sur une pile.

Les variables de pile ne contribuent pas aux problèmes d'allocation de mémoire dynamique de fragmentation et de surcharge. Allouer de la place sur la pile est rapide et facile (il suffit de régler un pointeur). L'allocation dynamique de mémoire implique généralement de rechercher dans un conteneur un bloc de mémoire adéquat, de marquer la mémoire, puis de la marquer comme occupée. La désallocation implique l'ajout du bloc de mémoire à un conteneur, et éventuellement sa fusion avec des blocs existants. Beaucoup plus de frais généraux que de simplement changer un pointeur.

Java et C # allouent la mémoire dynamiquement, sauf pour les types primitifs. Ces langages dépendent d'un environnement d'exécution qui marquera une variable à supprimer, puis exécutera un garbage collector à des intervalles aléatoires (non planifiés) pour récupérer la mémoire. En général, le programmeur n'a aucun contrôle sur le moment où la variable sera balisée pour la suppression ni quand elle sera récupérée (la récupération de la mémoire utilisée est un sujet avancé que la plupart des programmeurs C ++ et Java ne connaissent pas).

La vitesse de C ++ est principalement due à sa traduction directe en code exécutable. Java et C # sont compilés en un code intermédiaire qui est ensuite interprété par une machine virtuelle. En général, les langues interprétatives sont plus lentes que les langues directement traduites.

Thomas Matthews
la source
1
-1 (si je le pouvais) - les primitives locales sont allouées sur la pile en Java et en C #, et en C #, vous pouvez créer des piles allouées structs. Plus précisément, la très très augmentation de petite vitesse ce filets vous n'est pas presque assez pour justifier une langue sur l'autre. La vraie raison est indiquée par @Graham Perks: c'est ce que les développeurs de jeux sont censés savoir, c'est donc ce que les nouveaux développeurs de jeux apprennent, et à quoi s'adressent les nouveaux SDK. Il y a beaucoup de langues (ex. Go) qui sont tout aussi rapide ou plus rapide, et non presque aussi peu pratique à écrire.
BlueRaja - Danny Pflughoeft
C ++ n'est pas très bon pour l'allocation de pile; en fait, il est très difficile d'allouer des objets compatibles STL sur la pile. Par exemple, le dernier gros moteur sur lequel j'ai travaillé était en C, et nous avions une chaîne que vous pouviez démarrer sur la pile à une taille fixe (généralement 1K). S'il dépassait, il se déplaçait de manière transparente vers le tas. Vous pouvez faire des choses similaires avec les allocateurs personnalisés std :: string en C ++, mais le code est tellement plus difficile à obtenir correctement.
1
@Joe Wreschnig: C ++ est excellent pour l'allocation de pile, il suffit de vider une liste de langage d'assemblage. Cependant, la plupart des fournisseurs de compilateurs n'allouent pas une énorme quantité de mémoire à la pile. Une compréhension commune des programmeurs C ++ expérimentés est que les objets énormes sont alloués dynamiquement (tas) et non le stockage local (pile). Des objets énormes sur la pile peuvent envahir le tas sur certaines plates-formes à mesure que la pile et le tas se rapprochent.
Thomas Matthews
1
Une compréhension commune des programmeurs C ++ plus expérimentés, en particulier ceux des consoles de jeu, est que tout ce qui ne dépassera pas la pile est alloué ou préalloué. C facilite cela car l'allocateur ne fait pas partie du type structurel de l'objet. Cela permet également de libérer quelque chose de manière incorrecte, mais d'après mon expérience, c'est un problème rare par rapport à quelqu'un qui bousille les implémentations / compatibilité d'allocateur compatible stdlib. Il y a aussi quelques astuces avec le placement nouveau, mais encore une fois, c'est plus compliqué que l'équivalent en C.
2
Non. L'avantage de la vitesse de C ++ est dû à sa capacité à utiliser votre propre gestionnaire de mémoire personnalisé pour les allocations de tas . Chaque langue saine alloue des sections locales sur la pile.
Nevermind
3

Les jeux étaient autrefois écrits en langage machine, car ils avaient du matériel exotique pour lequel il n'y avait pas de compilateur. Le matériel manquait également de fonctionnalités que les programmeurs C tiennent pour acquises, telles que des mathématiques entières 16 bits efficaces.

Une fois les jeux installés sur du matériel familier, les compilateurs C sont devenus disponibles et en peu de temps, tous les jeux ont été écrits en C.

Le C ++ semblait être une bonne idée à un moment donné, et la plupart des jeux sont aujourd'hui du C ++, mais les ingénieurs marmonnent maintenant à propos d'un retour au C, et cela pourrait en fait arriver. J'adorerais travailler sur un jeu en C, tout comme de nombreux collègues. Il n'y a aucune fonctionnalité nouvelle en C ++ qui, je pense, améliore les jeux.

Il semblerait maintenant que les ordinateurs sont 1000 fois plus rapides qu'il y a quelques années, un langage de haut niveau réduirait le temps de développement ($) rendant le C obsolète.

Cela ne s'est pas produit car les acheteurs de jeux savent que le matériel est 1000 fois meilleur et veulent échanger leurs dollars contre un jeu qui ressemble et sonne 1000 fois mieux. Cela supprime le jeu du système qu'une langue de haut niveau consommerait.

Les exigences de performances dans les jeux sont brutales. Un nouveau cadre graphique doit être rendu en moins de 33 ms (ou 16 ms!) Sans faute. Tout ce que fait le matériel doit être pris en compte, afin que ce budget puisse être respecté. Tout langage qui se déclenche et fait quelque chose avec le matériel que le programmeur ne comprend pas ou attend, va rendre très difficile le respect de ce budget. Il s'agit d'un inconvénient automatique contre tout élément de haut niveau.

Les programmeurs de jeux fonctionnent non seulement dans un langage de bas niveau, mais ils évitent également les structures de données et les algorithmes de haut niveau. Les jeux n'ont généralement pas de listes chaînées et ont rarement des arbres. Il y a un mouvement pour éviter les pointeurs dans la mesure du possible *. Tout algorithme avec plus de temps O (N) ou d'espace O (1) a tendance à ne pas être largement utilisé.

* Si un pointeur ne provoque pas un échec de cache, alors pourquoi dépenser 32 bits pour le stocker? Si un pointeur provoque un échec de cache, mieux vaut se débarrasser de cet échec de cache.

bmcnett
la source
1
"Il n'y a aucune fonctionnalité nouvelle en C ++ qui, je pense, améliore les jeux." LOL? OOP? Une classe humanavec des dérivés playeret enemy?
orlp
2
@nightcracker: l'héritage de base est un bon fonctionnement en C; la relation que vous décrivez est mieux mise en œuvre en utilisant de toute façon has-a pour des raisons de performances et de propreté.
3
Il existe un consensus croissant sur le fait que les fonctionnalités de POO de C ++ ne sont pas appropriées pour les jeux, car ces fonctionnalités fonctionnent sur des hypothèses hostiles aux performances de cache.
bmcnett
Même si vous pensez que C ++ n'offre aucun avantage par rapport à C, vous devez certainement reconnaître qu'un retour à C n'offre aucun avantage par rapport à C ++.
Dan Olson
@Dan Un retour à C offre l'avantage que les "meilleures pratiques" comme ne pas utiliser de modèles ou de POO sont appliquées par des erreurs au moment de la compilation plutôt que de pourchasser les programmeurs juniors avec un bâton. En outre, comme le langage est plus simple, le compilateur et la maintenance du débogueur sont également moins chers.
bmcnett
3

Tous les langages de programmation ont des forces et des faiblesses à travers une gamme de facteurs. Des exemples de ces facteurs sont:

  • Vitesse sur une plate-forme particulière
  • Utilisation de la mémoire sur une plate-forme particulière
  • Quelles fonctionnalités il expose plus facilement
  • Sur quelles plateformes il existe
  • Quelles considérations un programmeur doit prendre en compte

L'un des facteurs les plus importants qu'un programmeur de jeux se soucie est la performance. Ils veulent produire une expérience interactive, ce qui signifie qu'elle doit être réactive et capable de produire autant de données utiles (ou intéressantes) que possible. Vous voulez savoir à tout moment combien de santé vous avez et vous ne voulez pas l'attendre. Et si vous cliquez sur un bouton, vous vous attendez à ce qu'un pistolet tire ou que votre personnage saute lorsque vous le dites. Un petit décalage peut interférer avec cette interactivité, vous avez donc besoin de performances.

Un autre facteur important est de préférer programmer dans la langue du problème, plutôt dans la langue de l'implémentation. Un programmeur de jeux veut gérer les humains, les orcs et les voitures de course, pas le registre de mémoire ED0. Ils veulent toujours avoir la possibilité de plonger dans les détails de l'implémentation s'ils ont besoin de performances, mais ce serait génial s'ils pouvaient pour la plupart traiter avec le niveau des entités dans leur monde de jeu. Ils ont assez à se soucier de simuler le monde du jeu sans avoir à se soucier toujours du fonctionnement d'une liste chaînée.

C ++ correspond très bien à ces deux facteurs principaux. Vous pouvez avoir les avantages de performance de l'assemblage ou du code C avec l'expressivité des objets. Pour voir pourquoi c'est un choix naturel pour les jeux, comparez avec d'autres options de langue:

  • Assemblage: c'est de la puissance brute. Ce que vous écrivez est essentiellement ce que fait le CPU. Mais à chaque étape, vous devez savoir ce qui se passe avec les registres et leurs effets, et cela ne ressemble jamais aux entités de votre monde de jeu. Le programmeur doit faire la correspondance mentale de ce que fait son code par rapport à ce qui se passe dans le jeu. Cela peut être une surcharge mentale.
  • C: Ici, nous avons de bonnes performances, mais nous pouvons tirer parti de l'expérience des gourous pour faire des choses standard (comme allouer de la mémoire, opérer sur des chaînes et utiliser des fonctions mathématiques standard). Nous nous rapprochons ici de l'expressivité, mais le langage vous oblige plus ou moins à vous concentrer sur l'implémentation car vous ne pouvez vraiment opérer que sur des types de données normaux. Tout est vraiment un char, un int ou similaire. Les structures, pointeurs et tableaux peuvent maintenir les choses ensemble, mais doivent toujours penser aux éléments internes.
  • Java: nous sautons sur C ++ et arrivons à Java. Java éloigne davantage les détails de l'implémentation. En fait, la plupart du temps, vous n'avez pas accès aux niveaux inférieurs. Java résume une grande partie des détails d'implémentation (par exemple, quel processeur ou système d'exploitation vous utilisez) pour la raison qu'il veut être multiplateforme. Vous ne pouvez pas accéder aux détails car ils ne sont pas là. Vous ne programmez pas pour l'ordinateur, vous programmez pour la plate-forme (la plate-forme Java, qui existe sur la plupart des ordinateurs). De plus, Java a sans doute un meilleur langage pour traiter le langage du problème que C ++. Le compromis est que vous ne pouvez pas optimiser pour un ordinateur particulier. Que cela fasse une différence pratique ou non se résume aux spécificités du programme et de l'ordinateur.
  • Langage de script de jeu: J'entends par là quelque chose comme UnrealScript , ou des langages de script personnalisés attachés à un moteur de jeu. Dans ces derniers, vous n'avez pas accès au moteur sous-jacent. Vous déléguez des considérations de performances au moteur, vous laissant libre de vous soucier de créer un jeu. Il est plus facile d'écrire le jeu, plus difficile d'optimiser ses performances vous-même.
  • Haskell (ou votre langage obscur préféré): Tout langage de programmation complet de Turing est équivalent à tout autre. Ainsi, bien que vous puissiez écrire n'importe quel programme dans n'importe quelle langue, vous faites des compromis, certains objectifs, certains subjectifs. Une langue comme Haskell est plus axée sur le travail dans un esprit mathématique. Les problèmes auxquels il est destiné sont quelque peu différents des problèmes rencontrés dans les jeux. Cela ne signifie pas qu'il ne peut pas ou ne devrait pas être utilisé pour les jeux, c'est juste que ce n'est pas facilement adapté.

Le dernier point est qu'une partie de cela est historique et politique. De nombreuses guerres de flammes ont été menées entre les différents langages de programmation. C # par exemple pourrait être tout aussi adapté au développement de jeux, mais il est venu après C ++. Ou les gens n'aiment pas que ce soit de Microsoft. Certaines personnes sont passées au C #, d'autres non. Certaines personnes continuent de programmer des jeux en BASIC, Pascal et C. Quels que soient les programmeurs qui s'y sentent à l'aise, ils s'y tiendront. Les programmeurs de jeux sont généralement à l'aise avec C ++, peut-être parce qu'ils ont grandi avec C et C ++, et qu'il répondait à leurs besoins. Si l'industrie informatique est dans un état où les performances et l'adoption de Java satisfont suffisamment de gens, alors peut-être que Java serait le langage de développement de jeu standard de facto.

BrettW
la source
2

Héritage et élan.

Il était une fois un code temporel écrit en assembleur pour des performances optimales. À mesure que la puissance de calcul augmentait, les langages compilés devenaient plus viables et C offrait le meilleur compromis entre puissance et productivité, à un niveau très basique étant à peine plus qu'un macro assembleur.

C ++ n'était que le successeur naturel de C. Vous ne jetez aucun ancien code ou connaissance, mais avez le potentiel de vous étendre à de nouvelles méthodologies. Le C ++ est finalement très flexible, et je n'ai pas encore vu de paradigme de conception qui ne puisse pas au moins être simulé en C ++, tout en étant capable de maintenir un contrôle quasi total sur les performances.

Simon Lacey
la source
2

Si vous développez pour les consoles, vous n'avez pas le choix: les SDK professionnels ne sont disponibles qu'en versions C ++. Habituellement, ils ont également accès C à la plupart des choses.

Étant donné que de nombreux développeurs sont des consoles + PC, il est logique de faire tout leur travail sur PC dans le même langage et de partager directement la technologie.

Parce que c'est là que vit l'industrie professionnelle, et que presque tout le monde veut en faire partie, la plupart des programmeurs de jeux sont des programmeurs C ++.

Parce que tout cela se produit, la plupart des développeurs de moteurs sont également des développeurs C ++, donc lors de l'évaluation de moteurs de qualité professionnelle, presque tous vos choix seront C ++.

C'est tout un gros moteur autonome. Le perturber nécessiterait plus qu'un simple progrès technique.

Chris Subagio
la source
2

FWIW: C # gagne en popularité pour le développement de jeux. Voir le blog de Miguel de Icaza . Lecture très intéressante, à mon humble avis.


la source
2
Comme d'habitude, Miguel pousse ses technologies préférées (généralement marginales) tout en ignorant la façon dont C # est devenu un acteur majeur de l'industrie, par exemple XNA.
2

Bien que je sois assez fortement anti-C, C & C ++, la seule chose qu'ils ont que peu d'autres langages ont est un contrôle complet sur la plate-forme sur laquelle il fonctionne, vous pouvez être sûr de ce qui se passera à tout moment, non GC, pas de pépins.

Ce n'est pas aussi important de nos jours, mais cela peut être pour les plateformes sous-alimentées.

Sur PC / Mac / Linux, c'est probablement le langage le moins portable que vous rencontrerez ces jours-ci, et le bonus de vitesse n'est plus très différent - Minecraft (Java) est fluide et fonctionne sur des plates-formes assez minimales (et tout système d'exploitation) avec un seul exécutable - je n'ai pas encore vu une application indi C / C ++ à faible effectif avec autant de fonctionnalités et aussi peu de bugs, sans parler de travailler sur trois plates-formes.

Donc, à ce stade, je dirais que la majeure partie est l'inertie et la conception que les vrais jeux sont toujours faits en C / C ++, bien que la capacité de "porter" sur iPhone et consoles soit importante (même si je suis assez sûr que la plupart de l'interface utilisateur des jeux prennent beaucoup d'efforts pour le portage, sauf entre Windows et XBox).

Bill K
la source
1
Oh, je ne sais pas que cela n'est important que pour les plateformes "sous-alimentées". L'autre façon de voir les choses est que le jeu est toujours à la pointe des performances sur n'importe quelle plate-forme: toute nouvelle puissance est immédiatement engloutie. Si nous parlons de développement de jeu professionnel, la performance est à peu près la principale préoccupation: vous n'écrivez pas Unreal sans maximiser chaque dernier cycle que la machine a à offrir. Chaque; Célibataire; cycle. À tous les niveaux, depuis le moteur graphique et l'accès au disque jusqu'à votre boucle d'interface utilisateur.
Chris Subagio
@Chris: La meilleure façon que j'ai trouvée de le décrire aux programmeurs non-jeu est que les jeux sont un domaine où la vitesse est un avantage concurrentiel. Si votre traitement de texte démarre dans 5 secondes où MS Word prend 10, ou redistribue dans 0,1 seconde où Word prend 0,2, cela ne vaut rien. Mais si votre jeu peut générer encore 10% de fragments supplémentaires ou afficher même un personnage plus détaillé, cela peut être un énorme avantage concurrentiel.
Ne serait-il donc pas idiot de ne jamais coder autrement qu'en assembleur? Ce serait certainement au moins 10% plus rapide. Il y a un moment où vous appelez à des compromis sur les performances pour la maintenabilité et la vitesse de développement. Généralement, ce point est C ++ de nos jours. Ce serait bien si la possibilité d'aller sur plusieurs plates-formes comme Minecraft avait plus de poids.
Bill K
Ah, mais c'est une erreur que le codage en assembleur soit plus rapide: les puces actuelles sont suffisamment complexes pour qu'il soit difficile pour un programmeur de surpasser un compilateur de manière cohérente. Ce n'est que dans des domaines plus restreints comme les SPU sur la PS3, que les boucles physiques internes et les shaders sur les GPU présentent encore des avantages évidents. Le C ++ est en effet actuellement le point idéal, avec la mise en garde que la POO n'est pas toujours le meilleur choix: la discussion en cours Struct of Arrays vs Array of Structs n'est pas exactement une discussion de langage, mais C ++ vous mène clairement à AoS naturellement; Parfois ... vous voulez vraiment juste C.
Chris Subagio
L'étape d'efficacité du programmeur entre l'assembleur et C / C ++ est également d'un ordre de grandeur supérieur à l'étape d'efficacité du programmeur entre C et C ++, ou C ++ et C # / Java. Fred Brooks l'a souligné il y a 25 ans.