lua-users home
lua-l archive

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


This isn't a direct answer to your question but one thing that you might
consider before you make your final choice is whether or not you expect
garbage collection to be a problem.

In a real-time game, Lua's garbage collection can be a real problem.
Sooner or later you're going to have to clean things up and garbage
collecting a large state can take long enough that it can have a real
negative effect on your frame rate.  I've found that breaking things up
into multiple Lua states can greatly reduce the problem because then you
can trigger garbage collection on just one of them per frame and even
out the hit.  Of course that assumes that you have some logical way to
break things up.  We use Lua in our UI engine (among other things) so
it's pretty easy for us to break our UI scenes up into units that each
have their own Lua state.  

(Now if only we could get true incremental GC then this wouldn't be an
issue.)

Steve

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