How can a script retain its values through different script loading in Lua?

Started by
1 comment, last by triqer 14 years, 1 month ago
My current problem is that I have several enemies share the same A.I. script, and one other object that does something different. The function in the script is called AILogic. I want these enemies to move independently, but this is proving to be an issue. Here is what I've tried. 1) Calling dofile in the enemy's constructor, and then calling its script function in its Update function which happens in every game loop. The problem with this is that Lua just uses the script of the last enemy constructed, so all of the enemies are running the same script in the Update function. Thus, the object I described above that doesn't use the same script for it's A.I. is using the other enemies' script. 2) Calling dofile in the Update function, and then calling its script function immediately after. The problem with this is that dofile is called in every object's update function, so after the AILogic function runs and data for that script is updated, the whole thing just gets reset when dofile is called again for another enemy. My biggest question here is whether there is some way to retain the values in the script, even when I switch to running a different one. I've read about function environments in Lua, but I'm not quite sure how to implement them correctly. Is this the right direction? Any advice is appreciated, thanks. I've also considered creating a separate place to store that data rather than doing it in the Lua script. Here is some sample code to show what I am trying to accomplish (count's value has to be retained separately for each AI in between Update calls).

-- Slime's Script

local count = 0;

function AILogic( Slime )
  --Make the slime move in circles(err a square)
  if count < 4 then
    Slime:MoveDir( 0 );
  elseif count < 8 then
    Slime:MoveDir( 2 );
  elseif count < 12 then
    Slime:MoveDir( 1 );
  elseif count < 16 then
    Slime:MoveDir( 3 );
  else
    count = 0;
  end
  count = count + 1;
end
I also posted my question at http://stackoverflow.com/questions/2353431/how-can-a-script-retain-its-values-through-different-script-loading-in-lua.
Advertisement
This is a common question, the simplest thing to do is to use alittle object oriented programming and create a instance of a class which holds the local instance state.

For example a simple class (say contained within a file called Scripts/SlimeLogic)

local class = {}function class:new() -- The constructor	local inst = {};	inst.count=0;	setmetatable(inst, {__index = class});	--setup metatable	return instend function class:AILogic( Slime )  --Make the slime move in circles(err a square)  if self.count < 4 then    Slime:MoveDir( 0 );  elseif self.count < 8 then    Slime:MoveDir( 2 );  elseif self.count < 12 then    Slime:MoveDir( 1 );  elseif self.count < 16 then    Slime:MoveDir( 3 );  else    self.count = 0;  end  self.count = self.count + 1;endfunction class:TestFunc(prefix)  self.count = self.count + 1;	print(prefix.." count is "..self.count);endreturn class;


this file wholly contains the implementation of just one class, note the class table itself is local (so inaccessible to external code and also avoid namespace issues) but it does return its interface at the very last line (see return class;)

This is will be apparent why in the next sample code :

--store away the class interface returned from Scripts/SlimeLogic2local class = require("Scripts/SlimeLogic2")--we use that interface to create instances of the class (t,t2)local t  = class.new();local t2 = class.new();--debug print to see if everything is ok (all should be tables)print(tostring(class));print(tostring(t));print(tostring(t2));--now we can test that each instance does indeed store its own local data...for i=0,10 do	t:TestFunc("object 1");endt2:TestFunc("object 2");


So afew things to consider, this is using the OOP Lua calling convention :, which like C++ implicitly passes a self parameter as the first argument into a function call, thats why the we use self.count to access the count.

The reason for having the class return its interface is to avoid namespace conflicts with multiple scripts using the same naming convention, which might not be an issue for u.

Good Luck!

-ddn
Thanks!

This topic is closed to new replies.

Advertisement