* Edit: This thread was called "Passing functions through world.setProperty" This works fine: Code: a[1] = "a" a[2] = "b" world.setProperty("a",a) Now, this doesn't: Code: a[1] = "a" a[2] = "b" a[3] = function() return 1 end world.setProperty("a",a) I get this exception: (LuaConversionException) Error converting LuaValue to type 'N4Star4JsonE' Any ideas? Or is it just impossible? And, no, I can't just call world.callScriptedEntity to pass the function, because the target is not a master scripted entity.
It would seem from that error, you can only store something that can convert to JSON. And we don't have access to load() in order to get around it. Test that by trying to store Code: local t = {} t[1] = 50 t["hello"] = "world properties" world.setProperty("t", t) that was really annoying to type on this new phone. Anyhow that table can't translate to JSON.
Code: #### `void` world.setProperty(`String` propertyName, `Json` value) Sets the specified world property to the specified value. the value needs to be JSON, so no functions and userdata from lua. You could pass functions as a dumped string and load them in the receiving script. The Property will be stored on the world until removed with setting it to nil
Indeed... except as part of the LUA restrictions placed upon the SB modding API - we don't have access to load() - so while you could save the function as a string easily enough, you can't turn the string back to a function. Unless that has changed while I wasn't looking, or you know some neat trick I'm missing.
There's no lua modding API that I know of which allows load. That'd be a huge security gap. I'm actually amazed with how much SB let us get, in terms of lua. Most APIs don't even give access to _ENV, or metatables in general, or coroutines, or passing scripts to be ran in other entities' contexts. There're lots of evil trickery that can be done just with that.
Also, I'm amazed with SB's lua engine performance. With other games I've modded to, modders have to be concerned with performance issues all the time. A simple traverse in a table with a couple hundred entries sometimes can lag down the game to its knees, leading to a whole series of workarounds and tweakings. Here, it's just amazingly fast. In the mod I'm working in, I do a world.objectQuery that returns about 400 objects. Traversing it is taking about .005 seconds, including the overhead of logging each item. If not logging, it takes whopping .000 to .001 seconds... Other games' lua engines would make that to the order of 10s of seconds for the logging version.
Thus is the advantage of doing JIT over strict interpreter. Kind of necessary too, as most of the vanilla content is written in lua to begin with!
I have access to load and loadfile. If you really don't have it then set "safeScripts" in your starbound.config to false.
For my own personal use, that would be fine. Editing things like config files (despite how simple it actually is) seems to be beyond the comfort level of the average user. That's even less likely to fly if you upload a mod to the Steam Workshop. Plus - correct me if I assume wrong - doesn't that also unlock things like the remainder of the OS table, and the IO table? Despite how possibly useful some of that might be, I don't think game mods should have access to those. Almost no one is going to check the source code before running a game mod. If a significant portion of the user base had "safeScripts" disabled, you'd probably see some malicious "mods" put out there. Yes those "mods" would probably be removed in short order, but could be very bad for those that downloaded/ran them before that point. And this would create a more widespread notion in people's minds that downloading mods is "dangerous" etc. Judging from some posts here and some on the Starbound Reddit, enough people refuse to mod as is. So personally I'd just rather find a way to do what I want within the confines of "safeScripts". There would usually be one way or another to accomplish most of what you're looking to do anyways, even if less direct/convenient.
I second bk3k on that. I was able to circumvent the problem by injecting a script (via .patch) into the object I was trying to communicate with, to add a message.handle and then sending messages. In the process, I discovered quests are server sided. That is why I was getting "target is not a master scripted entity" from callscripted.
Quests are clientside. world.callScriptedEntity() works from clientside to clientside scripts, and from serverside to serverside scripts. The exploits the community had with that before it was like this were insane.
So I thought also. Until I tried to world.callScriptedEntity() from a quest to an object and got "target is not a master scripted entity". If quests are client side, then objects are server side? I believe you. I was trying some insane exploits myself. Though, with message.handle, it's not that much harder.
Yes, objects are serverside (they always were). There are still alot exploits in the current version causing crashes, disconnects or corrupted game files. If you set safeScripts to false, people might do bad things to your computer. So don't do that unless the mods you install are trustworthy, or you know how to protect your computer. Luckily not everyone knows how to cause real damage!
Then quests have been moved serverside. If they were both clientsided I would be able to call world.callScriptedEntity() from quest to object, and I am not.
quests are clientside (belonging to the player); as are activeitems held by players (but serverside when held by NPCs); anything belonging to the world (npcs, monsters, objects, etc.) is serverside, even in ship worlds (saving/loading is dependent on the connected player, but actual interaction and world simulation is on the server)