0

我正在为多人游戏开发服务器,我想为每个玩家提供自己的 Lua 线程,我想填充一些独特的全局变量,例如玩家的姓名和 ID。基本上,我希望能够从主机应用程序设置线程局部变量,而无需在我正在编写的实际脚本中添加任何额外的代码,然后我可以在播放会话期间使用它,只要我调用一个函数。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 中设置函数环境的理解是它会全局更改它,这在我的情况下不起作用。

4

2 回答 2

0

您是否使用现有的游戏引擎?如果是这样,可能值得使用现有的库。例如,如果使用LÖVE2D,您可以使用类似thisthis的东西。

您可以使用setfenv_ENV(取决于 Lua 版本)创建单独的环境,并可选择在其中使用协程

于 2015-08-29T14:16:44.887 回答
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 状态,每个拥有自己线程的玩家都可以拥有自己的变量。

于 2015-08-31T00:56:40.000 回答