Lua, metatables, and global variables
I'm working on improving the way we handle Lua scripting for robot players in Bitfighter (http://bitfighter.org).  Currently, each robot gets its own L instance, and we're trying to get them to all share one by swapping out environment tables.

I realize that this method is deprecated in Lua 5.2, but we are currently using lua-vec, which still uses Lua 5.1.  The game is written in C++.

So...

First we create an environment, and call it <name>:


    // Create a table with room for 0 array and 1 non-array elements
    lua_createtable(L, 0, 1);                       // -- table

    // Set the globals table to handle any requests that the script's environment can't
    lua_pushstring(L, "__index");                   // -- table, "__index"
    lua_pushvalue(L, LUA_GLOBALSINDEX);             // -- table "__index", _G, 

    // Set table["__index"] = _G, pops top two items from stack
    lua_settable(L, -3);                            // -- table

    // Store the new table in the retistry for future use
    lua_setfield(L, LUA_REGISTRYINDEX, name);       // -- <<empty stack>>


Later, we load some Lua code, and recall the environment table:

    luaL_loadfile(L, "luascripts.lua");

    lua_getfield(L, LUA_REGISTRYINDEX, name);       // -- function, table 
    lua_setfenv(L, -2);                             // -- function


Then run the loaded code:

    lua_pcall(L, 0, 0, 0);

When the loaded Lua tries to use a basic function, such as print, it fails with the error:

    attempt to call global 'print' (a nil value) 

But, the script *can* do the following:

    __index["print"](12)

So... why can't we access print directly?  What are we missing?  Or is there a fundamentally better way to run multiple scripts in the same Lua instance?

Lua, metatables, and global variables
===

I'm working on improving the way we handle Lua scripting for robot players in Bitfighter (http://bitfighter.org).  Currently, each robot gets its own L instance, and we're trying to get them to all share one by swapping out environment tables.

I realize that this method is deprecated in Lua 5.2, but we are currently using lua-vec, which still uses Lua 5.1.  The game is written in C++.

So...

First we create an environment, and call it <name>:


    // Create a table with room for 0 array and 1 non-array elements
    lua_createtable(L, 0, 1);                       // -- table

    // Set the globals table to handle any requests that the script's environment can't
    lua_pushstring(L, "__index");                   // -- table, "__index"
    lua_pushvalue(L, LUA_GLOBALSINDEX);             // -- table "__index", _G, 

    // Set table["__index"] = _G, pops top two items from stack
    lua_settable(L, -3);                            // -- table

    // Store the new table in the retistry for future use
    lua_setfield(L, LUA_REGISTRYINDEX, name);       // -- <<empty stack>>


Later, we load some Lua code, and recall the environment table:

    luaL_loadfile(L, "luascripts.lua");

    lua_getfield(L, LUA_REGISTRYINDEX, name);       // -- function, table 
    lua_setfenv(L, -2);                             // -- function


Then run the loaded code:

    lua_pcall(L, 0, 0, 0);

When the loaded Lua tries to use a basic function, such as print, it fails with the error:

    attempt to call global 'print' (a nil value) 

But, the script *can* do the following:

    __index["print"](12)

So... why can't we access print directly?  What are we missing?  Or is there a fundamentally better way to run multiple scripts in the same Lua instance?
