Page 1 of 1

moding lua with live updates ingame without reloading?

PostPosted: Tue Aug 09, 2016 12:49
by ph8jPf9M
is there a way to make changes to lua mods to affect the game without the need for exiting to menu and entering the world again? Like you can make small changes to a mod and see live changes ingame. Then it would be possible to achieve codeacademy like learn to code in minetest with special modding tutorial subgames like the https://forum.minetest.net/viewtopic.php?t=10192 tutorial.

Re: moding lua with live updates ingame without reloading?

PostPosted: Tue Aug 09, 2016 19:23
by Byakuren
It would be tough, since many mods register nodes and things, which can only be done at init time. They also set up repeating actions and save/load data and things.

Re: moding lua with live updates ingame without reloading?

PostPosted: Tue Aug 09, 2016 22:58
by kaeza
You can code your mod in such a way to allow changing some behavior at runtime, but changing nodes at runtime is not possible.

Example:
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
-- init.lua
local do_something -- Local holding the function actually doing something.

local function reload_code()
  do_something = assert(loadfile(minetest.get_modpath("foo").."/dynamic.lua"))
end

reload_code()

minetest.register_node("foo:bar", {
  -- ...
  on_punch = function(...)
    return do_something(...)
  end,
})

minetest.register_chatcommand("reload_foo", {
  -- ...
  func = reload_code,
})

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
-- dynamic.lua
local pos, node, puncher, pointed_thing = ...
-- Do something here.
-- You can modify then reload this code fragment by issuing the
-- `/reload_foo` chat command (defined above).


Granted, there's not much flexibility, as Byakuren says, but it could be useful for certain things (particularly testing formspecs) until you decide on a final version.

Please, don't use it in production :P

Re: moding lua with live updates ingame without reloading?

PostPosted: Wed Aug 10, 2016 00:33
by BrandonReese
Would you be able to re-declare functions by reloading the file?

Re: moding lua with live updates ingame without reloading?

PostPosted: Wed Aug 10, 2016 22:18
by kaeza
BrandonReese wrote:Would you be able to re-declare functions by reloading the file?

There are no "declarations" in Lua (except for the `local` keyword).

When you define a function like this:
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
function foo(...)
  -- ...
end

The compiler actually sees something like this:
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
foo = function(...)
end

That is, you are assigning a value of type "function" to the (global, in this case) variable `foo`. When you execute the first code snippet again, it's again assigning to global `foo`.

To get to what I think is your question, you can change the values of variables holding functions (`foo` in the example) at runtime by simply assigning to them a new function value.

But the problem is how you use it in your code.

If you do something like this:
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
minetest.register_whatever("foo", {
  some_func = foo,
})

Then the field `some_func` in the definition holds the value of `foo` at that point, so if you later change the value at `foo` (by "reloading" or "redeclaring" the function), it won't get reflected in `some_func` unless you explicitly set it to the new value too.

If you do something like this:
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
minetest.register_whatever("foo", {
  some_func = function(...)
    return foo(...)
  end,
})

The function stored at `some_func` will read the value of `foo` at the point the function `some_func` is actually executed. So changing `foo` always reflects the change.

Tell me if something's not very clear and I'll try to explain it.

Edit: Also, it can't be stressed enough, but the Lua Manual and Programming in Lua are excellent resources.