Was sind die Vor- und Nachteile der Integration von Lua in ein C ++ - Spiel?

37

Ich habe ein C ++ - Programmierbuch und es enthält einen Lua-Abschnitt. Ich habe angefangen, den Lua-Abschnitt zu lesen, und das hört sich interessant an, aber ich kann die Vor- und Nachteile der Verwendung von Lua in meinem C ++ - Spiel nicht feststellen. Der einzige Vorteil, den ich mir derzeit vorstellen kann, ist, dass Sie einige Codierungsaktualisierungen über Lua vornehmen können, ohne neu kompilieren zu müssen. Ansonsten fällt mir nichts ein. Welche Vor- und Nachteile hat das Hinzufügen von Lua zu einem C ++ - Spiel?

Beispiele wären willkommen.

Ryan
quelle
Stimmen Sie zu, dass es diesen Fragen ähnlich ist, aber was hier wichtig ist, sind die Nachteile.
Jonathan Dickinson
@JonathanDickinson die antworten zeigen aber nicht in diese richtung ... sagen im grunde das selbe wie in der verlinkten frage.
Mistzack

Antworten:

33

Der einzige Vorteil, den ich mir derzeit vorstellen kann, ist, dass Sie einige Codierungsaktualisierungen über Lua vornehmen können, ohne neu kompilieren zu müssen.

Reduzieren Sie den Nutzen nicht so leicht. Sie werden nie verstehen, wie produktiv Sie sein werden, bis Sie den Neukompilierungsschritt wegnehmen.

Der "Fluss" ist ein ziemlich gut verstandenes psychologisches Konzept, wenn es um Arbeit geht. Der Flow ist das Gefühl, dass Sie bekommen, wenn Sie sich auf eine Aktivität konzentrieren, wenn Sie Probleme analysieren und lösen, fast ohne nachzudenken, usw. Sie sind am produktivsten, wenn Sie "fließen".

Kompilier mal vermassel das alles. Es ist schwierig, im Fluss zu bleiben, wenn zwischen den Tests sogar eine Kompilierung von 10 Sekunden liegt.

Wenn du das Gameplay entwickelst, hast du normalerweise eine "enge Schleife". Sie haben eine Idee, programmieren einen Test, um festzustellen, ob er funktioniert, und probieren ihn anschließend aus. Wenn es nicht funktioniert, ändern Sie es und versuchen es erneut. Die "Code-to-Test" -Zeit ist für die Aufrechterhaltung des Flusses sehr wichtig. Es ist entscheidend, es so klein wie möglich zu halten.

Mit Lua (oder einer anderen eingebetteten Skriptsprache) können Sie Änderungen testen, nicht nur ohne "Kompilieren", sondern live im Spiel . Abhängig davon, wie Sie Ihr Spiel erstellen, können Sie einen Befehl ausführen, mit dem das Spiel mit neuen Skripten neu gestartet wird, ohne Daten anhalten und neu laden zu müssen. Sie müssen nicht nur nicht neu kompilieren, sondern auch nicht erneut ausführen.

Die Fähigkeit, dies zu tun, kann bei richtiger Motorunterstützung die Produktivität dramatisch steigern.


Ein weiterer großer Vorteil von Skripten ist die Fähigkeit, sich einfach nicht darum zu kümmern. Wenn Sie lange Zeit mit dem Schreiben von C ++ verbracht haben, werden Sie erstaunt sein, wie viel Zeit Sie über minutae verbringen. Wo Speicher gelöscht wird. Wo dies befreit wird. Selbst wenn Sie shared_ptrüberall verwenden, werden Sie schon durch die Eingabe all dieser Variablentypnamen langsamer.

In einer dynamisch getippten Skriptsprache müssen Sie sich nicht darum kümmern. Das Scoping ist einfach. Funktionen sind erstklassige Objekte; Sie müssen Funktoren nicht manuell erstellen. Es ist einfach so einfach , einige Dinge zu tun.

Nun, das hat auch Nachteile, wenn Sie kein disziplinierter Programmierer sind. Es ist sehr einfach, Globals in Lua zu verwenden (obwohl es Möglichkeiten gibt, dies zu verhindern). Nicht fürsorglich bedeutet, dass Sie beim Codieren sehr schlampig sein können.

Aber dann wieder, kann Vorteile haben sehr nachlässig zu sein .


Ein weiterer Vorteil von Lua ist, dass es eine nette Datenbeschreibungssprache macht. Ähnlich wie JSON nur eine JavaScript-Datei ist, die ein Array / eine Tabelle erstellt und zurückgibt, können Sie Lua-Skripte erstellen, die Tabellen zurückgeben.

Dies ist nützlich für Konfigurationsdateien. Das Tabellenformat von Lua ist viel besser als das von .ini. Das Format ist immer noch recht übersichtlich, kompakt und erweiterbar.

Oh, und es ist immer noch ein Lua-Skript, damit es die eigentliche Logik ausführen kann. Der Nachteil dabei ist , dass es sich um ein Lua-Skript handelt, mit dem die eigentliche Logik ausgeführt werden kann . Das könnte im Spiel katastrophal sein, da der Benutzer möglicherweise anfangen könnte, Dinge zu vermasseln.

Tatsächlich ist dies jedoch leicht zu handhaben. Lua ist für die Einbettung konzipiert, was bedeutet, dass die Isolierung eigentlich recht einfach ist. In der Tat liefert ein neuer Lua-Staat standardmäßig nichts . Sie müssen tatsächlich etwas tun, um auch die grundlegendsten Lua-Standardbibliotheken verfügbar zu machen. Der Dateizugriff, der Spielstatuszugriff usw. sind alles Opt-in-Optionen, keine Opt-out-Optionen. Und jeder Lua-Staat ist voneinander getrennt. Der Lua-Status, den Sie für AI-Skripte verwenden, muss nicht der Lua-Status sein, den Sie für Konfigurationsdateien verwenden.

Ich habe tatsächlich einen Code, mit dem Sie viele Lua-Standardbibliotheken registrieren können, der jedoch alle Datei-E / A-Vorgänge durchläuft und entfernt. Das Schlimmste, was eine Lua-Skript-basierte Konfigurationsdatei anrichten kann, ist, dass Ihr Spiel sofort abstürzt, wenn es ausgeführt wird. Und da Sie diese Konfigurationsdateien nicht manuell freigeben, wäre das für einen Hacker kein großer Spaß.


Ich würde sagen, dass der größte Nachteil jeder Skriptsprache das Debuggen ist. Die meisten Skriptsprachen haben keine Debugger und Lua ist nicht anders. Lua verfügt über alle Tools, die zum Erstellen von Debugging-Tools erforderlich sind. Es ist jedoch kein Debugger eingebaut. Sie müssen eine zusammenstellen. Und das wird ein angemessenes Maß an Arbeit erfordern.

Oder du kannst mit "printf debugging" fällig machen. Es hängt wirklich davon ab, wie viel Lua-Code Sie schreiben.

Nicol Bolas
quelle
1
Fließen ist nicht immer gut; Dinge automatisch zu erledigen bedeutet manchmal, sich nicht die Zeit zu nehmen, über Designalternativen hinwegzugehen.
Lurscher
10
@lurscher: Design ist das, was Sie tun, bevor Sie sich an den Code setzen. Sie sollten alle diese Entwurfsalternativen ausgearbeitet haben, bevor Sie mit dem Schreiben, Testen und Debuggen Ihres Codes begonnen haben.
Nicol Bolas
23

Wo ich arbeite:

Vorteile:

  • Verbesserungen der Iterationszeit . Unser Spiel ist so eingerichtet, dass es ein Host-Dateisystem nach Änderungen abfragt und Änderungen automatisch "schlürft". (Sie werden erst beim nächsten Öffnen der Datei wirksam. In der Praxis ist dies jedoch eine wesentliche Verbesserung: Laden Sie das Level neu, und Ihre neuen Lua-Änderungen werden sofort wirksam.)
  • Konsolenintegration . Jede Debug-Funktionalität kann mit einer REPL an eine herkömmliche Konsole im Quake-Stil angehängt werden. Für interne Builds können wir sogar eine lua REPL an einen einfachen Socket anschließen, der Telnet spricht, und wir haben die Netzwerkkontrolle über unser Spiel.
  • Reduzierte API und niedrigere Lernkurve . Nichttechnische Künstler und Designer können sich an einigen Aufgaben beteiligen, bei denen es sich normalerweise um Engpässe für Programmierer handelt.
  • spezialisierte statische Code-Analyse . Es ist einfach, die Ausgabe von zu analysieren luac -lund einen Blick auf den Bytecode zu werfen, um eine Analyse durchzuführen. Es ist auch ziemlich einfach, die meisten Lua-Quelldateien zu analysieren, besonders wenn Sie eine Kodierungskonvention haben. Wir können lokale Konventionen durchsetzen. Sie können auch in Metalua nach noch mehr Power suchen .
  • Fehlerbehandlung . Wenn unsere API absturzfrei ist, können wir sie abfangen und mithilfe von wiederherstellen, auch wenn lua etwas Dummes tut lua_pcall.
  • einfache API-Erweiterung . Das Schreiben einer neuen Funktion für die Lua <-> C ++ - API ist nicht allzu schwierig. Es gibt auch Pakete, die dazu beitragen, dies zu automatisieren.
  • einfache Quelle . Änderungen vorzunehmen, um zB Gleitkomma-Mathematik im lua-Interpreter zu vermeiden (wichtig auf einigen Embedded-Plattformen) oder für bestimmte Systeme zu optimieren, ist nicht allzu schwierig!
  • metatables . Die sind Wahnsinn. So viel Potenzial, um zur Laufzeit interessante Dinge zu tun. Wir haben "virtuelle Tabellen", die eigentlich keinen Inhalt haben und einen Blick in eine komplizierte Datenstruktur auf der C ++ - Seite unserer Spiele werfen.
  • Coroutinen . Es ist erstaunlich, in der Lage zu sein, z. B. AI-Verhaltensskripte anzuhalten und fortzusetzen. Es ist allerdings ein bisschen schlauer für den Lua Scripter - wir arbeiten immer noch daran, wie wir dies mit unserem Motor "sicherer" machen können.

Nachteile:

  • unvorhersehbare GC . Was wir tun stepsollten, ändert sich drastisch pro Spiel. Einige funktionieren besser mit vollem GC für jeden Frame (kleines Arbeitsset). Einige arbeiten mit viel kleineren Pässen seltener besser. Beachten Sie, dass es eine Menge Arbeit gibt, die GC auf neueren Lua-Versionen und in einigen Patches zu verbessern (für die Sie sich nicht scheuen sollten, sie zu verwenden!).
  • höherer Aufwand . Wir behalten einen Großteil unserer großen Datenstrukturen auf der C-Seite bei, um den Speicheraufwand pro Tabelleneintrag zu vermeiden. C ++, C und Assembly erzeugen im Allgemeinen schnelleren Code. Es bleibt also bei 90% der Spiel-Engine, die nicht leistungskritisch ist, und gelegentlich migrieren wir Dinge von lua nach C (oder umgekehrt).
  • Fragmentierung . Vielleicht das größte Problem bei kleinen Speichersystemen. Normalerweise verwenden wir kleine Objektpools und einen vollständig separaten großen Objekthaufen für lua. Wir haben volle GC-Pässe für strategische Punkte im Spiel vergeben. Wir entladen Skripte oder werfen die lua_Statein einigen Fällen komplett weg . Und wir haben immer noch manchmal Probleme. Das Optimieren der Größe der kleinen Objektpools (der Einfachheit halber und mit geringerem Overhead) und der Größe des lua-spezifischen großen Objekthaufens kann problematisch sein. Auf Systemen mit mehr als 4 MB haben wir uns jedoch noch nicht mit den spezialisierten Heaps und Pools befasst.
  • mangelnde Typensicherheit . Wenn Sie nicht über ein gutes Toolset für die statische Codeanalyse verfügen, können Sie häufig auf die Überprüfung von Laufzeitfehlern zurückgreifen (möglicherweise mithilfe von __indexund __newindex). Es ist besser, wenn Sie Fehler beim Kompilieren abfangen können. Es gibt verschiedene Dinge, die Sie tun können, um dies zu lindern.

Lua ist sehr zu empfehlen, sei einfach bereit, ein bisschen damit zu arbeiten! Vielleicht möchten Sie auch Eichhörnchen ausprobieren, obwohl ich glaube, dass es eine kleinere Nutzerbasis hat.

Leander
quelle
Ich wünschte, ich könnte dies mehrmals abstimmen. Sehr umfangreich, sehr aufschlussreich, klar strukturiert. +1
Koarl
5

Eigentlich gibt es 3 große Vorteile:

Mit diesen Faktoren können Sie als Spieleentwickler Funktionen aktivieren, die die Entwicklung beschleunigen und die Qualität Ihres Spiels verbessern.

Beispielsweise:

  • Sie können Ihre Spielelogik einfach ändern, indem Sie Ihr Spiel über eine Datei oder ein Netzwerk-Socket aktualisieren.
  • Sie können Benutzern erlauben, ihre eigenen Skripte zu erstellen (für Bots oder Mods).
  • Ihre Spieleentwickler und -künstler können Teile des Spiels aktualisieren und testen, ohne dass Sie Ihr Kompilierungswerkzeug verwenden müssen.
  • Sie müssen nicht jedes Mal neu kompilieren, wenn Sie einige Skripte ändern.
  • Sie müssen nicht das gesamte Spiel neu schreiben, wenn Sie Plattformen / Engines / Sprachen ändern.
Kojote
quelle
1
"Sie müssen nicht das gesamte Spiel neu schreiben, wenn Sie Plattformen / Engines / Sprachen ändern." Es sei denn, Sie wechseln von Lua zu einer anderen Sprache. Und wenn Sie Ihr "gesamtes Spiel" in Lua schreiben, wenn Sie die Engines wechseln, muss diese Änderung Lua zur Verfügung gestellt werden (oder Sie benötigen eine Abstraktion zwischen Lua und der Engine, um die Details zu verbergen). Ich verstehe also nicht, wie Lua in solchen Fällen hilft.
Nicol Bolas
3

Aus meiner Erfahrung ein bisschen runtergekocht.

Vorteile

  • Die Erstintegration ist denkbar einfach. Es gibt Tools zum Erstellen von Bindungen, aber der Bindungsmechanismus ist so einfach, dass Sie in kürzester Zeit eine eigene Version davon mit Ihren eigenen benutzerdefinierten Funktionen schreiben können
  • Sie erhalten eine viel schnellere Iteration der Spielelogik (vorausgesetzt, Sie implementieren das Neuladen zur Laufzeit)
  • Sie erhalten ein befreiendes Umfeld zum Experimentieren: Sie werden mehr Dinge ausprobieren, weil der Aufwand dafür erheblich sinkt
  • Vertraute Syntax: Bei allen Unterschieden wird es Ihnen als C-Programmierer schwer fallen, sich innerhalb weniger Stunden nicht darin zurechtzufinden
  • Bessere Trennung der Spielelogik von "Engine": Ihre Engine wird zu einem Dienstanbieter, der dem Lua-Client eine anständige API zur Verfügung stellen muss. Die Sprachbarriere bringt Sie dazu, mehr darüber nachzudenken, anstatt nur dort hineinzugreifen und eine Mitgliedsvariable zu fummeln

Nachteile

  • Lua Memory Management ist nicht ideal für Spiele. Sie kommen damit klar, Sie mögen es nicht
  • Das Debuggen von Lua ist schrecklich. Sie müssen arbeiten, um die Erfahrung zu verbessern
  • Wenn Sie die Daten in Lua behalten, müssen Sie ein Debugging in Lua durchführen. Die Überprüfung von C aus ist zunächst schwierig
  • Lua hat eine Menge Möglichkeiten, sich selbst in der Fußsyntax zu erschießen, da alle Variablen standardmäßig global sind
  • Lua ist wie jede andere Programmiersprache. Erwarten Sie nicht, dass sich Nicht-Programmierer auf magische Weise in Programmierer verwandeln, nur weil Sie den Compiler entfernt haben
  • Lua gut zu integrieren und zu unterstützen ist ein großer Arbeitsaufwand. Erwarten Sie nicht, dass es sofort schnurrt. Es ist fair anzunehmen, dass Sie diese Kosten tatsächlich über ein paar Spiele amortisieren müssen

Endgültiges, persönliches Urteil: Wenn Sie ein Spiel mit anständiger Größe erstellen und noch keine Skriptsprache haben, dann holen Sie sich Lua. Es wird sich lohnen.

Chris Subagio
quelle
1

Garry's Mod ist ein Beispiel für ein Spiel, das Lua und C ++ verwendet. Sie benutzen Lua für alle Mods, was es für die Leute viel einfacher macht, sie zu machen. C ++ wird für alle Interna verwendet. Der einzige Nachteil, den ich mir vorstellen kann, ist die Tatsache, dass Lua nicht so schnell ist wie C ++.

TheGag96
quelle