Reload Lua files on the fly.

BobbyBonsaimind
Member
 
Posts: 97
Joined: Tue Apr 14, 2015 19:32
GitHub: RobertZenz
IRC: Robert_Zenz
In-game: Bobby

Reload Lua files on the fly.

by BobbyBonsaimind » Tue Jun 02, 2015 21:27

While thinking about how to better test my mapgen, I had the idea that it would be neat if I'd be able to reload parts of it on the fly, without the need to exit the subgame and restart it. There is no direct facility in Minetest that allows it, but we can work around it with a chatcommand and by encapsulating the important code in a function or object. Obviously you can't reload everything, as there are things that just need to be known when the mod starts, but other parts can be reloaded.

Let's have a look at the basics on how to accomplish this, assume this to be in the init.lua:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local base_path = minetest.get_modpath(minetest.get_current_modname())

minetest.register_chatcommand("reload", {
    description = "Reloads all we need.",
    params = "",
    func = function(name, params)
        dofile(base_path .. "/dynamic.lua")
        return true, "Done"
    end
})


And that's the basic framework, now you can run the command "reload" from within Minetest and "dynamic.lua" will be reloaded, you can make changes to "dynamic.lua" and simply reload it without having to exit Minetest.

You could also do that with a mapgen system, for example (note that the code assumes my utils mod to shorten it):

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local base_path = minetest.get_modpath(minetest.get_current_modname())
dofile(base_path .. "/mapgen.lua")

-- MapGen object is defined in mapgen.lua.
local mapgen = MapGen.create()

minetest.register_chatcommand("reload", {
    description = "Reloads all we need.",
    params = "",
    func = function(name, params)
        -- Reload the file.
        dofile(base_path .. "/mapgen.lua")
        -- Now we have the "new" MapGen object that we can use.
        mapgen = MapGen.create()
        return true, "Done"
    end
})

minetest.register_on_generated(function(minp, maxp, seed)
    local manipulator = MapManipulator:new()
   
    mapgen:run(minp, maxp, manipulator)
   
    manipulator:set_data()
end)


Now you can make changes to the system, type "reload" in Minetest and the next piece of the world is generated the new, reloaded system will be used.
 

prestidigitator
Member
 
Posts: 632
Joined: Thu Feb 21, 2013 23:54

Re: Reload Lua files on the fly.

by prestidigitator » Wed Jun 03, 2015 00:01

Right. Reloading the code isn't the problem. Dealing with the effects of the old code is what can screw things up. Any code module that gets reloaded needs to be carefully structured to take care of side effects. If it registers objects or callbacks, can they be replaced, or overridden somehow? Will old objects and functions still be referenced, essentially creating memory leaks and unexpected behavior? Those are the difficult sort of questions to answer, not whether or not dofile() can be called again. They make the "can" and "should" question very specific to the particular context in a mod.
 

User avatar
rubenwardy
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: Reload Lua files on the fly.

by rubenwardy » Wed Jun 03, 2015 06:59

It will work perfectly fine if the dynamic file only declared functions. The main init file could then register these in a callback through wrapping.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
mt.register_on_callback(function(one, two)
    dynamic.on_callback(one, two)
end)


I came up with a practically identical idea last year, but I've never used it other than in dev tch demos.

Of course you'd have to restart minetest if you want to add new call backs, unless you make a mechanism for it.
 

Sokomine
Member
 
Posts: 2980
Joined: Sun Sep 09, 2012 17:31

Re: Reload Lua files on the fly.

by Sokomine » Mon Jun 08, 2015 03:12

Dynamicly changing the code while working on a mapgen sounds like a very good idea. I just wonder how practical it actually is. There'd still be the need to fly into new terrain in order to get it generated. Or is there a way to get the current chunk beeing regenerated anew, without restarting the game?
A list of my mods can be found here.
 

BobbyBonsaimind
Member
 
Posts: 97
Joined: Tue Apr 14, 2015 19:32
GitHub: RobertZenz
IRC: Robert_Zenz
In-game: Bobby

Re: Reload Lua files on the fly.

by BobbyBonsaimind » Mon Jun 08, 2015 19:55

@Sokomine If it is probably encapsulated you'd only need to call it again for already existing blocks, either invoked by moving into it or when being invoked by a command. But no, I don't think that there is an automatic way.
 

User avatar
rubenwardy
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: Reload Lua files on the fly.

by rubenwardy » Tue Jun 09, 2015 07:57

You can use minetest.delete_block or whatever to delete mapblocks. They should then be remade in a few seconds. Also see /delete_block
 

BobbyBonsaimind
Member
 
Posts: 97
Joined: Tue Apr 14, 2015 19:32
GitHub: RobertZenz
IRC: Robert_Zenz
In-game: Bobby

Re: Reload Lua files on the fly.

by BobbyBonsaimind » Tue Jun 09, 2015 17:09

@rubenwardy I guess you mean "delete_area"? If yes, I have to try that, that sounds intriguing.

And it works, obviously. Pretty neat.
 

Nyarg
Member
 
Posts: 144
Joined: Sun May 15, 2016 04:32

Re: Reload Lua files on the fly.

by Nyarg » Sat Dec 17, 2016 17:54

More fun - prevent interrupt load script if error present on run.
Hmm but runtime errors still crash game.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local callResult, result = pcall(dofile, modPath .. "/dynamic_test.lua")
if callResult then
    print(" \n\n---------------- SUCCESS dynLoad   ---- ")   
else
    print("\n\n ---------------- ERR dynLoad   ---- \n"..result)
    chatSend("\n\n ---------------- ERR dynLoad   ---- \n"..result)
end
I am a noob. still yet. Not so noob ) [vml] WIP
"My english isn't well" I know. I'm sorry )
 


Return to Modding Discussion

Who is online

Users browsing this forum: No registered users and 67 guests

cron