Allow mods to register "slash" commands or global functions
Posted: Mon Mar 14, 2016 2:29 pm
Currently, it doesn't seem there is anyway to either:
a) Allow mods to register "slash" commands, e.g. /mymod dosomething 123
b) Allow mods to define global lua functions, so that something like /c myfunction("abc", 123) would work.
Of course, there are ugly workarounds, by requiring the user to copy/paste commands first, that would allow, to some extent, (b), but (a) is really my suggestion.
Note that using interfaces, we can *almost* get to (b), even if it's not ideal. But I say almost because remote.call currently restricts the return value to strings.
Consider the interface defined as:
One might think we could access those functions with:
But we cannot. Because the return value from the function called by remote.call is forced to be a string. If it is a string, the return value is assigned to mymod. If it is not a string, mymod is instead assigned the name of the interface function. So after the first console command above, mymod would be the string "export", not a table of functions like you might expect.
For clarity, if the interface was defined as:
... then after the first console command above, mymod would be the string "This is my mod".
So returning strings from interface functions works, but returning tables does not.
Lifting the strings-only restriction would allow mod authors to expose any number of "public" lua functions with only a small amount of code needed to be entered by the user (the "/c mymod = remote.call(...)" line).
Coincidentally, this approach also gives the mod's functions their own unique namespace (in the above example, mymod). So even if two mods defined a function with the same name (e.g. named "reset"), they wouldn't interfere, as each would have to be called from the function table returned by remote.call (e.g. mymod.reset() vs. hismod.reset()).
Lastly, on the topic of moving closer towards (a), allowing mods to register slash commands, I'll just point out that World of Warcraft has a relatively straightforward way of allowing mods (which are also written in Lua) to register slash commands, which may be some inspiration of how the issue might be approached. (Link to example of registering slash commands removed, as it's my first post).
For those interested, below is one other attempt at exposing mod-defined functions globally. Although this approach should work in theory, it crashes Factorio.
a) Allow mods to register "slash" commands, e.g. /mymod dosomething 123
b) Allow mods to define global lua functions, so that something like /c myfunction("abc", 123) would work.
Of course, there are ugly workarounds, by requiring the user to copy/paste commands first, that would allow, to some extent, (b), but (a) is really my suggestion.
Note that using interfaces, we can *almost* get to (b), even if it's not ideal. But I say almost because remote.call currently restricts the return value to strings.
Consider the interface defined as:
Code: Select all
local function do_something_1()
game.player.print("Did something!")
end
local function do_something_2()
game.player.print("Did something else!")
end
remote.add_interface("mymod",{
export = function()
return {
["something1"] = do_something_1,
["something2"] = do_something_2
}
end
})
Code: Select all
/c mymod = remote.call("mymod", "export")
-- then --
/c mymod.something1()
For clarity, if the interface was defined as:
Code: Select all
remote.add_interface("mymod",{
export = function()
return "This is my mod"
end
})
So returning strings from interface functions works, but returning tables does not.
Lifting the strings-only restriction would allow mod authors to expose any number of "public" lua functions with only a small amount of code needed to be entered by the user (the "/c mymod = remote.call(...)" line).
Coincidentally, this approach also gives the mod's functions their own unique namespace (in the above example, mymod). So even if two mods defined a function with the same name (e.g. named "reset"), they wouldn't interfere, as each would have to be called from the function table returned by remote.call (e.g. mymod.reset() vs. hismod.reset()).
Lastly, on the topic of moving closer towards (a), allowing mods to register slash commands, I'll just point out that World of Warcraft has a relatively straightforward way of allowing mods (which are also written in Lua) to register slash commands, which may be some inspiration of how the issue might be approached. (Link to example of registering slash commands removed, as it's my first post).
For those interested, below is one other attempt at exposing mod-defined functions globally. Although this approach should work in theory, it crashes Factorio.
Additional attempt