我正在为多人游戏开发一个服务器,我希望给每个玩家自己的Lua线程,我想填充一些独特的全局游戏,例如:玩家的名字和身份证明。基本上,我希望能够从主机应用程序设置线程局部变量,而不是我写的实际脚本中的任何其他代码,然后我可以在播放期间使用会话,每当我调用一个函数。这可能与Lua有关吗?
// Example of how it naturally doesn't work
var L = Lua.LuaLNewState();
Lua.LuaRegister(L, "print", WriteLine);
dostring(L, "print('hello, world')", null);
var x = Lua.LuaNewThread(L);
Lua.LuaPushLiteral(x, "charId");
Lua.LuaPushNumber(x, 123);
Lua.LuaRawSet(x, Lua.LUA_GLOBALSINDEX);
dostring(x, "print('x1 '..charId)", null); // call to a function that uses charId
var y = Lua.LuaNewThread(L);
Lua.LuaPushLiteral(y, "charId");
Lua.LuaPushNumber(y, 456);
Lua.LuaRawSet(y, Lua.LUA_GLOBALSINDEX);
dostring(y, "print('y1 '..charId)", null); // call to a function that uses charId
dostring(x, "print('x2 '..charId)", null); // I want this to still be 123
更新:我的应用程序是多线程的,多个玩家可以同时运行脚本。我对在Lua中设置函数环境的理解是它在全局范围内改变它,在我的情况下不会起作用。
答案 0 :(得分:0)
您使用的是现有的游戏引擎吗?如果是这样,可能值得使用现有的库。例如,如果使用LÖVE2D,您可以使用this或this之类的内容。
您可以使用setfenv或_ENV创建单独的环境(取决于Lua版本),也可以选择使用coroutines。
答案 1 :(得分:0)
我找到了另一种方法来实现这一点,对我来说感觉不那么“hacky”。 Lua有一个名为LUAI_EXTRASPACE
的常量,用于在Lua状态前加上指定的字节数。我现在正在使用我自己编译的普通C Lua库,在那里我将该常量更改为4,在实际的Lua状态结构前面创建空间,以保存对应用程序中对象的引用,我可以查询每当我在一个函数中需要它时。
存储
var NL = Lua.lua_newthread(L);
unsafe
{
var ptr = (int*)NL.ToPointer();
ptr -= 8;
*ptr = index;
}
return NL;
提取
var index = 0;
unsafe
{
var ptr = (int*)L.ToPointer();
ptr -= 4;
index = *ptr;
}
var obj = objects[index];
虽然这不允许我自由地推送变量,但我可以轻松编写使用存储int的函数,从数组中获取对象,并将值传递给Lua。或者,如果您只需要几个特定变量,您也可以腾出更多空间。
由于这是每个Lua状态,每个拥有自己线程的玩家都可以拥有自己的变量。