バックグラウンド
Bitfighter というゲームで Watusimoto と仕事をしています。LuaWrapper のバリエーションを使用して、c++ オブジェクトをゲーム内の Lua オブジェクトに接続します。また、 lua-vecと呼ばれる Lua のバリエーションを使用して、ベクトル操作を高速化します。
私たちはしばらくの間、解決できなかったバグを解決するために取り組んできました。メタテーブルの破損を示唆するランダムなクラッシュが発生します。この問題に関する Watusimoto の投稿については、こちらを参照してください。メタテーブルが破損しているためかどうかはわかりませんが、ここで質問したい奇妙な動作が見られました。
問題の顕在化
例として、オブジェクトを作成し、次のようにレベルに追加します。
t = TextItem.new()
t:setText("hello")
levelgen:addItem(t)
ただし、ゲームがクラッシュすることがあります (常にではありません)。エラーあり:
attempt to call missing or unknown method 'addItem' (a nil value)
上記の Watusimoto の投稿への回答で与えられた提案を使用して、最後の行を次のように変更しました。
local ok, res = pcall(function() levelgen:addItem(t) end)
if not ok then
local s = "Invalid levelgen value: "..tostring(levelgen).." "..type(levelgen).."\n"
for k, v in pairs(getmetatable(levelgen)) do
s = s.."meta "..tostring(k).." "..tostring(v).."\n"
end
error(res..s)
end
これは、そこlevelgen
からメソッドを間違って呼び出した場合に、if 何かのメタテーブルを出力します。
ただし、これはクレイジーです。失敗してメタテーブルを出力すると、メタテーブルはまさにaddItem
(正しい呼び出しとすべてで)あるべき姿になります。levelgen
スクリプトの読み込み時にメタテーブルを出力し、pcall
上記の使用に失敗した場合、それらは同一であり、ユーザーデータへのすべての呼び出しとポインターは同じである必要があります。
メタテーブル forlevelgen
がランダムに自然に消えていくようなものです。
何が起こっているのか誰にも分かりますか?
ありがとうございました
注:levelgen
これは、オブジェクトだけでは発生しません。たとえば、TestItem
上記のオブジェクトでも発生しています。実際、同じコードが自分のコンピューターの行levelgen:addItem(t)
でクラッシュしますが、別の開発者のコンピューターでt:setText("hello")
は同じエラー メッセージの行でクラッシュします。missing or unknown method 'setText' (a nil value)