[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: RE: multiple lua states
- From: "Joel Pritchett" <jpritchett@...>
- Date: Mon, 3 Nov 2003 09:55:34 -0800
We're using lua in our game and did the following:
We have a single master lua state that stores all our common and library
functions as well as any constants in its global table.
Each object runs a thread (lua_newthread) spun from this state. Each
thread has a new global table and '__index' operator added to its
metatable. In the new '__index' operator we first search the threads new
global table and if we cannot find what we are looking for we look for
it in the master states global table. Also in each threads global table
we add a 'this' pointer and any other object specific data. All the
explicitly named objects live in the global state table and when
referred to are resolved properly.
As for your solutions: I can't see any way to fix #1, not if you stick
to name mangling.
We found the adding of named objects extremely memory intensive, to the
order of 250 bytes per just for a pointer associated with a name. So we
pulled them out in favor of something like the following:
'Actor.GetNamed( "WorldNode1", "Barrel1" )' which fixed node (or scene)
specific naming collisions and an ass load of memory. We had several
hundred objects per level being added though.
If you want to keep the named objects I'd have to ask for more info
about how you need to use a global polling script in relation to the
local thread. I'm sure there is a good solution though using metatables.
[mailto:email@example.com] On Behalf Of Brett Bibby
Sent: Friday, October 31, 2003 8:15 PM
To: Lua List
Subject: multiple lua states
We're trying to decide whether to go with multiple lua states or a
state for our game. Any advice appreciated. Sorry for the length of
post but to give a good answer, understanding our usage is important.
Our game editor allow you to define game objects using GUI property
which get compiled into lua tables (the level designer doesn't see or
know about the lua tables). Our game editor does this by internally
assigning an identifier that is a number such that it starts at
"A". On export, we generate the object tables using this number but
converted to string, and starting with "A" makes sure we have a valid
beginning with A-F followed by a bunch of numbers.
So now we have a bunch of lua tables holding the properties of a game
like health, hit points, whatever. We then have an event system that
basically creates a C object that holds the name of a handler script for
given object. When the event fires we call the lua script, converting
internal number back into a string and pass it to lua so the lua script
sees it as a table access. In other words, when a script gets called it
gets passed a variable which contains the numeric identifier, a "self"
you will. In the script I can then do a function like:
LightColorSet(selfId, 255, 255, 255)
and the engine will look up the object back into it's scenegraph and all
well. We additionally need to sometimes refer to other objects
so in our tools when you create the game object there is a checkbox that
says "Scriptable" and a label name then becomes editable. When this
we then generate a lua variable and set it equal to the table name we
generated. So an object labeled as "treasure" known as "B245"
that is scriptable would then emit a lua variable below the table
declaration like treasure = B245 so that any function requiring an
identifier can use the variable instead. Very nice system so far.
The tricky part is that we can have multiple scenes running at the same
and this leads to the problem. So, if I have a tree swaying in the
known internally as A123, it has a table called A123. If this tree
in more than one scene though, I would have multiple tables with the
name which is no good. The solutions are:
1. Use a single, global lua state. Prefix the id (e.g. A123) with a
id so it becomes something like A1A123 where the first A1 is the scene
concatenated with the object id. I can then run the same script on the
"same" object that appears in multiple scenes and they each have their
private table. The tree A123 in scene A1 is A1A123 and in scene A2 is
A2A123 and a single script can work on all swaying trees no matter how
scenes it's in. The problem with this is that then my label is broken!
will have two tables, A1A123 and A2A123 but one label called "tree"
will be equal to the last uploaded one, either tree=A1A123 or
So I lost explicit scriptability of objects. Any ideas how I can
2. Use multiple lua states. In this scheme I still prefix the object
identifiers with a scene identifier, and everything works as before, but
my label will also work because the variables of the same name are in
different states so there is no namespace collision. The problem with
approach is that I waste memory on functions that are essentially
in each state and, more importantly, I don't know how to share data
scenes. For instance how can Ihave global player health, score, etc.?
I can't think of any solution to #1, but for the global variable problem
#2 I could create a global scene, mark it as such, and include a
auotmatically in all scenes with the global variable scene id, something
like global_scene=A0. Then I would write a function to make an object
that concatenates the global scene id with an object id to make a final
correct id for the global scene. Then my engine would need to call into
that global scene on behalf of the calling script so I change lua states
Am I missing something? Is there an easy way to share _some_, but not
variables amoung different lua states? Any way to solve #1?
Sorry for the long post!