Lua<-->AI communications [in Spring 0.83+]

Lua<-->AI communications [in Spring 0.83+]

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

Post Reply
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Lua<-->AI communications [in Spring 0.83+]

Post by Kloot »

Listen very carefully, I shall say this only once.

For Spring 0.83+, I have expanded the API to allow full two-way*** interaction between native (C{++}, Java, Python, ...) AI's and Lua gadgets and widgets. The tools at your disposal are:

Code: Select all

    -- Lua callins (one new, one old, UNSYNCED LUA ONLY)
    -- (RecvSkirmishAIMessage was formerly known as AICallIn)
    gadget:RecvSkirmishAIMessage(number aiTeam, string aiMessage) --> string
    widget:RecvSkirmishAIMessage(number aiTeam, string aiMessage) --> string

    -- Lua callouts (new, UNSYNCED LUA ONLY)
    Spring.SendSkirmishAIMessage(number aiTeam, string aiMessage) -->
        boolean, {[1] = string, [2] = string, ...}

    // legacy C++ callins (new)
    void IGlobalAI::RecvLuaMessage(const char* inData, const char** outData);

    // legacy C++ callouts (one new, one old)
    const char* IAICallback::CallLuaRules(const char* inData, int inSize, int* outSize);
    const char* IAICallback::CallLuaUI(const char* inData, int inSize, int* outSize);
This example is for AI's using the legacy C++ interface (figuring out how to translate it to your wrapper of choice is left as an exercise):

Code: Select all

-- some LuaUI widget
function widget:RecvSkirmishAIMessage(aiTeam, aiMessage)
    func = loadstring(aiMessage)
    if (func ~= nil) then
        func()
    end
    return ""
end

-- some LuaRules gadget
if (gadgetHandler:IsSyncedCode()) then
    function gadget:Explosion(weaponDefID, px, py, pz, ownerID)
        SendToUnsynced("Explosion", px, py, pz)
    end
else
    local function HandleExplosion(...)
        local x = arg[3]
        local y = arg[4]
        local z = arg[5]
        local aiTeam = 1
        local aiMessage = "t = {" ..
            "msgID=\"Explosion\"" .. ", " ..
            "x=" .. x .. ", " ..
            "y=" .. y .. ", " ..
            "z=" .. z .. ", " ..
        "}"
        Spring.SendSkirmishAIMessage(aiTeam, aiMessage)
    end

    local eventMap = {Explosion = HandleExplosion}

    function gadget:RecvFromSynced(...)
        local eventName = arg[2]

        if (eventMap[eventName] ~= nil) then
            eventMap[eventName](...)
        end
    end
end



// AI code
void AI::UnitDestroyed(int unitID, int attackerID) {
    static char buffer[1024];

    const float3& unitPos = callback->GetUnitPosition(unitID);
    const char* luaString = "Spring.MarkerAddPoint(%f, %f, %f, \"AI: unit %d was here\")";

    snprintf(buffer, 1024, luaString, pos.x, pos.y, pos.z, unitID);
    callback->CallLuaUI(buffer, -1, NULL);
}

void AI::RecvLuaMessage(const char* inData, const char** outData) {
	const LuaTable& table = LuaParser::Parse(inData);
	if (table.GetValue<std::string>("msgID") == "Explosion") {
	    const float x = table.GetValue<float>("x");
	    const float y = table.GetValue<float>("y");
	    const float z = table.GetValue<float>("z");
	    intelHandler->Explosion(x, y, z);
	}
}


*** WARNING: http://springrts.com/phpbb/viewtopic.ph ... 92#p546792
Last edited by Kloot on 27 Aug 2013, 13:28, edited 8 times in total.
cain
AI Developer
Posts: 124
Joined: 09 Aug 2005, 10:04

Re: Lua<-->AI communications

Post by cain »

wow, passing&parsing lua strings, seriously?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Re: Lua<-->AI communications

Post by AF »

If you look at the AI gadget standardisation thread you'll see why his example uses lua strings =p

Kloot, thanks for this, what are the performance overheads on this API?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Lua<-->AI communications

Post by Kloot »

The cost of paSsing a message from either end to the other is the same as that of any regular callin or callout, plus the time needed to cross the border from the engine into or out of Lua land (which mostly gets taken up by stack management).

The cost of paRsing a message is much more significant (Lua's loadstring _compiles_ code on the fly, and on the AI side your LuaParser implementation will probably use luaL_loadstring which just runs the same algorithms). That means you need to batch and keep crosstalk to a minimum.
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Lua<-->AI communications

Post by knorke »

Kloot wrote:Listen very carefully, I shall say this only once.
Would you (or anybody else who is familiar with AI stuff) mind putting that into the wiki?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Re: Lua<-->AI communications

Post by AF »

Kloot wrote:The cost of paRsing a message is much more significant (Lua's loadstring _compiles_ code on the fly, and on the AI side your LuaParser implementation will probably use luaL_loadstring which just runs the same algorithms). That means you need to batch and keep crosstalk to a minimum.
Would a different data format such as json or xml be faster in this regard due to the lack of compilation? Or would it be exchanging one overhead for another?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Lua<-->AI communications [in Spring 0.83+]

Post by Kloot »

It depends on what a JSON parser does under the hood to turn strings back into JavaScript objects (a really bad implementation could just call eval, which is the JS interpreter equivalent of Lua's loadstring), but the process is probably more lightweight than for Lua. The JSON object representation is also fairly close to how a Lua table would look in string form (unlike any XML scheme), so that simplifies writing** the Lua-side (de)serialization code.

** there already are bidirectional (encoding&decoding) JSON parser modules available for Lua, see eg. http://json.luaforge.net
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Re: Lua<-->AI communications [in Spring 0.83+]

Post by AF »

I mean from a C++ perspective. Java should be able to load json data quite efficiently in comparison to anything C/C++ or lua could muster anyway.

In principle, since the json or xml parser needs only to pick apart the datas structure and assign a dom or OO representation in the native language, is this always going to have an advantage performance wise over lua strings pushed through lua into bytecode and out back through the lua API?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Lua<-->AI communications [in Spring 0.83+]

Post by Kloot »

In most cases yes, because that (pulling the string apart into some internal tree representation) is just a basic form of lexing & parsing, which a compiler also has to do _plus a lot more_ to produce (byte / machine)code.

Reading any kind of XML format still involves copious amounts of string operations though which are never exactly fast, so avoid that.
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6241
Joined: 29 Apr 2005, 01:14

Re: Lua<-->AI communications

Post by FLOZi »

knorke wrote:
Kloot wrote:Listen very carefully, I shall say this only once.
Would you (or anybody else who is familiar with AI stuff) mind putting that into the wiki?
In the process of updating the wiki with a whole heap of stuff since 83, kloot, where is the best place to put SendSkirmishAIMessage?

http://springrts.com/wiki/Lua_UnsyncedCtrl#SendMessage

http://springrts.com/wiki/Lua_UnsyncedC ... LuaMessage

http://springrts.com/wiki/Lua_UnsyncedCtrl#Misc

?
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Lua<-->AI communications [in Spring 0.83+]

Post by jK »

new section after SendLuaMessage
Post Reply

Return to “AI”