lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.

Joel

-----Original Message-----
From: lua-bounces@bazar2.conectiva.com.br
[mailto:lua-bounces@bazar2.conectiva.com.br] On Behalf Of Brett Bibby
Sent: Friday, October 31, 2003 8:15 PM
To: Lua List
Subject: multiple lua states

Hello,
We're trying to decide whether to go with multiple lua states or a
single
state for our game.  Any advice appreciated.  Sorry for the length of
the
post but to give a good answer, understanding our usage is important.

Our game editor allow you to define game objects using GUI property
sheets
which get compiled into lua tables (the level designer doesn't see or
even
know about the lua tables).  Our game editor does this by internally
assigning an identifier that is a number such that it starts at
hexidecimal
"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
string
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
object
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
a
given object.  When the event fires we call the lua script, converting
the
internal number back into a string and pass it to lua so the lua script
just
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"
if
you will.  In the script I can then do a function like:

function UpdateLight(selfId)
     LightColorSet(selfId, 255, 255, 255)
end

and the engine will look up the object back into it's scenegraph and all
is
well.  We additionally need to sometimes refer to other objects
explicitly,
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
happens
we then generate a lua variable and set it equal to the table name we
also
generated.  So an object labeled as "treasure" known as "B245"
internally
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
time
and this leads to the problem.  So, if I have a tree swaying in the
wind,
known internally as A123, it has a table called A123.  If this tree
appears
in more than one scene though, I would have multiple tables with the
same
name which is no good.  The solutions are:

1.  Use a single, global lua state.  Prefix the id (e.g. A123) with a
scene
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
own
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
many
scenes it's in.  The problem with this is that then my label is broken!
I
will have two tables, A1A123 and A2A123 but one label called "tree"
which
will be equal to the last uploaded one, either tree=A1A123 or
tree=A2A123.
So I lost explicit scriptability of objects.  Any ideas how I can
resolve
this?

2.  Use multiple lua states.  In this scheme I still prefix the object
identifiers with a scene identifier, and everything works as before, but
now
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
this
approach is that I waste memory on functions that are essentially
identical
in each state and, more importantly, I don't know how to share data
amoung
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
in
#2 I could create a global scene, mark it as such, and include a
variable
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
id
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
all,
variables amoung different lua states?  Any way to solve #1?

Sorry for the long post!
Brett