La nouvelle année pour les développeurs de jeux a commencé par une vague de critiques qui a frappé le comité de normalisation C ++ après la publication des plaintes d'Aras Prankevichus concernant le C ++ moderne . Une question sérieuse s'est posée: le comité des normes a-t-il vraiment perdu le contact avec la réalité, ou est-ce l'inverse, et est-ce que les développeurs de jeux se sont séparés du reste de la communauté C ++?
Nous vous proposons une traduction du poste populaire de Ben Dean, un vétéran de l'industrie du jeu , qui a longtemps travaillé chez Blizzard, Electronic Arts et Bullfrog en tant que développeur et chef d'équipe C ++, dans lequel il répond aux critiques du point de vue de sa propre expérience.TL; DR: Le Comité de normalisation C ++ n'a pas d'objectif caché d'ignorer les besoins des développeurs de jeux, et le C ++ «moderne» ne va pas devenir un langage «débogué».
Au cours de la semaine dernière
, il y a eu
une discussion active sur Twitter , au cours de laquelle de nombreux programmeurs - en particulier ceux qui travaillent dans le domaine du développement de jeux - ont déclaré que le vecteur de développement actuel du «C ++ moderne»
ne répond pas à leurs besoins . En particulier, du point de vue d'un développeur de jeux ordinaire, tout semble ignorer les performances de débogage dans le langage et l'optimisation du code devient attendue et nécessaire.
Étant donné qu'en 2019 j'ai réussi à travailler dans l'industrie du jeu pendant plus de 23 ans, j'ai ma propre opinion basée sur des observations sur ce sujet en relation avec le développement de jeux, que je voudrais partager. Le débogage est-il important pour les développeurs de jeux, et pourquoi? Quels sont les problèmes qui y sont associés?
Pour commencer - une petite digression dans l'histoire.
De nombreux développeurs de jeux C ++ travaillent dans Microsoft Visual C ++. Historiquement, un énorme marché pour les jeux s'est formé autour des plates-formes Microsoft, ce qui a affecté l'expérience typique d'un programmeur de jeux ordinaire. Dans les années 90 et 2000, la plupart des jeux ont été écrits en tenant compte de ces circonstances. Même avec l'avènement des consoles d'autres fabricants et la popularité croissante des jeux mobiles, les atouts de nombreux studios AAA et de nombreux programmeurs de jeux sont aujourd'hui des outils créés par Microsoft.
Visual Studio est sans doute le meilleur débogueur de C ++ au monde. De plus, Visual Studio se démarque vraiment le plus en termes de débogage de programme - plus qu'avec son front-end, son back-end, son implémentation STL ou autre. Au cours des cinq dernières années, Microsoft a fait des progrès importants dans le développement d'outils de développement C ++, mais même avant cela, le débogueur dans Visual Studio a toujours été très cool. Ainsi, lorsque vous développez sur un PC Windows, vous disposez toujours d'un débogueur de classe mondiale.
Compte tenu de ce qui précède, examinons le processus d'obtention de code dans lequel il n'y aura pas de bogues; les opportunités que nous avons du point de vue d'un programmeur qui ne s'occupe pas des jeux; ainsi que les limitations rencontrées par les développeurs de jeux. Si vous reformulez l'argument principal en faveur du «vecteur de développement du C ++ moderne», il sera alors réduit à des types, des outils et des tests. Suite à cette réflexion, le débogueur devrait être la
dernière ligne de défense . Avant de l'atteindre, nous avons les options suivantes.
Occasion n ° 1: types
Nous pouvons utiliser autant de typage fort que nécessaire pour éliminer des classes entières de bogues au moment de la compilation. Le typage fort est, sans aucun doute, une opportunité que la récente évolution du C ++ nous a fourni; par exemple, à partir de C ++ 11, nous avons réussi à obtenir:
- extension significative des
type traits
de type traits
; - des innovations telles que
nullptr
et scoped enum
pour lutter contre le patrimoine C - typage faible; - GSL et outils auxiliaires;
- concepts en C ++ 20.
Certains d'entre vous peuvent ne pas aimer la métaprogrammation de modèles; d'autres peuvent ne pas aimer le style de codage qui utilise l'
auto
presque partout. Indépendamment de ces préférences, le principal motif d'utilisation des styles répertoriés en C ++ est clairement tracé ici - c'est le désir d'aider le compilateur afin qu'il puisse à son tour nous aider, en utilisant en même temps ce qu'il sait le mieux: le système de types.
Si nous parlons de programmation de jeux, le typage fort est un vaste domaine de recherche, et il est activement utilisé par les programmeurs de jeux que je connais, qui souhaitent améliorer leurs compétences dans l'utilisation du C ++ dans la pratique. Deux choses importantes sont préoccupantes ici: l'effet sur le temps de compilation et l'effet sur la lisibilité du code.
Franchement, vous pouvez facilement ignorer le temps de compilation - mais seulement à condition que vous soyez programmeur dans une très grande entreprise qui ne joue pas à des jeux et possède une infrastructure interne établie et une puissance de calcul sans fin afin de compiler n'importe quel code que vous pouvez écrire . Ces grandes entreprises s'inquiètent du coût de la compilation - elles utilisent donc des modules - mais, en règle générale, cela ne cause pas de douleur aux développeurs individuels. Dans le même temps, pour la plupart des programmeurs de jeux, ce n'est pas le cas. Les développeurs indépendants n'ont pas de fermes à construire; Les développeurs de jeux AAA utilisent souvent quelque chose comme
Incredibuild , mais étant donné qu'ils peuvent facilement travailler avec une base de code de 10 ans ou plus, le processus de construction peut encore prendre de 15 à 20 minutes.
Nous pouvons discuter du coût relatif de l'ajout de matériel par rapport au coût du temps du programmeur, et je suis d'accord avec l'idée que le matériel est moins cher, cependant:
- Le matériel est de véritables dépenses ponctuelles qui seront affectées au budget du trimestre en cours, contrairement à des dépenses moins tangibles en termes de temps / d'embauche / similaires, qui seront allouées pour une période plus longue. Les gens ne supportent pas bien la décision en faveur d'un tel compromis, et les entreprises sont spécialement conçues de manière à optimiser les bénéfices à court terme.
- L'infrastructure nécessite un support, et presque personne n'entre dans l'industrie du jeu pour devenir ingénieur de la version. Comparé à d'autres domaines où C ++ est utilisé, le salaire des développeurs de jeux n'est pas si élevé - et les ingénieurs non-jeux sont encore moins payés ici.
On peut également spéculer sur le fait que le temps de compilation n'aurait jamais dû atteindre un tel état; et encore une fois je suis d'accord avec vous. Le prix de cela est une vigilance constante - encore une fois, venant d'un ingénieur de la version - et, idéalement, un outil automatisé qui vous permet de suivre les changements dans le temps requis pour construire la build. Heureusement, avec l'avènement des systèmes CI, cet objectif peut être atteint beaucoup plus facilement aujourd'hui.
Occasion n ° 2: Outils
Nous devons utiliser le maximum d'outils à notre disposition - avertissements, analyse statique, désinfectants, outils d'analyse dynamique, profileurs et autres.
D'après mon expérience, les développeurs de jeux utilisent ces outils dans la mesure du possible, mais ici, l'industrie dans son ensemble a plusieurs problèmes:
- Ces outils ont tendance à mieux fonctionner sur les plates - formes non Microsoft - et, comme mentionné précédemment, ce n'est pas un scénario de développement de jeu typique.
- La plupart de ces outils visent à travailler avec du C ++ "standard". Ils prennent en charge
std::vector
, mais pas ma classe auto-écrite CStaticVector
partir d'un moteur hypothétique. Bien sûr, blâmer les outils est inutile, mais c'est toujours l'un des obstacles à leur utilisation que les développeurs doivent surmonter. - La création et la maintenance d'une chaîne CI qui exécutera tous ces outils nécessite la présence d'ingénieurs de publication - et, comme mentionné précédemment, l'embauche de personnes pour des emplois d'ingénierie qui ne sont pas directement liés aux jeux est un problème systémique pour l'industrie du jeu.
Donc, comme ces outils fonctionnent si bien avec le C ++ standard, pourquoi les développeurs de jeux n'utilisent-ils pas STL?
Par où commencer la réponse à cette question? Peut-être, à partir de la prochaine excursion dans l'histoire du développement de jeux:
- Jusqu'au début des années 90, nous ne faisions pas confiance aux compilateurs C, nous avons donc écrit des jeux en assembleur.
- Du début au milieu des années 90, nous avons commencé à faire confiance aux compilateurs C, mais nous ne faisions toujours pas confiance aux compilateurs C ++. Notre code était C, qui utilisait des commentaires de style C ++, et nous n'avions plus besoin d'écrire des typedefs pour nos structures tout le temps.
- Vers 2000, la révolution C ++ a eu lieu dans le monde du développement de jeux. C'était une ère de modèles de conception et de grandes hiérarchies de classes . À cette époque, le support STL sur les consoles laissait beaucoup à désirer, et les consoles régnaient alors sur le monde. Sur PS2, nous sommes toujours bloqués avec GCC 2.95.
- Vers 2010, deux autres révolutions ont été lancées. La douleur de l'utilisation de hiérarchies de classes importantes a stimulé le développement d'une approche composante du code. Ce changement poursuit aujourd'hui son évolution sous la forme d'architectures Entité-Composant-Système. Cette seconde révolution a été accompagnée d'une tentative de tirer parti des architectures multiprocesseurs.
Pendant ces changements de paradigme, les plates-formes de développement de jeux elles-mêmes changeaient constamment, et elles changeaient sérieusement. La mémoire segmentée a cédé la place à un espace d'adressage plat. Les plateformes sont devenues multiprocesseurs, symétriques et peu nombreuses. Les développeurs de jeux, habitués à travailler avec des architectures Intel, ont dû s'habituer à MIPS (Playstation), puis à un matériel spécial avec des CPU hétérogènes (PS2), puis à PowerPC (XBox 360), puis à une hétérogénéité encore plus grande (PS3) ... Chacun La nouvelle plate-forme est venue avec de nouvelles fonctionnalités de performance pour les processeurs, la mémoire et les lecteurs. Si vous vouliez atteindre des performances optimales, vous étiez obligé de réécrire votre ancien code, et souvent et souvent. Je ne mentionnerai même pas à quel point les jeux ont été influencés par l'émergence et la croissance de la popularité d'Internet, ainsi que les restrictions que les détenteurs de plates-formes ont imposées aux développeurs.
Historiquement, les implémentations STL sur les plates-formes de jeux n'ont pas été satisfaisantes. Ce n'est pas un secret que les conteneurs STL sont mal adaptés aux jeux. Si vous poussez le développeur du jeu contre le mur, il admettra peut-être que
std::string
est tout à fait OK, et
std::vector
est une option par défaut raisonnable. Mais tous les conteneurs contenus dans la STL ont un problème de contrôle d'allocation et d'initialisation. De nombreux jeux doivent se soucier des limitations de mémoire pour diverses tâches - et pour les objets pour lesquels la mémoire devra probablement être allouée dynamiquement pendant le jeu, des allocateurs de
dalles ou d'
arènes sont souvent utilisés.
Le temps constant amorti n'est pas un bon résultat, car l'allocation est potentiellement l'une des choses les plus «coûteuses» qui peuvent se produire pendant l'exécution du programme, et je ne veux pas sauter une image juste parce qu'elle s'est produite alors que je ne m'y attendais pas . En tant que développeur de jeux, je dois gérer à l'avance mes besoins en mémoire.
Une histoire similaire est obtenue pour les autres dépendances en général. Les développeurs de jeux veulent savoir ce que prend chaque cycle de processeur, où et quand et pour quoi chaque octet de mémoire est responsable, ainsi que où et quand chaque thread d'exécution est contrôlé. Jusqu'à récemment, les compilateurs Microsoft changeaient l'ABI à chaque mise à jour - donc si vous aviez de nombreuses dépendances, les reconstruire toutes pourrait être un processus pénible. Les développeurs de jeux préfèrent généralement les petites dépendances faciles à intégrer, ne font qu'une chose et le font bien - de préférence avec une API de style C - et sont utilisées par de nombreuses entreprises, sont accessibles au public ou ont une licence gratuite qui ne fonctionne pas nécessite l'indication de l'auteur.
SQLite et
zlib sont de bons exemples de ce que les développeurs de jeux préfèrent utiliser.
De plus, l'industrie des jeux C ++ a une riche histoire de patients atteints du syndrome «pas inventé ici». Cela devrait être attendu de l'industrie, qui a commencé avec des passionnés célibataires qui ont fait leurs propres choses avec un équipement complètement nouveau et n'avaient pas d'autres options. L'industrie du jeu, entre autres, est la seule où les programmeurs sont indiqués dans les crédits sans ordre particulier.
Écrire une variété de choses est amusant et cela aide votre carrière! Mieux vaut construire soi-même que d'acheter du ready-made! Et comme nous sommes tellement préoccupés par les performances, nous pouvons adapter notre solution de manière à ce qu'elle soit adaptée spécifiquement à notre projet - au lieu de prendre une solution généralisée qui gaspille sans réfléchir les ressources disponibles. L'hostilité à Boost est le principal exemple de la façon dont une telle pensée se manifeste dans le développement de jeux. J'ai travaillé sur des projets qui se sont déroulés comme suit:
- Pour commencer, pour résoudre un problème particulier, nous connectons une bibliothèque de Boost au projet.
- Tout fonctionne très bien. Lorsque vous devez mettre à jour, une petite douleur survient, mais pas plus que lors de la mise à jour de toute autre dépendance.
- Un autre jeu veut utiliser notre code, mais l'obstacle est que nous utilisons Boost - malgré le fait que notre expérience avec Boost se soit plutôt bien passée.
- Nous supprimons le code en utilisant Boost, mais maintenant nous sommes confrontés à un nouveau problème: nous devons résoudre le problème que la bibliothèque de Boost au lieu du nôtre a résolu auparavant.
- Nous copions essentiellement les parties du code Boost dont nous avons besoin dans nos propres espaces de noms.
- Plus tard, nous constatons inévitablement et maintes et maintes fois que nous avons besoin de fonctionnalités supplémentaires qui seraient déjà dans le code d'origine si nous ne l'avions pas jeté. Mais maintenant, nous sommes les propriétaires de ce code, nous devons donc continuer à le prendre en charge.
Nous n'aimons pas quelque chose d'énorme qui essaie de faire trop de choses en même temps ou qui peut affecter le temps de compilation - et c'est tout à fait raisonnable. Ce que les gens font des erreurs encore et encore, c'est qu'ils sont opposés à accepter la douleur supposée aujourd'hui - alors qu'en raison de cette décision, ils feront face à une douleur très réelle et beaucoup plus grande avec le soutien de quelque chose aux dépens de quelqu'un - le budget dont ils devront disposer au cours des trois prochaines années. Hélas, la présence de preuves sous forme de jeux qui utilisent avec succès un plat de STL et Boost, ne peut en aucun cas affecter la psychologie humaine et convaincre les développeurs de jeux.
Pour toutes ces raisons, de nombreuses sociétés de jeux ont créé leurs propres bibliothèques qui couvrent ce que fait STL - et même plus - tout en prenant en charge des cas d'utilisation spécifiques au jeu. Certaines grandes sociétés de jeux ont même pu maîtriser le développement de leur propre
remplacement STL à part entière, presque entièrement compatible API, ce qui a entraîné des coûts énormes pour soutenir ce projet.
Il est sage de trouver une alternative améliorée à std::map
, ou d'appliquer une
petite optimisation de tampon dans
std::vector
. Il est beaucoup moins acceptable d'être condamné à prendre en charge vos propres implémentations d'
algorithms
ou de
type traits
, ce qui ne servira à rien. Quant à moi, il est regrettable que pour la plupart des développeurs, les STL ne soient que des conteneurs. Depuis lors de l'apprentissage du STL au début, on leur apprend juste que, en parlant du STL, la plupart impliquent
std::vector
- bien qu'en fait ils devraient penser à
std::find_if
.
Occasion n ° 3: tests
Il est soutenu que des tests approfondis devraient être effectués, TDD et / ou BDD devraient couvrir tout le code qui peut être couvert, et les bogues devraient être corrigés en écrivant de nouveaux tests.
Par conséquent, discutons du sujet des tests.
À en juger par mon expérience, les tests automatisés ne sont pratiquement pas utilisés dans l'industrie du jeu. Pourquoi?
1. Parce que l'exactitude n'est pas si importante, mais il n'y a pas de véritable spécification
En tant que jeune programmeur dans l'industrie du jeu, je me suis rapidement débarrassé de l'idée que je devais m'efforcer de simuler quelque chose de manière réaliste. Les jeux sont de la
fumée et des miroirs et la recherche de chemins courts. Personne ne se soucie du réalisme de votre simulation; l'essentiel est que ce soit amusant. Lorsque vous n'avez pas d'autre spécification que «le jeu devrait se sentir bien», le sujet du test est manquant. Grâce aux bugs, le gameplay peut même s'améliorer. Très souvent, un bug pénètre dans la version et gagne même l'amour des utilisateurs (
rappelez-vous le même Gandhi de Civilization ). Les jeux sont différents des autres domaines qui utilisent C ++; ici, un manque de justesse n'entraîne pas le fait que quelqu'un finisse par perdre ses économies.
2. Parce que c'est difficile
Bien sûr, vous souhaitez produire des tests automatisés partout où vous le pouvez. Cela peut être fait pour certains sous-systèmes pour lesquels il existe des résultats finaux clairement indiqués. Les tests unitaires dans l'industrie du jeu, bien sûr, sont présents, mais en règle générale, ils sont limités au code de bas niveau - les analogues STL mentionnés précédemment, les procédures de conversion de chaînes, les méthodes de moteur physique, etc. Les cas où la section exécutable du code a des résultats prévisibles sont généralement testés par des tests unitaires, bien que TDD ne soit pas utilisé ici - car les programmeurs de jeux préfèrent simplifier leur vie, et non l'inverse. Mais comment testez-vous le code de gameplay (voir point un)? Dès que vous allez au-delà du test unitaire, vous rencontrez immédiatement une autre raison pour laquelle le test des jeux est si difficile.
3. Parce que le contenu est impliqué
Les tests de systèmes non triviaux comprendront probablement la fourniture de contenu avec lequel ils seront mis en œuvre. La plupart des ingénieurs ne sont pas très bons pour produire ce contenu par eux-mêmes, donc pour obtenir un test significatif, vous devrez attirer quelqu'un avec les bonnes compétences pour créer le contenu. Après quoi, vous rencontrerez le problème de mesurer ce que vous obtenez sur la sortie - après tout, ce n'est plus une ligne ou un nombre, mais une image à l'écran ou un son qui change avec le temps.
4. Parce que nous ne le pratiquons pas
Le test unitaire est une fonction dont je connais les entrées et sorties possibles. Cependant, le gameplay est un comportement imprévisible et évoluant dynamiquement, et je ne sais pas comment un tel phénomène pourrait être correctement testé. Que puis-je tester - si, bien sûr, j'obtiens la permission de mon manager pour y consacrer suffisamment de temps - ce sont, par exemple, les performances ou les capacités de haut niveau, comme le matchmaking, que je peux analyser. Un tel travail d'infrastructure peut être passionnant pour certains programmeurs de jeux, mais pour la plupart, il n'est tout simplement pas intéressant, et en outre, il nécessite l'approbation et le soutien du propriétaire du portefeuille. En tant que programmeur de jeux, je n'ai jamais eu l'occasion de pratiquer l'écriture de tests de haut niveau.
5. Étant donné que [la société] ne voit pas la nécessité de tests automatisés
Notre objectif principal est de sortir le jeu. Nous vivons dans une ère d'industrie qui évolue avec des hits qui tirent le meilleur parti de leur argent au cours du premier mois de vente, lorsque les coûts de commercialisation de ces hits sont maximisés. Le cycle de vie des consoles nous a appris que le code de toute façon ne vivra pas aussi longtemps. Si nous travaillons sur un jeu en ligne, nous aurons très probablement plus de temps pour tester le matchmaking ou la charge du serveur. Étant donné que pour la sortie du jeu, nous avons besoin que ses performances soient en ordre, nous devons au moins effectuer des tests de performances, mais nous ne devons pas automatiser ce processus. Pour la gestion dans l'industrie du jeu, les tests automatisés ne sont rien de plus qu'une perte de temps et d'argent. Pour sa mise en œuvre, il est nécessaire d'engager des ingénieurs expérimentés qui effectueront les travaux dont le résultat sera presque imperceptible. Le même temps pourrait être consacré au développement de nouvelles fonctionnalités. À court terme, il est beaucoup plus rentable d’utiliser du personnel d’assurance qualité pour tester le jeu, ce qui nous amène au point suivant.
6. Parce qu'en général, les tests dans les jeux sont classés comme une activité de second ordre
J'adore les bons professionnels de l'assurance qualité. Pour moi, ils valent son pesant d'or. Ils savent comment améliorer votre jeu en le cassant d'une manière qui n'aurait jamais traversé votre esprit. Ce sont des experts spécialisés dans votre gameplay à cet égard que vous ne comprenez pas et que vous ne comprenez presque jamais. Ils sont meilleurs qu'une équipe de compilateurs super-capables pour vous aider à tout faire correctement. Je suis heureux d'avoir eu la chance de travailler avec plusieurs merveilleux spécialistes de l'assurance qualité au cours des années de mon travail.
J'ai presque toujours dû me battre pour qu'ils restent dans mon équipe.
Dans les grandes entreprises AAA, une organisation QA est généralement un département complètement séparé de toute équipe de développement, avec sa propre structure de gestion et d'organisation. Ceci est prétendument fait pour qu'ils puissent être objectifs pendant le test. En pratique, tout est loin d'être aussi beau.Ils sont traités comme des engrenages dans un énorme mécanisme, qui sont souvent jetés entre les projets sans avertissement et généralement traités comme si n'importe qui pouvait gérer leur travail. Lorsque le projet «s'écarte» de la date limite, les ingénieurs peuvent sentir le resserrement sur leur propre peau, mais l'assurance qualité devient beaucoup plus forte, car ils doivent travailler le quart de nuit et le week-end, et ils comprennent également qu'ils apportent de sombres nouvelles sur le courant état de qualité du projet.Ils sont sérieusement sous-payés. Les testeurs les plus expérimentés avec des années d'expertise dans le domaine reçoivent moins de la moitié de ce qu'ils paient un développeur de niveau intermédiaire. J'ai dû travailler avec les ingénieurs QA les plus intelligents qui ont créé des pipelines pour tester les performances avec suivi et alertes, créé des cadres pour tester les API et pour les tests de charge, et effectué de nombreuses autres tâches soi-disant indignes du temps des «vrais ingénieurs». Je suis sûr que ces personnes les plus intelligentes gagneraient beaucoup plus si elles travaillaient dans une autre grande entreprise technologique.Ils ne font pas confiance. Il n'est pas rare que les testeurs soient séparés des autres développeurs, et leurs badges leur permettent d'accéder uniquement à cet étage du bâtiment où ils travaillent eux-mêmes - ou même d'utiliser une entrée séparée.Ils sont obligés d'obéir. On dit souvent aux testeurs de ne pas déranger les autres ingénieurs. Lorsqu'ils doivent signaler un bug directement, ils sont priés de contacter les ingénieurs avec respect, comme "Mme H." ou "Mr. Y.". Parfois, je recevais un appel des patrons ennuyés des départements d'assurance qualité - dans ces cas, lorsque je contactais ceux qui avaient découvert le bogue pour une enquête conjointe.Tout cela ressemble à une terrible histoire, et ne laissez pas tout le monde faire face à de telles choses, malheureusement cela arrive assez souvent; si souvent que les ingénieurs commencent à penser - peut-être sous un stress constant, mais cela ne les excuse pas - que le travail de l'AQ est de rechercher leurs propres bogues, ou, pire encore, de commencer à blâmer l'AQ pour les bogues.Dans les meilleures équipes avec lesquelles j'ai dû travailler, nous avons insisté pour que nos équipes aient leurs propres ingénieurs QA qui travailleraient avec nous. Cependant, ils n'ont pas perdu leur objectivité ou leur désir d'obtenir un meilleur résultat. Ils étaient ravis de recevoir l'aide des programmeurs pour la rédaction de tests automatisés. Ce dont je ne doute certainement pas, c'est qu'il serait utile pour l'industrie du jeu de faire de l'automatisation plus souvent.Déboguer les performances
Compte tenu de tout ce qui précède - les habitudes de débogage, la plate-forme pour les API et les outils qui continuent de croître, et la complexité (combinée à un manque de culture) des tests automatisés - il devient clair pourquoi les développeurs de jeux insistent sur les capacités de débogage.Mais en même temps, il reste des problèmes avec le débogage lui-même, et des problèmes avec la façon dont les développeurs de jeux font face au vecteur de développement C ++ actuel.Le principal problème du débogage est qu'il n'est pas évolutif. Parmi les développeurs de jeux de développeurs lisant cet article, il y a ceux qui décident que les phénomènes que j'ai décrits ne sont pas d'accord avec ce qu'ils ont observé dans leur pratique. Très probablement, cela est dû au fait que tôt ou tard, ils ont eux-mêmes dû faire face au problème de l'évolutivité du débogage, et ils ont trouvé un moyen de le contourner.En d'autres termes, nous voulons un débogage productif, car pour détecter les bogues, nous devons souvent pouvoir exécuter des applications avec des ensembles de données suffisamment volumineux et représentatifs. Mais en fait, lorsque nous atteignons ce point, le débogueur devient généralement un outil trop grossier à utiliser - qu'il soit productif ou non. Bien sûr, définir des points d'arrêt sur les données ( points d'arrêt des données) peut être utile pour détecter des problèmes de taille moyenne, mais que se passe-t-il si nous rencontrons de vrais bugs - ceux qui subsistent après que nous semblons avoir tout résolu? Avec les mêmes qui surviennent sous la charge du réseau, ou en cas de manque de mémoire, ou fonctionnent à la limite des capacités de multithreading, ou se produisent uniquement pour un petit sous-ensemble non identifié dans le contexte d'un million d'autres joueurs, ou se produisent uniquement sur des versions de disque du jeu, ou seulement dans l'assemblage en allemand, ou après trois heures passées à tester la stabilité ( test de trempage )?Trait deux, nous pouvons compter uniquement sur le débogueur. Dans ce cas, nous faisons ce que nous avons toujours fait. Nous essayons d'isoler le problème, de le faire se produire plus souvent; nous ajoutons la journalisation et passons au crible notre programme; nous ajustons les minuteries et les paramètres de flux; nous utilisons la recherche de construction binaire; nous étudions les vidages mémoire et les journaux de plantage; nous essayons de reproduire le problème en réduisant le contenu au minimum; nous réfléchissons à ce qui pourrait être à l'origine du problème et en discutons.Souvent, jusqu'à ce que nous arrivions à la véritable cause de l'accident, nous aurons le temps de réparer quelques autres choses. En d'autres termes, nous résolvons des problèmes et, à la fin, l'utilisation d'un débogueur n'est qu'une petite partie de ce processus. Alors oui, la vitesse de débogage est un bel ajout, mais son absence ne nous empêche pas de continuer à être ingénieurs. Nous avons encore besoin de nos autres compétences, telles que la capacité d'analyser les vidages de mémoire et de lire l'assembleur optimisé.Lorsque j'utilise «C ++ moderne», j'utilise le débogueur de la même manière que d'habitude. Je passe par le code fraîchement écrit; Je mets des points d'arrêt sur les données qui m'intéressent; J'utilise un débogueur pour explorer du code inconnu. Avec l'avènement du «C ++ moderne», rien de tout cela ne change - et oui, même si STL utilise des identifiants _ Ugly _, cela ne fait pas de magie STL. Parfois, il est utile de voir ce que fait la STL «sous le capot» ou de passer par-dessus; ou, comme vous pouvez maintenant le faire, utilisez le débogueur pour me cacher le code de la bibliothèque .Quand je rencontre des problèmes de performances de débogage, ce n'est généralement pas que le «C ++ moderne» me ralentit - le fait est qu'à ce moment j'essaie déjà d'en faire trop. L'utilisation du débogueur n'est pas évolutive , contrairement aux types, aux outils et aux tests.J'étais moi-même inquiet du problème que le code C ++ nécessitait de plus en plus d'optimisation, et j'étais intéressé par l'opinion des développeurs de compilateurs à ce sujet. Le fait est qu'il n'y a pas de réponse unique. Nous sommes déjà dans le continuum et nous avons la possibilité d'aller plus loin dans cette direction sans nuire à la capacité de déboguer du code. Aujourd'hui, nos compilateurs effectuent la suppression de copie pour les objets temporaires., même si nous ne leur demandons pas d'effectuer cette optimisation. Cela n'affecte pas notre capacité à déboguer des applications. Je doute que nous nous plaignons que les versions de débogage ont commencé à inclure NRVO ou une autre demi-douzaine d’optimisations qui peuvent être faites de telle manière que nous ne les remarquerons pas pendant le débogage. Je soupçonne que C ++ évolue dans cette direction.Épilogue: La voie du C ++ moderne
Si vous travaillez en tant que programmeur dans le domaine du développement de jeux et que vous n'aimez pas où C ++ se dirige, vous avez essentiellement deux options pour d'autres actions possibles.1. Ne rien faire
En supposant que vous allez encore écrire du code C ++, vous pouvez simplement continuer à utiliser le langage de la même manière qu'auparavant. Il n'est pas nécessaire de commencer à utiliser de nouvelles fonctionnalités si vous ne le souhaitez pas. Presque tout ce que vous utilisez maintenant continuera d'être pris en charge - et ce faisant, dans les années à venir, vous continuerez à récolter les avantages de l'amélioration du compilateur.Il s'agit d'une stratégie de comportement tout à fait appropriée pour ceux qui travaillent pour eux-mêmes ou avec une équipe de personnes partageant les mêmes idées. C ++ 98, avec quelques fonctionnalités plus récentes, est toujours un bon choix pour écrire des jeux dessus.Cependant, si vous travaillez dans une grande entreprise, vous devrez tôt ou tard faire face à des changements de langue, car vous devrez augmenter l'équipe et embaucher de nouvelles personnes. À son tour, lorsque vous embauchez des développeurs C ++, cela signifie que vous embauchez des développeurs avec du C ++ «moderne». Un changement de générations se produira - comme cela s'est déjà produit avec l'assembleur, C et C ++ 98. Vous pouvez gérer le processus si vous définissez des limites sur ce qui est autorisé dans votre base de code et ce qui ne l’est pas, mais cette solution ne vous sauvera pas à long terme. Et que devez-vous faire dans ce cas?2. Participez
Au lieu d'aller dans un seul GDC une fois par an, commencez à visiter CppCon , où vous bénéficierez beaucoup plus de l'argent que votre entreprise a dépensé pour un billet. Participer aux discussions sur les normes; rejoignez des groupes et abonnez-vous aux newsletters; lire les projets de normes et fournir aux auteurs leurs commentaires. Si vous pouvez également assister aux réunions du comité, ce sera très bien, mais même si ce n'est pas le cas, vous pouvez encore faire beaucoup pour transmettre votre point de vue aux autres.L'adhésion au Comité C ++ est ouverte à tous. Toutes les informations nécessaires pour ceux qui souhaitent participer aux travaux de SG14, ou SG7, ou SG15 - ou de tout autre groupe de travail lié à votre domaine d'intérêt -peut être trouvé sur isocpp.org . Le comité n'a pas de plans secrets - en fait, pensez-vous vraiment que plus de 200 programmeurs peuvent s'entendre sur un programme commun? Ici, même les «patrons» du comité échouent souvent à «pousser» leurs idées.Si vous voulez que votre opinion soit entendue, alors vous devriez commencer à parler où votre opinion peut être entendue, et non sur Twitter ou Reddit. Veuillez suivre ce conseil - j'attends avec impatience notre discussion.