21 posts
Posted 16 February 2015 - 11:49 PM
For modding purposes, I want there to be a variable exchange between two different Lua files; apparently os.run and shell.run can't return variables to the original code that called it.
Basically, something like this:
Mod file:
local mod = {
name = "test",
--moreModStuffHere
}
return mod
Base code:
local mod = shell.run("modFile")
print(mod.name)
It may be simple and I'm just missing something, but any ideas on how to get this to work?
7083 posts
Location
Tasmania (AU)
Posted 16 February 2015 - 11:56 PM
In a nutshell, what you're trying to do is have a script load in information from a file.
In this particular case, the answer would be to
manually read the file data and use
textutils.unserialize() on it. Eg:
Mod file:{
name = "test",
--moreModStuffHere
}
Base code:local myFile = fs.open("modFile")
local mod = textutils.unserialize(myFile.readAll())
myFile.close()
print(mod.name)
If you actually wanted executable code in your "mod" file, you'd rig it up as an
API.
355 posts
Location
Germany
Posted 17 February 2015 - 12:32 AM
I guess the part that really gets him is the return of values. Unfortunately lua chunks can not return values as if they were functions. You would have to write an interface which executes an "anonymous" function within the mod files. So that every mod has to have a certain function, for example run(), which gets loaded and executed by the host application(your base code).
Without testing Lignums code, I'll take his word for it. I know that loading a file or string will return the chunk as a function, which is able to take parameters, but of some source I was thinking the return value of the chunks function was allocated to handle debugging stuff, since the chunks themselve have a copy of the original source to for example, tell you which line the runtime error occured. I guess lua handles this somewhat deeper in the codez than I thought. So much for that misconception ^_^/>
Edited on 16 February 2015 - 11:51 PM
570 posts
Posted 17 February 2015 - 12:41 AM
Unfortunately lua chunks can not return values as if they were functions.
Yes, they can. Lua chunks
are functions. Try this:
Mod file:
return 5
Base code:
local modFunc = loadfile("modfile")
print(type(modFunc)) --# We've loaded the mod file as a function.
local theNumber = modFunc()
print(theNumber) --# Prints 5.
7083 posts
Location
Tasmania (AU)
Posted 17 February 2015 - 12:41 AM
Again, that is the circumstance in which you would build an API. For the specific purpose asked about, however, textutils.unserialize() is sufficient.
21 posts
Posted 20 February 2015 - 08:54 PM
Hi.
I'd previously posted here about trying to run a Lua script that would pass variables onto the script that started it. For example…
local _, returnedVariables = shell.run("mod")
I understand that returning variables is not a functionality of shell.run; I was merely using it as an example. Bomb Bloke had suggested that I use textutils.unserialize to manually read the mod file and convert it into a table, and if necessary, load it as an API to execute code. However, this really doesn't work. I've looked into it and textutils.unserialize does not support functions within the table, and os.loadAPI doesn't allow any kind of return values either.
In regards to my previous post, I believe I should have been a bit more specific and detailed:
Mod file:
--init code up here
mod = {
name = "testMod",
--more arbitrary properties here
mouse_click = function()
print("test!")
end,
timer = function(event)
if event[2] == "timer" then
print("another test!")
end
end
}
return mod
Basically, the modding is event based. Any event that has a function attached to it will execute in the game code once that event is triggered. My only problem here is that nothing I've tried can return variables to the script that started it like a function. I've considered using environments somehow and came up with the idea of putting it in _G for the game to retrieve. Although I'm sure there's a better way to do it - any suggestions?
355 posts
Location
Germany
Posted 20 February 2015 - 08:57 PM
Lignum posted some example code that fits your question ;)/>
1426 posts
Location
Does anyone put something serious here?
Posted 20 February 2015 - 09:00 PM
Can you not do:
local mod = loadfile("mod")
print("Loaded " .. mod.name)
Edit: Woops, only just saw Lignum's post. Sorry.
Edited on 20 February 2015 - 08:00 PM
7083 posts
Location
Tasmania (AU)
Posted 20 February 2015 - 11:09 PM
Mod file:--init code up here
name = "testMod",
--more arbitrary properties here
function mouse_click()
print("test!")
end
function timer(event)
if event[2] == "timer" then
print("another test!")
end
end
Base code:os.loadAPI("mod")
print(mod.name)
mod.mouse_click()
mod.timer({os.pullEvent()})
os.unloadAPI("mod")