Sign in to follow this  
coderx75

Lua: Running multiple scripts?

Recommended Posts

coderx75    435
I've recently gotten Lua up and running for my project but I'm having trouble figuring out how to handle multiple scripts (non-concurrent) and multiple instances of the same script. The Lua manual isn't very clear (reference only) and what I've found online deals only deals with more basic issues. I'm planning on having a large number of scripted game objects loaded simultaneously, however, there are only a few (dozen or so) object types loaded at any given time. So, each object has a type and each type a script in which each object runs during its update. It must be STRICTLY forbidden for any two objects to access eachother's variables (environment) even if they are the same type (and therefore using the same script). In a perfect world, I'd be able to have all objects of a type share the same code but have their own variables. How can I achieve this? I was thinking of using a seperate state for each type but then objects of the same type would see eachother's data. Having a seperate state for each and every object seems like EXTREME overkill. I'm thinking that each type can have a state but each instance a seperate environment. Would that be possible and, if so, how? Any ideas appreciated. Thanks!

Share this post


Link to post
Share on other sites
bobofjoe    322
The idea is that you should use tables to create what is like objects in lua, and pass them around to your scripts.


You can pass each object an instance of a lua table, and define operations on that table.
For instance:


--Lua Script
basicEnemyBehavior =
{
--This returns an instance of the table, with the update function.
new = function( spd )
--Create the table that we want to use.
result = { speed = spd };

--Make it so that we can 'see' the functions in basicEnemyBehavior
setmetatable(result, {__index = basicEnemyBehavior});

--Return the table, with the operations defined.
return result;
end

--This is called whenever the enemy needs to do some logic.
--The self parameter is like the 'this' pointer in C++
--The enemy parameter is just a conceptual enemy thats passed from C++

onUpdate = function(self, enemy)
--We assume that we pass the correct table to this function
enemy:moveToPlayer(self.speed);
end
}

--Add two enemies, with the same update function, but different speeds.
addEnemy(basicEnemyBehavior.new(2));
addEnemy(basicEnemyBehavior.new(4));






slowEnemy.update(); //Calls onUpdate in lua, which moves itself and only itself.
fastEnemy.update(); //Calls onUpdate in lua, using the same lua script as the one above, but with different data.


Share this post


Link to post
Share on other sites
coderx75    435
That helps! Does the Lua interpreter keep a copy of the functions within each instantiated basicEnemyBehavior or are the functions defined within stored seperately and shared by all instances? This is important since I want to keep object as light as possible.

I can't allow scripts to create new objects directly (must be done from within the application) and I also need each script to be completely encapsulated from eachother. So, I figure I can still use a new state for each object type and have the object defined similarly but have a standardized name for the object definition (ObjectType = { --etc. }). Now, I can either have procedures defined seperately (function OnUpdate ()) or, if functions are NOT stored with each instance, define it within the object table (OnUpdate = function ()) which would be preferable. I've got some work to do! =)

Share this post


Link to post
Share on other sites
ddn3    1610
This seems pertinent to what your after.

http://lua-users.org/lists/lua-l/2003-10/msg00268.html

I believe creating a new lua thread and assigning a unique global table for each thread will effectively isolate the objects, while still allowing you to run the same basic script.

This is essentially running a script multiple times using the same VM. These are not true preemptive threads, rather cooperative threads, so you'll be responsible for yielding them and continuing them as u see fit.

Personally I don't like this method of scripting, but if it's what you need, it's possible.

Good Luck!

-ddn

Share this post


Link to post
Share on other sites
BornToCode    1185
I ran into a similar problem. But i used AngelScript. The way i solve the issue is that i have a system in my engine that parse each script at runtime after it loads them into memory and extract all the global variables which would be shared between objects that reference the same script and then actually create those variables on the objects themselves. So whenever you run a script the object updates all the global variables for the script it is about to run and when the script is done executing it update the variables back on the object. That way variables are not shared between objects that are using the same script.

Share this post


Link to post
Share on other sites
NovaBlack    166
Quote:
Original post by BornToCode
I ran into a similar problem. But i used AngelScript. The way i solve the issue is that i have a system in my engine that parse each script at runtime after it loads them into memory and extract all the global variables which would be shared between objects that reference the same script and then actually create those variables on the objects themselves. So whenever you run a script the object updates all the global variables for the script it is about to run and when the script is done executing it update the variables back on the object. That way variables are not shared between objects that are using the same script.



hmm now that sounds really interesting and what im after!!

for example i have a CUsableObject class. Any instance of this class has a pointer to one of several CUsableObjectTemplate instances, each of which contains unique stuff (like a name e.g. "OBJ_USABLE_DOOR", mesh "Door.x" scriptName "DOOR_OPEN_CLOSE.lua").

This gives me a really simple flexible way of creating new 'usable' objects (by just defining a new template with a different mesh/script etc).

The problem i had was trying to keep CUsableObject very generic. The problem is that lets say i have a door template and a say.. a computerPanel template.

I need to record for the door say.. several bools, e.g. open (true/false), currentlyOpening(true/false), currentlyClosing(true/false). However these completely dont apply to a 'computer panel' object. So the problem is i dont want to just jam boolean member variables into the CUsableObject class.

Obviously, the script for a door can have global vars for the members mentioned above, and the computerPanel could have equally appropriate ones within its script.

The problem is, i need to 'save' these variables on a CUsableObjectInstance between script calls! (i mean how is one instance of a door going to remember if it was say currentlyOpening or currentlyClosing when the script executes next frame...

Can you explain any more about your system to create variables on the instances so that they can 'save' unique vars between calls?


I was wondering if i coud do this with a luabind::object...
Since it simply references a table containing all script 'globals'.. could i tell an instance to call a script, and then fill a luabind::object with the current globals, then next frame, set the globals within a script to the values stored within this 'savedglobals' object, then execute as normal?

Share this post


Link to post
Share on other sites

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