Sign in to follow this  

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

This topic is 2842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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 inst
end

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;
end

function class:TestFunc(prefix)
self.count = self.count + 1;
print(prefix.." count is "..self.count);
end

return 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/SlimeLogic2
local 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");
end

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

Share this post


Link to post
Share on other sites

This topic is 2842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this