lua-users home
lua-l archive

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

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)

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

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!