Delayed execution of member functions in Lua/C++ / luabind / Interaction with other lua behavior scripts

StackOverflow https://stackoverflow.com/questions/10968746

  •  13-06-2021
  •  | 
  •  

Question

I have a game with a mainloop - on each loop i call for every NPC in the game ->ProcessAI() to execute any actions. This is a server so the call to ProcessAI is not executed on every frame like on a client game! Its also singlethreaded.

Now i wanted to extend the C++ codebase with lua using luabind (maybe, even with boost overhead). So i expose some functions of my NPC class to LUA.

I wanted to create actor scripts for example - boss battles which have more sophisticated behaviour - whenever in my c++ ProcessAI function an event happens - i would delegate this to the corresponding lua script for the specific NPC.

i imagined in my boss.lua script i would have something like this

 function OnEngageCombat(NPC)
 NPC:say ("Some taunts...")
 ScheduleEvent(CastEvilSpell,/*time*/2000,/*numExecutions*/1,)
 end

 function CastEvilSpell(NPC)
 NPC:CastSpell("someSpell")
 end

However - i have no idea how to do this - i gather ScheduleEvent should be some C++ function exported to Lua - but what would be the best approach to keep the object reference of the NPC (boss) with this and call a function in that script about 2 seconds later ?

Furthmore along with this delayed execution - i want that NPCs can interact with each other - my current idea is to have an actor behavior script for each special NPC.

Now what i imagined is to initiate a conversation between two NPCs e.g.

function DoGossip(NPC)
// check if NPC1 is close to NPC2
if NPC:DistanceToNpc("SomeGuy") < 10 then
 StartConversation1()
end

function StartConversation1(NPC)
NPC:Say("Hello ...")
// wait a moment now trigger NPC2 to reply
????
end

Basically - how do i call a function from lua scriptA which exists in lua scriptB which is the behavior script for NPC2. What would be a good design?

Thanks

Was it helpful?

Solution

If you use LuaBind, you can set a global scriptable object that refers to a wrapper class around your game engine that you expose to your script.

So, whenever you set up your lua engine, you can register a global you want all scripts to have access to, like this in your C++ code:

luabind::globals(m_pLuaState)["Game"] = m_pGameWrapperClass;

Then, in your script, you could simply refer to the Game object to get at game specific functionality, like this:

Game:ScheduleEvent(...)

Your C++ game wrapper class would just implement a ScheduleEvent function that you'd bind with LuaBind. You could add/register as many game-y specific functions as you'd need on that object.

To lead into your question 2, you could simply register a function on your Game class called FindNPC(), that takes a string argument or id or something that would look up an npc in your engine, and return a reference to it. You'd probably want to write a wrapper class around the npc object that exposes npc-y functionality just like you would do with your Game class, and FindNPC() would return userdata that represents an NPC, and exposes whatever functionality that is necessary to use it, or to make it do stuff in the Game itself.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top