2015-09-23 12 views
6

Ich möchte meiner C++ Gameengine Skriptfunktionen hinzufügen.Racket als Skriptsprache in einer Spielengine

Ich habe Engine.exe, Physics.dll, Audio.dll und ich hinzufüge Scripting.dll, die einen High-Level-Racket-Wrapper ist.

Engine.exe Lasten Physics.dll und richtet Physik Welt, lädt Audio.dll und richtet Audio-Welt ein. Es soll geladen werden Scripting.dll, um Bindungen zu Physics.dll, Audio.dll einzurichten und Spiel-Skripte zu laden.

AFAIK gibt es zwei mögliche Wege Racket in ein C++ Programm einzubetten:

Foreign Interface Mit bizarren scheint aufgrund Notwendigkeit Physics.dll, Audio.dll zweimal zu laden: zuerst aus Engine.exe und dann aus dem Spiel-Skript.

Das Schreiben Extensions sieht ansprechender aus, weil es Skriptbindungen auf C++ - Seite ermöglicht. Auf der anderen Seite müssen Sie Ihre Erweiterung mit raco ctool erstellen, verknüpfen Sie es mit mzdyn Objektdatei - die auch peinlich aussieht: Warum nicht mzdyn eine statische Bibliothek machen?

Ich möchte ein einzelnes Verfahren, z. setupScriptBindings(), sowohl in Physics.dll als auch in Audio.dll, und beim Start von Engine.exe anrufen.

Gibt es einen einfachen Weg, es zu tun?

+0

Hm, vielleicht [diese] (http://docs.racket-lang.org/inside/embbedding.html) Beschreibung hilft. –

+0

Hm ... die Links, die Sie zur Verfügung stellen, sprechen über das Einbetten von C/anderen Code ** in ** ein Racket-Programm. Von Ihrer Beschreibung, ich denke, Sie wollen es umgekehrt, z. Einbetten von Racket in Ihre C++ - Anwendung: http://docs.racket-lang.org/inside/embbedding.html Obwohl die einfachste und wahrscheinlich sauberste Lösung wäre, eine Art Protokoll für die Kontrolle Ihrer Spieleinheiten zu definieren, und dann Schläger zu starten als ein neuer Prozess, Kommunikation mit Sockets oder einem anderen IPC-Mechanismus. –

+0

Offtopic: Racket wurde erfolgreich in der Videospiel-Produktion von Naughty Dog verwendet. Siehe [«Racket auf der Playstation 3»] (http://www.youtube.com/watch?v=oSmqbnhHp1c) und [«State-Based Scripting in Uncharted 2: Unter Dieben»] (http: //www.gameenginebook .com/resources/gdc09-staatscripting-uncharted2.pdf). –

Antwort

3

Nachdem ich sowohl die Erweiterung und FFI-Methoden der Verbindung von Racket mit C-Code verwendet habe, muss ich sagen, der FFI Ansatz ist viel nicer. Die Bindungen im Racket zu den C-Funktionen sind gut spezifiziert und robust und der Umgang mit C-Typen im Racket ist sehr schön. Der einzige Nachteil bei der Verwendung des FFI-Ansatzes ist, dass AFAIK Ihr Racket-Programm die Treiberanwendung sein muss.

Mit dem Einbettungsansatz ist Ihre C/C++ - Programmdatei der Treiber, aber die Schnittstelle mit dem Racket-Code zu deklarieren ist viel mehr manuell und fehleranfällig. Ganz zu schweigen davon, dass Sie entweder raco ctool herausfinden müssen und es replizieren müssen oder das Racket-Build-System übernehmen muss. Für unsere Zwecke haben wir die Racket-Quellen extrahiert und selbst gebaut. Ich empfehle diesen Ansatz nicht wirklich.

Schließlich für meine Zwecke eine Anwendung mit einer fremden .DLL/.so-Datei, die es für C-Funktionen geladen funktioniert am besten funktioniert, aber es klingt wie Sie möglicherweise mit der Einbettung stecken bleiben.

+0

Danke. Ja, ich brauche eine eingebettete Lösung. Obwohl Sie sagen, dass es schwierig sein könnte, scheint mir der Bau von Racket aus der Quelle ansprechender zu sein. Wenn Sie ein Beispiel für eine «native» ↔ «Skript» -Bindung von Ihrem embedding-basierten Ansatz geben könnten, wäre das sehr hilfreich. Welche Form der Skriptausführung haben Sie gewählt: Klartext, [Bytecode] (http://docs.racket-lang.org/raco/make.html) oder [eigenständige ausführbare Datei] (http: //docs.racket-lang. org/raco/exe.html)? –

+2

Wir würden Klartext oder Bytecode verwenden. Bytecode ist merklich schneller, aber Sie müssen darauf achten, dass es aktualisiert wird oder dass Racket es bei Bedarf kompiliert. –

+2

Und unsere ursprüngliche <-> Skriptbindung sah genauso aus wie das Beispiel in der Dokumentation ... nichts besonderes. –