Jump to content

Mission Scripts - chaining a function


Flexman
 Share

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

6600 2.4G / GTX 460 280.26 / 4GB Windows 7

Author: GROME Terrain Modeling for Unity, UDK, Ogre3D from PackT

Tricubic Studios Ltd. ~ Combat Helo

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :(

Link to comment
Share on other sites

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.

6600 2.4G / GTX 460 280.26 / 4GB Windows 7

Author: GROME Terrain Modeling for Unity, UDK, Ogre3D from PackT

Tricubic Studios Ltd. ~ Combat Helo

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

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.

 Share

×
×
  • Create New...