Lua: Running multiple scripts?

Started by
4 comments, last by NovaBlack 15 years, 4 months ago
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!
Quit screwin' around! - Brock Samson
Advertisement
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 ScriptbasicEnemyBehavior = {    --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.

[size=1]Visit my website, rawrrawr.com

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! =)
Quit screwin' around! - Brock Samson
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
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.
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?

This topic is closed to new replies.

Advertisement