Modding Discussion SB's lua engine. Performance, limitations, etc

Discussion in 'Starbound Modding' started by cpeosphoros, Jul 12, 2017.

  1. cpeosphoros

    cpeosphoros Orbital Explorer

    * 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.
     
    Last edited: Jul 13, 2017
  2. bk3k

    bk3k Oxygen Tank

    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.
     
  3. cpeosphoros

    cpeosphoros Orbital Explorer

    Didn't throw the exception, but a world.getProperty("t") just in the next line returned nil.
     
  4. TheElderScroller

    TheElderScroller Pangalactic Porcupine

    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
     
  5. bk3k

    bk3k Oxygen Tank

    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.
     
  6. cpeosphoros

    cpeosphoros Orbital Explorer

    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.
     
  7. cpeosphoros

    cpeosphoros Orbital Explorer

    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.
     
  8. zetaPRIME

    zetaPRIME Pangalactic Porcupine

    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!
     
  9. TheElderScroller

    TheElderScroller Pangalactic Porcupine

    I have access to load and loadfile. If you really don't have it then set "safeScripts" in your starbound.config to false.
     
  10. TheElderScroller

    TheElderScroller Pangalactic Porcupine

    If you dont want to use load then you could also use a lua lua-interpreter.
     
  11. bk3k

    bk3k Oxygen Tank

    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.
     
    cpeosphoros likes this.
  12. cpeosphoros

    cpeosphoros Orbital Explorer

    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.
     
    Last edited: Jul 14, 2017
    IHart likes this.
  13. TheElderScroller

    TheElderScroller Pangalactic Porcupine

    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.
     
  14. cpeosphoros

    cpeosphoros Orbital Explorer

    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.
     
  15. TheElderScroller

    TheElderScroller Pangalactic Porcupine

    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!
     
    Last edited: Jul 16, 2017
  16. cpeosphoros

    cpeosphoros Orbital Explorer

    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.
     
  17. zetaPRIME

    zetaPRIME Pangalactic Porcupine

    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)
     
  18. cpeosphoros

    cpeosphoros Orbital Explorer

    Nice info, @zetaPRIME, mind if I add it to my scripting tutorial?
     
  19. zetaPRIME

    zetaPRIME Pangalactic Porcupine

    ...why would I mind about simple factual info?
     
  20. TheElderScroller

    TheElderScroller Pangalactic Porcupine

    Edited my last post because I saw that I mixed up clientside and serverside.
     

Share This Page