Jump to content
Flexman

Mission Scripts - chaining a function

Recommended Posts

Supposing you want to implement a quest system where each quest is a lua script.

 

quest_101.lua

quest_102.lua

quest_103.lua

...

 

In each quest script I want to call function "Update()" in a chain. Similar to how TModel LUA scripts are processed.

 

Is it good practice to create a virtual machine for each script? Or use one VM and call the "Update()" function in each script? And if not, what is the correct way to index them and call the same function in each script?

 

 

example source

Local vm:Byte Ptr = luaL_newstate()
luaL_openlibs(vm)
lua_dofile(vm, AbstractPath("abstract::quest_101.lua"))
lua_getfield(vm, LUA_GLOBALSINDEX, "Update")
lua_pushinteger(vm, 0)
lua_call(vm,1,0)

 

 

script "quest_101.lua"

function Update(s)
  -- mission update code here
end

Share this post


Link to post

I haven't enough knowledge about virtual machines. But I concerned about concept of Update() function.

If I made quest management system I would use events subscribers concept to minimize calling count:

  1. We make a pool of active quests.
  2. Some triggers (special little scripts or another quests) add quests to this pool (activate them).
  3. Each script has an Init() function. So we have to call it once we start a level оr load saved game.
  4. Script checks its variables and state and subscribes itself to specific events that it need (changing in inventory, changing health level, killing enemies and so on).
  5. So when those events occur we callback handlers for small amount of quest scripts.
  6. Script in handler makes some actions, changes some variables, changes its' state etc.

Share this post


Link to post

You most likely would want to use Le's Lua state only so that each script can have access to everything in that state and can share data easily between states from inside the Lua script themselves. If each script has it's own state sharing data will be painful and most likely outside of the script itself.

 

As far as how to go about the quest system, there would be a million and 1 ways to do that :(

Share this post


Link to post

OK, thanks for the advice so far. I got it loading how I want and up to 8 scripts hooking an Update() function.

 

I need a little more help here to do the next bit. This is the first time I've tried to work with multiple scripts and need a little guidance and hand-holding from you chaps with experience. A little knowledge is a dangerous thing here, I'm more comfortable using simple data structures and flags rather than VMs to do this sort of thing. So anyway....

 

 

Using LEs single LUA state to load in quest scripts (up to a max of 8). An example of such a script with an init, quit and update....

 

require("Scripts/hooks")
local s = "mission_test.lua"

function MissionInit(id)
  s = "INIT mission_test.lua " .. id
end

function MissionEnd()
  RemoveHook("UpdateWorld",MissionUpdate)
  s = Nil
end

function MissionUpdate()
  print ("mission update called..." .. s)
end

AddHook("UpdateWorld",MissionUpdate)

 

Here's what I'm not to clear on. When I load and run a script I can call a function in it. But only the function in the last loaded script. How can I change the context of a specific script.

 

e.g A call to "MissionEnd()" will always execute the function in the last loaded script. What if I want to call it in the first loaded script?

 

See what I mean by basic questions here? I wish we could hang-out in a virtual class-room to cover this stuff sometimes.

 

 

Note: I have avoided using events to keep things simple for now.

Share this post


Link to post

That's a good question Flexman. I mean all your functions have the same name so really I don't think there would be a way to tell them apart if they were all loaded at the same time. In LE I believe why it works for the entity scripts is because each entity script is more like an instance of a class instead of just functions so they can all be stored in a container to have that instances functions called at any time.

 

You might want to look at maybe doing that instead. That way you would create each instance at startup and store them in some container with maybe a string keyword that represents the quest name. Then you would be free call their functions as you see fit.

Share this post


Link to post

Yes. Use tables (containers in Lua). They are quite powerful.

--create a quest
quest = {}

function quest.Init()
  Print("Init!")
end

function quest.Finish()
 Print("Finish!")
end

function quest.Update()
 Print("Update!")
end

--add quest to global table
all_quests[quest] = quest

 

--call Init() for each quest in global table
for key,value in pairs(all_quests) do
 value.Init()
end

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...