私は、ロボットプレイヤーのLuaスクリプトを扱う方法を改善するために、Bitfighterに取り組んでいます。現在、各ロボットは独自のLインスタンスを取得しており、環境テーブルを交換することにより、それらをすべて共有するようにしています。ボットはまったく別のスクリプトかもしれないことに注意してください。ルアとメタテーブルとグローバル変数
この方法はLua 5.2では非推奨ですが、現在はLua 5.1を使用しているlua-vecを現在使用しています。このゲームはC++で書かれています。
そう...
まず私たちは環境を作成し、それを呼び出す:
// Create a table with room for 0 array and 1 non-array elements
lua_createtable(L, 0, 1); // -- tab
// Set the globals table to handle any requests that the
// script's environment can't
lua_pushstring(L, "__index"); // -- tab, "__index"
lua_pushvalue(L, LUA_GLOBALSINDEX); // -- tab, "__index", _G
// Set table["__index"] = _G, pops top two items from stack
lua_settable(L, -3); // -- tab
// Store the new table in the retistry for future use
lua_setfield(L, LUA_REGISTRYINDEX, name); // -- <<empty stack>>
その後、我々はいくつかのLuaのコードをロードし、環境テーブルをリコール:
luaL_loadfile(L, "luascripts.lua");
lua_getfield(L, LUA_REGISTRYINDEX, name); // -- function, table
lua_setfenv(L, -2); // -- function
次に、ロードされたコードを実行します。
lua_pcall(L, 0, 0, 0);
ロードLuaは、このような印刷など、基本的な機能を使用しようとすると、それはエラーで失敗します。
attempt to call global 'print' (a nil value)
しかし、スクリプトは次の操作を実行できます。
だから、__index["print"](12)
..なぜ印刷物に直接アクセスできないのですか?何が足りないの?あるいは、同じLuaインスタンスで複数のスクリプトを実行する根本的に良い方法はありますか?
ありがとうございました! "別の方法は、各スクリプトの環境テーブルを作成することです..."これは私がしようとしているものですが、私は各スクリプトにグローバルテーブルのコピーを提供することは考えていませんでした。あなたの例から、これがスクリプトのセキュリティと分離を改善する理由がわかりますが、これを実装する方法がわかりませんし、かなりの研究にもかかわらず実装の良い例は見つかりませんでした。 – Watusimoto
@魂本:実際はかなりシンプルです。ホワイトリストに登録された各要素をグローバルテーブルから環境テーブルにコピーするだけです(変更可能な要素になると、参照だけでなく要素も正しくコピーされます)。私は数日後に戻っていくつかの適切な例を挙げます。 (私に忘れないで、私に思い出させてください!) – Mankarse
ありがとうございました。これは、私のグローバルテーブルが既にスクリプトにアクセスできるようにする関数と値に限定されているので、比較的単純であるはずです。だから、卸売コピー操作になるでしょう。 – Watusimoto