How can I link to callback functions in Lua such that the callbacks will be updated when the scripts are reloaded?

I'm implementing Lua scripting in my game using LuaBind, and one of the things I'm not clear on is the logistics of reloading the scripts live ingame.

Currently, using the LuaBind C++ class luabind::object, I save references to Lua callbacks directly in the classes that use them. Then I can use luabind::call_function using that object in order to call the Lua code from the C++ code.

I haven't tested this yet, but my assumption is that if I reload the scripts, then all the functions will be redefined, BUT the references to the OLD functions will still exist in the form of the luabind::object held by the C++ code. I would like to be able to swap out the old for the new without manually having to manage this for every script hook in the game.

How best to change this so the process works?

My first thought is to not save a reference to the function directly, but maybe save the function name instead, and grab the function by name every time we want to call it. I'm looking for better ideas!

• Do you only want to be able to sanely reload lua scripts for dev purposes? or do you want to do it in production as well? – Michael Slade May 6 '12 at 18:59
• @MichaelSlade I'm going to be doing both! My now-current solution is to store the name of the script "class" in each entity, and then use that name to resolve the necessary functions/data at runtime. This seems to be nice and easy (no management required) and so far isn't causing performance issues, but I would absolutely welcome ideas! – Raptormeat May 8 '12 at 7:01

It seems to me that you're probably going about implementing your script interface the wrong way.

If you're reloading scripts, that generally means some level of teardown and rebuilding of the mirror C++ objects that talk to them. For example, if you have a Lua script that runs the AI for an entity, there would be some C++ object that represents that AI. That object is responsible for communicating with the Lua script (so that external code is insulated from knowing that a Lua script is even involved).

That object needs to be destroyed and rebuilt with the newly loaded script.

let Lua do whatever it will without having to destroy / rebuild / manage anything on the C++ side.

If you want Lua to be in charge of this, then this means that Lua be in charge of this. With great power comes great responsibility. And if you want Lua to have the power, then the onus is now on Lua to have the responsibility to use it correctly.

If Lua hands some "function" to C++, then it is the responsibility of the Lua script to ensure that this function is properly and transparently updated when scripts change. There are several ways to do this in Lua. One way is to build a simple stub function which searches some global registrar object for the actual function to call:

local stubForDoStuff = function(...)
return Registrar.DoStuff(...)
end


You can even make a simple stub generator function (it would need to be more complex to find things that aren't direct members of the registrar):

function MakeStub(stubName)
return function(...)
return Registrar[stubName](...)
end
end


When a script changes, you simply update the functions in the Registrar. There are more complex ways of doing it, by giving C++ code tables that contain metamethods for __call that will go track down the actual function or whatever. But this is the simplest and most obvious method of doing it.

This sort of complexity is generally why I don't give Lua this power. I want to focus my Lua scripts on doing their actual job, rather than updating functions and other nonsense. So I give C++ the responsibility for managing Lua-created object loading and destroying.

I tend to use Lua scripts as an alternate means of instantiating C++ derived classes. So "reloading a script" means destroying an object and replacing it with a new one.

• Why does that "need" to be the case though? I would much rather have the C++ code be agnostic as to what Lua code it is pointing at, and let Lua do whatever it will without having to destroy / rebuild / manage anything on the C++ side. I can totally understand if I'm missing something or just being naive here- I'm just not sure what the advantages are of that model. – Raptormeat May 4 '12 at 19:38
• @Raptormeat: See edit. – Nicol Bolas May 4 '12 at 20:06