2 Live reloading of minetest mods.
whosit edited this page 2024-02-27 11:04:11 +00:00

Since reloading the server with a lots of mods takes too long, during development it's nice to be able to just reload one mod/script whatever. There are pretty nice and advanced solutions for lua live/hot reloading (https://github.com/anton-kl/lua-hot-reload for example), but making them work with MT is not straightforward...

Main problem is that typical init.lua has a bunch of side effects that will make simple re-evaluating of init.lua do something you don't want. So you should structure your code with re-evaluation in mind and probably move the code you want to reload into separate module.

During development of a very simple mod I used this code, it's not bulletproof and should be improved, but I'm posting it here for myself:

local modname = "modname"
local modpath = minetest.get_modpath(modname)

local function error_printer(name)
    local p = function()
        minetest.chat_send_player(name, debug.traceback("Can't reload:", 2))
    end
    return p
end

local function reload_mod(name, _param)
    print('----------------------------------')
    minetest.chat_send_player(name, "Reloading "..modname.."...")

    local filepath = modpath .. DIR_DELIM .. "init.lua"
    local module, err = loadfile(filepath)
    if module then
        local status, ret = xpcall(module, error_printer(name))
        if status then
            print("Ok", dump(ret))
            minetest.chat_send_player(name, "Done reloading.")
        else
            minetest.chat_send_player(name, "Failed to execute.")
        end
    else
        print("Error", err)
        minetest.chat_send_player(name, "Failed to load:" .. err)
    end
end


minetest.register_chatcommand("rl", {
    params = "none",
    description = "reload",
    privs = { server = true },
    func = reload_mod
})