lua-users home
lua-l archive

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

Loading the levels with a different environment is surely the way to
go to provide simple measures to get rid of level dependent data that
is no longer needed once the level is finished. Nothing sucks more
than data / functions that still roam around at a later point. I can
imagine a lot of bugginess with that way of development, e.g. one
level defines a certain function which the following level does not
handle - calling such a function (belonging to a previous level) ends
up in a pretty undefined state. If everything is global, of course,
the outcome can be that everything works... but well, not really that
nice if you have to load level 3 before being able to load level 4.

However, the convenience that you are asking for, the ability to call
level dependent functions as globals, is however somewhat puzzling me
- because it doesn't seem to me to be a huge convenience at all and
despite the small win, it comes with a huge lack of transparency. The




is carrying much more information that is useful when reading code.
The latter one is indistinguishable from anything else that's being
defined by your application. It looks like an application function,
but it's not. The first one however makes a clear statement: It's a
level's function (If you are really lazy, you could shorten it to
something like "lvl.", "lv." or even "l." - still, it would remain

Whenever someone else is supposed to read / write code, this small
statement will be a blessing. I can perfectly visualize someone
editing the files and regularly saying things like "WTF does this
function come from and why doesn't it exist anymore?" mixed with agony
and pain, trying to find out what should be done to get the
application running.

Usually, it's good to be a lazy programmer, but I wonder if you aren't
asking for too much laziness here...


PS.: you could always set the level's environment table as the
environment table of your application code (after it has been loaded!)
so that you would be able to call level function without any
prefixing, though you might end up writing values to your level
environments within code that is actually supposed to be application
values, so this would just be a swap of prefixing variables.

2010/3/24 Ricky Haggett <>:
> Hey everyone, (and thanks very much to all of you for the help!)
> So, it seems like there a couple of equivalent options. One is using
> setfenv, and then linking in the global stuff I need (as in Enrico's
> solution below or Fabio's code)..
> Another is maybe to put make my level script files modules - i.e. put
> module("level1", package.seeall) at the top of level1.lua and then require
> "level1" after that level is loaded..
> But it seems like, either way, I would then have to access all the
> functions/objects in my level code with level1.a().  This is problematic,
> because I already have a load of places in xml files (which describe the
> level graphically and structurally) where I am just calling a();  .. which I
> don't want to change..
> An ideal solution would be a module-like structure, but where all the
> functions in my level remain global (accessible from the outside without
> doing level.a() ) ..
> Also, as an aside, I'm loading my scripts in C, with
> luaL_loadbuffer+lua_pcall or luaL_dostring. It seems that these functions
> return only an error int - is there no C equivalent for the lua code:
> proc,err = loadstring(script) ?
> Cheers,
> Ricky
> -----Original Message-----
> From:
> [] On Behalf Of Enrico Colombini
> Sent: 24 March 2010 13:08
> To: Lua list
> Subject: Re: Cleaning up specific lua scripts
> Ricky Haggett wrote:
>> How would I go about loading the level script into a table?
> Here is a simple example. This is your level:
> -------------------------
> -- this is "level1.lua"
> function a()
>     b()
> end
> function b()
>     print("Ships: " .. ships)
> end
> ships = 5
> -------------------------
> and this is the level loader:
> -------------------------
> -- this is "loader.lua"
> level = {} -- the table containing a level
> -- read "lev1.lua" into level
> local t = assert(loadfile("lev1.lua")) -- could use loadstring
> setfenv(t, level)
> local r, err = pcall(t) -- execute loaded chunk to define stuff
> r = r or error('error reading level')
> -- add global functions to level (just an example)
> level.print = print
> -- call function a() from outside the level table
> level.a()
> -------------------------
>> Also, if I used setfenv to change the environment, aren't I just moving
> the
>> problem? If I then have to add global functions to this same table, how
> will
>> I differentiate them from the level functions when I need to clean up?
> No need to differentiate, just throw away the level table:
>   level = nil
> If you must access many global values/functions, a trick such as Steve
> suggested would be better than copying them to 'level'. The copy, on the
> other hand, allows fine control over global accesses (there are other,
> possibly better, intermediate solutions).
>> I am thinking maybe my solution is going to be (shallow) copying _G before
>> loading a level, then comparing the copy with _G after the level load. Any
>> objects which don't exist in the copy, but do exist in _G should be the
>> level-specific ones
> Too much work, I prefer lazy solutions :-)
>   Enrico