Quels sont les avantages et les inconvénients de l'intégration de Lua dans un jeu en C ++?

37

J'ai un livre de programmation de jeux C ++ et il comporte une section Lua. J'ai commencé à lire la section Lua et cela semble intéressant, mais je ne peux pas déterminer les avantages et les inconvénients de l'utilisation de Lua dans mon jeu en C ++. Le seul avantage que je peux actuellement penser est que vous pouvez effectuer des mises à jour de codage, via Lua, sans avoir à recompiler. À part ça, je ne peux penser à rien. Alors, quels sont les avantages et les inconvénients de l’ajout de Lua à un jeu en C ++?

Des exemples seraient appréciés.

Ryan
la source
Convenez que cela ressemble à ces questions, mais ce qui est important ici, ce sont les «inconvénients».
Jonathan Dickinson
@ JonathanDickinson, les réponses n'indiquent pas cette direction, mais elles sont fondamentalement les mêmes que dans la question liée.
Bummzack

Réponses:

33

Le seul avantage que je peux actuellement penser est que vous pouvez effectuer des mises à jour de codage, via Lua, sans avoir à recompiler.

Ne négligez pas l'utilité de ceci si facilement. Vous ne comprendrez jamais à quel point vous serez productif tant que vous n'aurez pas supprimé l'étape de recompilation.

Le "flux" est un concept psychologique assez bien compris quand il s'agit de travailler. Le flux est ce sentiment que vous ressentez lorsque vous êtes concentré sur une activité, lorsque vous analysez et résolvez des problèmes presque sans réfléchir, etc. Vous êtes au maximum de votre productivité lorsque vous "coulez".

Les temps de compilation bousillent tout ça. Il est difficile de rester dans le flot si vous avez même une compilation de 10 secondes entre deux tests.

Lorsque vous développez le gameplay, vous avez généralement une "boucle serrée". Vous avez une idée, vous codez un test pour voir si cela fonctionne, puis vous l'essayez. Si cela ne fonctionne pas, modifiez-le et essayez à nouveau. Le temps de "code à tester" est très important pour le maintien du flux. Obtenir le plus petit possible est crucial.

Ce que Lua (ou tout autre langage de script intégré) vous permet de faire, c'est de tester les changements, pas seulement sans "compiler", mais de vivre dans le jeu . Selon la manière dont vous construisez votre jeu, vous pouvez exécuter une commande qui le relancera avec de nouveaux scripts sans avoir à arrêter et à recharger des données, etc. Non seulement vous n'êtes pas obligé de recompiler, vous n'avez pas besoin de le réexécuter.

La capacité de le faire, avec le support moteur approprié, peut augmenter considérablement la productivité.


Un autre avantage majeur du script est la possibilité de ne pas s'en soucier. Si vous avez passé beaucoup de temps à écrire en C ++, vous seriez surpris du temps que vous passez sur les minutae. Où la mémoire est supprimée. Où cela est libéré. Même si vous utilisez shared_ptrpartout, le simple fait de taper tous ces noms de type de variable vous ralentit.

Dans un langage de script à typage dynamique, vous n'avez pas à vous en soucier. Le cadrage est simple. Les fonctions sont des objets de première classe. vous n'avez pas à construire manuellement des foncteurs. C'est tellement facile de faire certaines choses.

Maintenant, il y a des points négatifs, si vous n'êtes pas un programmeur discipliné. Il est très facile d’utiliser des globals dans Lua (bien qu’il existe des moyens de l’empêcher). Ne pas s'en soucier signifie que vous pouvez être très bâclé lorsque vous codez.

Mais encore une fois, être très bâclé peut avoir des avantages .


Un autre avantage de Lua est qu’il fait un bon langage de description de données. Tout comme JSON est juste un fichier JavaScript qui construit et retourne un tableau / une table, vous pouvez créer des scripts Lua qui renvoient des tables.

Ceci est utile pour les fichiers de configuration. Le format de table de Lua est bien meilleur que celui de .ini. Le format est encore plutôt propre, compact et extensible.

Oh, et c'est toujours un script Lua, il peut donc exécuter une logique réelle. L'inconvénient de cela est ... eh bien, c'est un script Lua, donc il peut exécuter une logique réelle . Cela pourrait être désastreux dans le jeu, car l'utilisateur pourrait potentiellement commencer à tout gâcher.

Mais en réalité, cela se règle facilement. Lua est conçu pour l'intégration, ce qui signifie que l'isolement est en fait assez facile. En effet, un nouvel état de Lua ne fournit rien par défaut; vous devez réellement faire quelque chose pour exposer même la plus élémentaire des bibliothèques Lua standard. L'accès aux fichiers, l'accès aux états du jeu, etc., sont tous opt-in, pas opt-out. Et chaque état de Lua est séparé l’un de l’autre. L'état Lua que vous utilisez pour les scripts AI ne doit pas nécessairement être l'état Lua que vous utilisez pour les fichiers de configuration.

En fait, j'ai un code qui vous permet d'enregistrer de nombreuses bibliothèques Lua standard, mais qui passe et supprime tous les fichiers IO. En fin de compte, le pire qu’un fichier de configuration basé sur un script Lua puisse faire est de faire planter votre jeu immédiatement après l’exécution de celui-ci, en l’utilisant à court de mémoire. Et puisque vous ne partagez pas ces fichiers de configuration manuellement, ce ne serait pas très amusant pour un pirate informatique.


Je dirais que le plus gros inconvénient de tout langage de script est le débogage. La plupart des langages de script n'ont pas de débogueurs, et Lua n'est pas différent. Lua dispose de tous les outils nécessaires pour créer des outils de débogage. Mais il n’a pas réellement de débogueur intégré. Vous devez en mettre un ensemble. Et cela nécessitera un degré de travail raisonnable.

Ou vous pouvez rendre compte avec "printf debugging". Cela dépend vraiment de combien de code Lua vous écrivez.

Nicol Bolas
la source
1
couler n'est pas toujours une bonne chose; faire les choses automatiquement signifie parfois ne pas prendre le temps de marcher sur des alternatives de conception.
Lurscher
10
@ lurscher: Le design est ce que vous faites avant de vous asseoir pour coder. Vous auriez dû définir toutes ces alternatives de conception avant de commencer à écrire, tester et déboguer votre code.
Nicol Bolas
23

Où je travaille:

Avantages:

  • amélioration du temps d'itération . Notre jeu est configuré pour interroger un système de fichiers hôte afin de connaître les modifications et automatiquement "filtrer" les modifications. (Ils n'entreront en vigueur qu'à l'ouverture du fichier suivant, mais dans la pratique, c'est une amélioration majeure: rechargez le niveau et vos nouvelles modifications de lua entreront immédiatement.)
  • intégration de la console . Toute fonctionnalité de débogage peut être connectée à une console traditionnelle de style Quake avec un REPL. Pour les versions internes, nous pouvons même connecter un LAU REPL à une simple prise telnet, et nous avons le contrôle du réseau sur notre jeu.
  • api réduit et courbe d'apprentissage inférieure . Les artistes et les concepteurs non techniques peuvent participer à certaines tâches qui seraient généralement gênées par le programmeur.
  • analyse de code statique spécialisé . Il est facile d'analyser la sortie luac -let de jeter un coup d'œil sur le bytecode pour effectuer une analyse. Il est également assez facile d'analyser la plupart des fichiers sources de Lua, en particulier si vous avez une convention de codage. Nous pouvons appliquer la convention locale. Vous pouvez également regarder dans metalua pour encore plus de puissance ici.
  • traitement des erreurs . Si notre API est exempte de crash, même si Lua fait quelque chose de stupide, nous pouvons l'attraper et récupérer en utilisant lua_pcall.
  • extension facile de l'API . Écrire une nouvelle fonction pour l'API Lua <-> C ++ n'est pas trop difficile. Il existe également des packages qui aideront à automatiser cela.
  • source simple . Modifier, par exemple, éviter les mathématiques en virgule flottante dans l'interpréteur lua (important sur certaines plates-formes intégrées) ou optimiser des systèmes particuliers n'est pas si difficile!
  • métatables . Ce sont géniaux. Tant de potentiel pour faire des choses intéressantes au moment de l'exécution. Nous avons des "tables virtuelles" qui, en réalité, ne contiennent aucun contenu et effectuent une recherche dans une structure de données complexe du côté C ++ de nos jeux.
  • coroutines . Pouvoir arrêter et reprendre, par exemple, des scripts de comportement IA est incroyable. Cela demande un peu plus de savoir-faire de la part du scripteur Lua - nous travaillons toujours sur la manière de rendre cela plus "sûr" avec notre moteur.

Les inconvénients:

  • imprévisible GC . Le réglage de ce que nous stepdevrions être change radicalement à chaque match. Certaines fonctionnent mieux avec une GC complète à chaque image (petit jeu de travail). Certains fonctionnent mieux avec des passes beaucoup plus petites et plus rarement. Notez qu'il y a beaucoup de travail à faire pour améliorer le GC avec les nouvelles versions de lua et dans certains correctifs (que vous ne devriez pas avoir peur d'utiliser!)
  • frais généraux plus élevés . Nous conservons une grande partie de nos grandes structures de données côté C afin d’éviter une surcharge de mémoire par entrée de table. C ++, C et assembly produisent généralement du code plus rapide. Ainsi, les 90% du moteur de jeu ne sont pas critiques en termes de performances, et nous migrons parfois des éléments de Lu vers C (ou inversement).
  • la fragmentation . Peut-être le plus gros problème sur les petits systèmes de mémoire. Nous utilisons généralement de petits pools d’objets et un segment de mémoire de grande taille complètement séparé pour Lua. Nous mettons des passes complètes de GC dans les points stratégiques du jeu. Nous déchargeons les scripts ou les rejetons lua_Stateentièrement dans certains cas. Et nous avons encore parfois des problèmes. Ajuster les tailles des petits pools d'objets (ils sont fixes, pour plus de simplicité et moins de temps système) et la taille du tas d'objets volumineux spécifique à Lua peut s'avérer difficile. Mais sur les systèmes de plus de 4 Mo environ, nous n’avons pas encore pris la peine de nous préoccuper des tas et des bassins spécialisés.
  • manque de sécurité de type . Si vous ne disposez pas d'un ensemble d'outils d'analyse de code statique bien construit, vous aurez recours à de nombreuses vérifications d'erreur d'exécution (peut-être en utilisant __indexet __newindex). C'est mieux si vous pouvez détecter les erreurs au moment de la compilation. Vous pouvez faire plusieurs choses pour remédier à cela.

Lua est fortement recommandé, soyez juste disposé à travailler avec elle un peu! Vous pouvez également vouloir vérifier Squirrel , bien que je pense qu’il a une base d’utilisateurs plus petite.

leander
la source
J'aimerais pouvoir voter à plusieurs reprises. Très complet, très perspicace, clairement structuré. +1
Koarl
5

En fait, il y a 3 grands avantages:

Ces facteurs vous permettent, en tant que développeur de jeux, d'activer des fonctionnalités qui accéléreront le développement et augmenteront la qualité de votre jeu.

Par exemple:

  • Vous pourrez modifier vos logiques de jeu simplement en mettant à jour votre jeu à partir d'un fichier ou d'un socket réseau.
  • Vous pouvez autoriser les utilisateurs à créer leurs propres scripts (pour les robots ou les mods)
  • Vos concepteurs de jeux et artistes pourront mettre à jour et tester des parties du jeu sans avoir à utiliser votre jeu d’outils de compilation.
  • Vous ne devrez pas recompiler chaque fois que vous modifiez quelques scripts.
  • Vous n'aurez pas à réécrire tout le jeu si vous changez de plate-forme / moteur / langue.
Coyote
la source
1
"Vous n'aurez pas à réécrire tout le jeu si vous changez de plate-forme / de moteur / de langue." Sauf si vous passez de Lua à une autre langue. Et si vous écrivez votre "jeu entier" en Lua, si vous changez de moteur, ce changement doit être exposé à Lua (ou vous avez besoin d'une certaine abstraction entre Lua et le moteur pour masquer les détails). Je ne vois donc pas comment Lua peut aider dans ces cas.
Nicol Bolas
3

D'après mon expérience, s'est un peu résorbé.

Avantages

  • L'intégration initiale est vraiment facile. Il existe des outils pour aider à générer des liaisons, mais le mécanisme de liaison est si simple que vous pouvez écrire votre propre version, avec vos propres fonctionnalités personnalisées, en un rien de temps
  • Vous obtenez une itération beaucoup plus rapide sur la logique de jeu (en supposant que vous implémentiez le rechargement à l'exécution)
  • Vous obtiendrez un environnement libérateur dans lequel vous pourrez expérimenter: vous allez essayer plus de choses parce que la charge de travail qui en résulte diminue considérablement.
  • Syntaxe familière: malgré toutes ses différences, il serait difficile pour un programmeur C de ne pas être à l'aise en quelques heures
  • Meilleure séparation de la logique de jeu et du "moteur": votre moteur devient un fournisseur de services qui doit exposer une API décente au client Lua. La barrière de la langue vous fait penser à cela plus, au lieu de simplement y toucher et de bidouiller une variable membre

Les inconvénients

  • La gestion de la mémoire Lua n'est pas idéale pour les jeux. Vous y faites face, vous ne l'aimez pas
  • Le débogage de Lua est affreux hors de la boîte. Tu devras travailler pour améliorer l'expérience
  • Garder les données dans Lua signifie que vous aurez besoin de déboguer dans Lua: les inspecter à partir de C sera d'abord délicat
  • Lua a une bonne dose de shoot dans la syntaxe du pied, comme toutes les variables étant globales par défaut
  • Lua est un langage de programmation, comme tout autre. Ne vous attendez pas à ce que des non-programmeurs se transforment en magie simplement parce que vous avez supprimé le compilateur
  • Devenir bon pour intégrer et soutenir Lua est une grosse partie du travail. Ne vous attendez pas à ce qu'il ronronne dès la sortie de la boîte. Il est juste de supposer que vous devrez réellement amortir ce coût sur quelques jeux.

Dernier verdict: si vous construisez un jeu de taille décente et que vous n'avez pas encore de langage de script, procurez-vous Lua. Ça vaudra le coup.

Chris Subagio
la source
1

Garry's Mod est un exemple de jeu utilisant Lua et C ++. Ils utilisent Lua pour tous les mods, ce qui les rend beaucoup plus faciles à fabriquer. C ++ est utilisé pour tous les internes. Le seul inconvénient auquel je puisse penser serait le fait que Lua n’est pas aussi rapide que C ++.

TheGag96
la source