Unreal Engine: Blueprint vs C++

J’entends parfois dire : les BP, c’est illisible… c’est plus lent… c’est gadget… en préparant j’ai lu “si tu cherches à faire des choses plus sérieuses, le C++ est inévitable” sur un forum… que BP, c’est de la merde ! Et je souris… car quelques fois, j’ai pas envie de polémiquer avec ceux qui ne le méritent pas – tout simplement. J’ai beaucoup souri pendant les élections françaises…

La Polémique n’en est pas une. Ou plutôt, qui n’en est plus une ! C’est essentiellement dû au passé, du moteur, à  la jeunesse des BP.  D’anciens dev ou des gens pas assez compétents pour comprendre pourquoi… Parce qu’en école d’informatique on vous apprend la différence entre interprété et compilé et que les gens confondent avec les BP.

Je vais essayer de lever le voile sur tout ça. Nous allons analyser le problème sous plusieurs angles: Simplicité, vitesse, lisibilité, maintenance, API. A la fin, je ferai des recommandations.

Simplicité

Par expérience: les BPs plus simple pour débutant, plus compliqué pour des gens maitrisant le C++ (ce qui est mon cas) – mais au final, on a le meilleur des 2 mondes. J’explique pourquoi plus loin.

En C++, on peut faire des erreurs que l’on ne ferait pas en BP. Les BP sont bien plus contrôlés par l’éditeur. On ne manipule pas de pointeur – tout du moins, rien qui nous permettrait d’aller écrire n’importe où en mémoire… c’est plus sécurisé. En BP, si Unreal plante, c’est certainement parce qu’il y a bogue dans le moteur. En C++, c’est souvent parce qu’on n’a mal codé un truc (en plus des bogues d’Unreal). Et on peut chercher longtemps en C++…

Vitesse

Interprété contre compilé ? Il faut bien comprendre ce qui se cache derrière ces termes. L’image de l’interprète dans la vie de tous les jours, c’est à dire le traducteur, est assez bonne. Si vous parlez à un chinois en passant part un interprète, vous devrez parler en français, et lui traduira en chinois… c’est forcément plus long ! C’est pareil avec un langage informatique interprété. La machine ne le comprends pas directement, alors on utilise un logiciel, un interpréteur dans ce cas, qui va traduire chaque ligne et exécuter le code équivalent. Car lui, ce programme, est directement un exécutable, c’est à dire qu’il est en langage “machine”, une suite de 0 et de 1 que le processeur comprend parfaitement.

Cet interpréteur a t-il était écrit en assembleur ? Déjà, l’assembleur n’est pas un langage que la machine comprend, mais il en est très proche. Même l’assembleur… s’assemble – on ne parle plus de compilation pour lui, même si le principe est respecté. Un interpréteur est écrit dans un langage compilable… ça signifie que son code source va être traduit en langage machine pour créer un exécutable. Le C++ est un langage que l’on compile. Le C#, celui qui est utilisé par Unity, est un langage qui passe par une machine virtuelle… enfin, un équivalent. Mais nous n’allons pas entrer là dedans, ça nous forcerait à parler de Just In Time et autres subtilités.

Python est considéré comme un langage de script. Pourtant, cython permet de transformer du code python de telle façon qu’on puisse le compiler en exécutable (en passant par le C). Et je ne parle pas d’embarquer un interpréteur python dans l’exe ! Non, au final, le programme est “quasiment” aussi performant en terme de vitesse d’exécution qu’un programme écrit directement en C.

Alors, pourquoi Epic Games n’a pas transformé les BP en code C++ pour pouvoir les compiler  ? Ben, c’est exactement ce qu’ils ont fait.

Sous l’éditeur, les BP sont interprétés, ils sont donc plus lents… depuis une version assez récente, je crois que c’est postérieur à la 4.10, il est possible de transformer les BP en code C++, de compiler ce code et de l’insérer dans le package. C’est le procédé de “Nativization“, à ne pas confondre avec la compilation standard des BP qui consiste à transformer le BP en Bytecode interprété par une VM.

Le “Nativization” peut être activé à tout moment, mais cela ne va que dans un seul sens. Soit vous le faites à la fin, juste pour le Build et vous gardez les BP ainsi pour la maintenance du code. Soit vous transformez à n’importe quel moment vos classes BP en C++. Plus d’infos sur cette page.

Bémol: Un BP compilé aura ainsi la même vitesse que son équivalent C++ une fois compilé, à un détail près: la compétence du développeur. Ex: Faite une boucle 100.000x et appelez une fonction qui en appele d’autres… et comparer cela à appeler une macro… ce n’est pas le même résultat au final. C’est pire avec les fonctions qui s’appellent elles-mêmes. Mais on peut faire les mêmes conneries en C++.

De même, un compilateur C++ est capable d’optimiser des choses auxquelles on ne penserait même pas en assembleur. C’est vrai aussi pour les Blueprints. Les développeurs qui bossent sur l’Engine, surtout depuis qu’il est Open Source, sont suffisamment géniaux pour faire en sorte d’optimiser de façon très intelligente des boucles, en substituant des macros à des fonctions quand ces dernières sont petites, à réécrire des fonctions faisant appel à de la récursivité… ce qui ne sera pas forcément le cas avec votre code C++

Quand j’étais à l’IUT Informatique… il y a fort longtemps, dans un pays très froid où il pleut tout le temps… où les gens boivent pour oublier… bon je m’arrête ici… bref, on me disait à l’époque, et le prof était un gars très capable car il fabriquait des robots high tech pour l’armée, que le compilateur produisant le code le plus rapide du monde n’était pas un compilateur C, mais un compilateur ADA ! WTF??? C’est pas possible… cette merde de langage où il faut tout déclarer, ou on n’a pas de pointeur…. beurk… beurk et rebeurk… Mais il avait raison. C’est un langage très contraint, très sécurisé… Et de ce fait, les développeur géniaux du meilleur compilateur avait pu faire des optimisations qu’ils n’auraient jamais pu faire en C. Tout s’explique, mais c’est contraire à l’intuition.

Maintenance du code

On peut écrire salement du C++ comme des BP.

Les BP, selon les cas, ça peut devenir très fouillis. Dans ce cas, faire une routine C++.

En prog, 2 grands secrets: diviser pour mieux régner, et simplifier/complexifier – Et un 3ième, commentez, mais pas trop. Le secret de l’élixir, c’est quand il n’y a plus rien à retirer – idem en BP, idem en C++.

Par expérience, un code C++ et un Blueprint, sont aussi difficiles à maintenir pour un dev expérimenté. Dans la semaine, c’est nickel. 3 mois après, on se gratte la tête. Mais on y arrive, dans les deux cas.

Les BP sont plus facile à déboger: voir ces liens s’illuminer, pouvoir zoomer dans un arbre de décision d’IA, gérer par controller, etc. L’éditeur est super en ce sens ! Disons que c’est plus ludique.

J’ai eu l’occasion de bosser dans plusieurs équipes: c’est plus facile de faire appliquer des règles simples de codage en BP qu’en C++. Le BP est plus impersonnel et il est donc plus facile de s’approprier le code d’un autre. De même, le mélange entre dev, artistes et d’autres intervenants donne plus d’interactivité à l’équipe…. le codeur est moins perçu comme un dictateur, seul dieu du coeur du système… il tombe un peu de son pied d’estale… mais au final, tout le monde participe et on entend un peu moins de “c’est pas possible… de toute façon, t’y connais rien, t’es un batard de graphiste”… Promis, ces mots ne sortent pas de ma bouche, mais je les ai entendus durant une battle en demomaking… Perso, j’ai une grande admiration pour les gens créatifs et pour ce dont sont capables les graphistes… grâce à eux, on construit des mondes magnifiques et qui me font rêver… mais je m’égare.

API

Si 95% (à la louche) des fonctions de l’API d’Unreal Engine sont exposées en Blueprints, reste 5% qui ne l’est pas. Dans ce cas, il peut être nécessaire de passer par le C++. Exemple dans mon tome 5, j’utilise un plugin pour palier à certains manques des Blueprints, mais ce n’est que pour mapper des fonctions du moteur qui existent en C++.

Conclusion

Non, BP ce n’est pas que pour le prototypage. D’ailleurs je trouve ça un peu absurde, car cela signifie qu’il faut tout recoder. Oui, réécrire quelques fonctions critiques… et encore.

Certaines fonctions doivent être développées en C++: c’est plus simple – et plus rapide à dév comme à exécuter. Exemple: vous devez créer une matrice et effectuer un tri avec des opérations… Vous voulez utiliser des listes chainées, des pointeurs… etc. Pour faire de l’IA aussi c’est plus pratique, si les fonctions d’Unreal ne suffisent pas. Sachez qu’en 4.16, vous avez un plugin en bêta qui permet de faire des structures de structures ! StructBox !

Il doit rester des cas où le BP est mal traduit en C++, donc plus lent à l’exécution, mais cela doit rester rare et cela sera corrigé avec le temps. Pas encore vu de mon coté.

Il faut considérer les Blueprints comme un langage de plus haut niveau que le C++: constituer une API avec des fonctions et des objets développées en C++.

C++, c’est l’ouverture vers le monde extérieur à UNREAL ENGINE. Exemple: utiliser CUDA pour faire du calcul parallèle…. Faire appel à OpenCV pour de la reconnaissance d’images.

Je met au défi un développeur de déterminer, dans un Build compilé avec les bonnes options, s’il s’agit de BP ou de C++ – Car, tout du moins, en terme de perfs, le résultat est vraiment très proche, à compétence de dev égale. Je parle de perfs, car dans le binaire, dans les logs, il reste des traces.

Quand on est en studio, c’est génial: les dev outils étendent les Blueprints, les autres dev, comme le game dev, voire le game et level designer et les graphistes peuvent créer ou modifier des Blueprints, c’est Top !Je connais des gars qui bossent sur des matériaux et qui font des fonctions que j’arrive à peine à comprendre… les gars sont très doués, c’est quasiment un métier, développeur de matériaux ! Je pense à toi Marien si tu passes par là. Et tout ça à plusieurs en même temps en utilisant un outil comme perforce.

Donc, oui, je recommande aux débutants comme aux devs confirmés d’apprendre les BP et de les utiliser abondamment. Les premiers y verront un accès simplifié à ce qu’est la programmation. S’ils veulent toutefois être bons pour créer des BP performants, il leur faudra développer toutefois des compétences en programmation, en algorithmique, etc. On ne code bien en BP que si on a des compétences en algorithmique, mais également si on sait comment fonctionne un compilateur et l’assembleur. Un CPU, un GPU … ce qu’est un garbage collector par exemple, car UE4 en utilise un.

Quant aux seconds, ils pourront utiliser le meilleur des 2 mondes et c’est vraiment le pied ! Plus aucune limite à Unreal Engine, de belles fonctions à appeler en BP… y-a même un commerce derrière cela, car les dev confirmés peuvent vendre les librairies développées sous forme de plugins et utilisables par des débutants en BP. C’est du middleware.

Et si vous n’êtes pas un pro du C++, restez au Blueprint ! Vous ferez moins de dégâts… Non, sans dec !

Voilà, j’espère avoir été compréhensible par toutes et par tous… ce n’est pas toujours évident. J’ai l’impression de ne pas avoir fait complètement le tour du sujet.. j’aurais voulu vous dire que derrière les Blueprints vous avez des dev expérimentés qui optimisent un max… je ne serai pas étonné qu’ils soient capable de // le code d’ici quelques temps, d’envoyer une partie des BP dans le GPU… à l’instar d’ADA – plus un langage est “protégé”, plus on peut l’accéléré, prédire les sorties, etc.

Si vous voulez un tome sur le C++, merci d’en faire part à l’éditeur car il n’y pas de plan pour l’instant ! Les ventes sur le multijoueurs et le réseau commencent à arriver, mais le tome décolle moins vite que les autres… il est plus effrayant ! ^^

Laisser un commentaire