Dynamic Lua im Lua Code

Nov 22, 2011 at 1:01 PM
Edited Nov 22, 2011 at 1:05 PM

Hi,

vor Dynamic Lua hab ich ich LuaInterface benutzt, Dynamic Lua hat den wesentlichen Vorteil, dass es mit .Net Framework 4 läuft.

Vorneweg: Mit Lua kenn ich mich nicht besonders aus und mit C# hab ich erst vor Kurzem angefangen.

In meinem Projekt brauche ich Lua als Skriptsprache, die die in c# geschriebenen objekte kontrolliert. Die Kontrolle aus Lua (zB Obj1:MoveTo(5,5) ) führt den C# Code aus und der kümmert sich dann um DirectX und so weiter.

"Problem": Die AI und der "Spielengine" (so richtig kann man es bei mir als Engine nicht bezeichnen, ka was es ist...) sind in Lua geschrieben, d.h. Im Spielengine muss neue AI erstellt und ausgeführt werden. Dazu habe ich dem Engine ein Object 'g' mit u.a. folgender Methode bereitgestellt:

public dynamic NewAI()
		{
			dynamic lua = new DynamicLua.DynamicLua();
			AI.Add(lua);
			return lua;
		}


 

(zur zeit von Luainterface war das halt entsprechend ein klein bisschen anders)
(Ai ist ne arraylist, die die ai enthält, wird aber bisjetzt nicht weiter verwendet)


Der Engine kann also eine neue AI erstellen und dann den Code der AI mithilfe von 'g' ausgeführt werden (der muss nämlich von c# bestimmt werden weil er ja level unterschiedlich ist) und danach möchte der Engine in der AI ein paar variablen nachschauen (was halt so passiert ist)

AI01 = g:NewAI();
g:RunAICode(AI01);
 
Als ich noch LuaInterface verwendet habe, konnte ich jetzt in Lua schön folgende Sachen machen:
AI01["var1"] = 123456; LocationX = AI01["LocationX"] AI01:DoString(" WarMode = true ")

Problem: nichts von dem funktioniert mit DynamicLua. Auch nicht die coolen DynamicLua Sachen funktionieren:

AI ("WarMode = true") -- Attempt to call global userdata 'AI'
AI.WarMode = true -- field or property not found
LocationX = AI.LocationX -- gibt nicht 123 wieder, sondern den string "LocationX"

Das einzige, was mann machen kann ist LoadString verwenden (und da wäre mir DoString() lieber)
AI:LoadString("WarMode = true","name") (für was der Name parameter ist hab ich nicht verstanden...)
aber LoadString("return WarMode") funtkioniert nicht (returnt irgendne Userdata).

ich werde vermutlich mit der oben erwähnten AI ArrayList und dem Objekt 'g' workarounden, d.h. 2-3 neue Methoden schreiben mit denen der Lua Engine dem C# befehlen kann der Lua AI was zu befehlen und dann irgendwas wiedergeben (aber das ist ja nicht sinn der Sache)

Ich hoffe man kann alles soweit verstehen...

Meine Fragen:
Gibts ne andere Lösung?
Mach ich irgendwas falsch? (außer Lua in Lua ausführenzu wollen ;-) )
Wird sich an DynamicLua in nächster Zeit in der Richtung irgendwas ändern?

Vielen lieben Dank,

Someonelse

 

[edit]

wenn ich c# funktionen in die AI einbinde, funktioniert das ausführen vom Engine auch nicht

(ist für mich eigtl. nicht notwendig, war aber ein workaroundansatz)

Coordinator
Jun 27, 2012 at 12:27 PM

Hallo!

Tut mir Leid, dass ich jetzt erst antworte, ich hab diese Diskussion überhaupt nicht gesehen. Ich vermute es hilft dir nicht mehr, aber ich will deine Frage trotzdem beantworten:

Du scheinst etwas falsch zu verstehen, die ganzen Neuerungen von DynamicLua betreffen nur C# und funktionieren nicht in Lua selber. Im Lua Code wirst du den gleichen Syntax wie vorher benutzen müssen. Du kannst aber die AI Steuerung von C# aus machen und dort auch den neuen Syntax benutzen:

dynamic lua = new DynamicLua.DynamicLua();

dynamic AI01 = lua("return g:NewAI()");
//oder
dynamic AI01 = lua.g.NewAi();

//Dann klappt sowas auch:
lua.AI01.WarMode = true;
dynamic LocationX = lua.AI01.LocationX
Ich hoffe, jetzt ist dir die Funktionsweise von DynamicLua etwas klarer? Ansonsten frag einfach noch mal ;)

Jun 27, 2012 at 1:04 PM

Lol. Danke für die Antwort.

Ich bin nicht mehr so into C# oder Lua. Ich raff selber nicht mal was ich da schreibe. Es war so dass ich mit C# die GUI und den Untergrund für das Lua zeugs gemacht habe. C# hat einen von mir sogenannten "Engine" ausgeführt. Dass der Engine in Lua war, hatte den Vorteil, dass später auch mal User einen schreiben können. Der Engine hat praktisch die "Spielregeln" vorgegeben (ein paar Variablen bereitgestellt) und die AI durfte dann Probleme lösen. (DIe Ai konnte auch von den Usern geschrieben werden). Deswegen musste der Engine (in Lua) die AI (in Lua) ausführen. Der Engine hat die genannten Variablen reingestopft und die AI hat sich dann anhand davon entschieden,bspw. an welchen Ort sie geht oder welche Waffe sie nutzt. Was sie machen will hat sie in Variablen gespeichert und der Engine hats dann rausgeholt.

das mit dem Reinstopfen und Rausholen hat dann glaub ich nicht so geklappt. Außerdem musste der Engine und die AI idiotensicher sein, aber dass hat gut geklappt.

Ich glaube ich habe irgendeinen coolen (?) Workaround gefunden. Ich schau ihn mir mal an nachher (ich muss jetzt zur Uni) und schreibe wenn ich ihn checke.

Vllt fang ich das AI Projekt nochmal an und dann wird mir das hilfreich sein (es war schon sehr interessant).

Nochmals vielen Dank!

Jun 27, 2012 at 7:44 PM
Edited Jun 27, 2012 at 7:45 PM

Also ich habs durchgeschaut, aber ich kann mich wirklich nicht erinnern was ich mir wobei gedacht habe. Mein Workaround scheint gewesen zu sein wieder auf luainterface umzusteigen. Was aus dem oben beschriebenen Workaround wurde weiß ich nicht. Vermutlich war es zu aufwendig oder das Rausholen der Variablen hat entweder aus dem AI-Lua-Objekt oder danach aus dem C# nicht geklappt. Das ist ein Beispiel was ich machen kann(Player ist die "AI"):

 

-- Im Engine
Player = g:NewPlayer();

 

Player["PositionY"] = 0
Player["PositionX"] = 0 -- Player weiß jetzt wo er ist
Player:DoString("PositionX = 0") -- Wenn ich ganze Codesnippets von dem PlayerLua Objekt ausführen lassen möchte
 g:RunPlayerCode(Player); -- Player überlegt ganz viel, unter anderem in welche Richtung er laufen möchte
Direction = Player["Dir"] -- Variable kann easy abgerufen werden


 /* Die Lua Methoden von g im C# sieht so aus: */
 public Lua NewPlayer()
{ Lua lua = new Lua();

            Players.Add(lua);
return lua;
/* Erinnert an das Zeug aus dem ersten post ;) */
 }
 public void RunPlayerCode(Lua lua)
{ form.RunLuaCode(lua); }
/* von form: */ public void RunLuaCode(Lua lua)
{
try {
lua.DoString(PlayerCode); /* Player code ist das Lua Programm der AI (in Lua gecodet) */
}
// Mein Errorhandling:
 catch (Exception e)
{
End();
error(e.Message);
}
}

(sorry das der code so durcheinander ist, aber ich komm mit dem editor nicht zurecht)

Ich finde das ist ziemlich praktisch. Du empfiehlst mir die AI per C# zu steuern, aber die Lua-Engine muss sie leider steuern können. Meine Idee war ja dem c# zu sagen wie es die AI-Lua steuern soll, aber irgendwas hat scheinbar nicht geklappt. entweder das steuern oder das rausholen der Variablen. Umständlicher gewesen wärs eh.

Wie gesagt vielen Dank für deine Hingabe,

Coordinator
Jun 29, 2012 at 2:50 PM

Ah, jetzt verstehe ich langsam, was du vor hast. :D

Dabei wird dir DynamicLua nicht viel helfen, es vereinfacht nur den Zugriff von C# auf Lua, aber das machst du nur sehr wenig. Falls du das Projekt noch mal aufgreifst kannst du dir ja noch mal LoadString() von Lua ansehen, dann musst du den Umweg über das C# DoString() nicht gehen: http://en.wikipedia.org/wiki/Eval#Lua

Jul 1, 2012 at 9:43 PM

Danke, den Befehl kannte ich noch nicht. Funktioniert schätze ich nicht so gut, da "Eval is Evil" (kurzgesagt).

Wenn usergeschriebene AI in einem ungesicherten Evironment agiert, kann es doch auf die Variablen und so zugreifen. Auch auf die komplizierten C# objekte wie z.B. das o.g. "g". Klingt als könnten Sachen gemacht werden, die sie nicht dürfen.

Deswegen Player als eigenes Lua Objekt (man kann dann auch sehr viele Player benutzen mit den gleichen oder unterschiedlichen Anweisungen, das könnte Konflikte geben bei eval).

Erinnert mich irgendwie an ein simples AntMe (http://www.antme.net/pages/home) (in Lua, nicht in C#). Und der "Engine" könnte die Regeln vorgeben, d.h. wo der Ameisenbau oder Zucker liegen. Der Player darf da auch nicht Zugriff auf alle Variablen haben, vor allem nicht die exakten Positionen von Gegnern und anderen Sachen.

Mann, das Projekt war schon interessant und vielfältig (weil ja die User zeugs machen können)