lua-users home
lua-l archive

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


I am developing a game using C++ where the logic of different entities
are controlled by Lua scripts. So, I'd have a collection of scripts
that each have a standard set of functions like "nextAction", as well
as any internal state (most likely in the form of global variables)
the C++ side doesn't and shouldn't know about.

Since I don't want my scripts overwriting each other, some form of
sandboxing is in order. The behaviour I want can be achieved by having
multiple lua_State objects for each script instance; i.e. each
script-controlled entity has its own lua_State. I heard that this was
wasteful though, so I've been looking at threads and environment
tables.

So far I've been trying to use lua threads. I start off by creating my
main lua_State. For every script I load, I create a new thread:

-----------------------------------------------------------------------
lua_State *scriptThread = lua_newthread(mainLuaState);

lua_newtable(scriptThread);
lua_replace(scriptThread, LUA_GLOBALSINDEX );
//lua_setfenv(scriptThread, 1); // Doesn't seem to work

luaL_openlibs(scriptThread); // I could have loaded this once in the
                             // main Lua state and then manipulated the
                             // current thread's metatable, but I want
                             // to illustrate a bug here later.

if (luaL_dofile(scriptThread, path.c_str()))
{
    throw runtime_error("Could not load file '" + path + "': "
      + lua_tostring(scriptThread, -1));
}
-----------------------------------------------------------------------

Whenever I need to call a function for a particular script instance, I
access its thread. This seems to work for running general script
logic. However, including libraries seems to only work for the first
script I load.

The call to luaL_openlibs only works for the first script I load. If I
have print() in two scripts and I run those scripts, only the first
script I loaded and ran will recognize the print() while the second
script will think it's a nil value.

Similarly, require doesn't work for scripts that weren't loaded first.
I made two scripts that call a function inside a common Lua file (i.e.
they both require() this file). The first script to be loaded is able
to call this function, while the second thinks the function is a nil
value.