Modding Help Why won't this work? Please help me.

Discussion in 'Starbound Modding' started by @lias, Apr 19, 2017.

  1. @lias

    @lias Void-Bound Voyager

    status.setStatusProperty("frontArmRotationCenter", [-3, 5])
    I found a LUA function that's supposed to be able to swap part of a player's properties out for new values and tried dropping it into a pre-existing status effect, but it won't do anything. What else is missing that I need to make it work?
  2. Errors4l

    Errors4l Ketchup Robot

  3. Cyel

    Cyel Zero Gravity Genie

    I doubt Status Properties can't change this; and I think only activeItems can affect arms, with activeItem.setFrontArmFrame() and activeItem.setArmAngle(). What are you trying to do exactly? Maybe there's another way of doing something similar
  4. @lias

    @lias Void-Bound Voyager

    Thanks, I didn't know this.

    I'm starting to think you're right, which is really disheartening.

    I want to be able to set custom rotation points and offsets for arms without having it affect everybody. I'm trying to wring out as much control over the player as I possibly can, and it's gone pretty well until now.
    I've already figured out how to change arm position for individual races, but I want to be able to change it by armor and status effects too. I can change the player's hitbox, physics, size, you name it, but arm rotation so far seems untouchable. It doesn't seem to be defined anywhere but humanoid.config. I thought I could get to it with set.statusProperties, but I guess it can only change things in the player.config? Frustrating.
  5. Cyel

    Cyel Zero Gravity Genie

    In which context is your script running? An object, a tech, a statuseffect, something else?
  6. @lias

    @lias Void-Bound Voyager

    Status effect, though I probably didn't set it up right. I figured that was the only way to get it on armor.

    e: Incidentally, what all can you apply patch files to? Can you patch .species files, because I may have a hackish idea.
  7. Cyel

    Cyel Zero Gravity Genie

    Yes, you can patch basically anything that is a text file and not a .lua script (more specifically, anything that is formatted in JSON)

    Another hack-ish way to do it would be to use vehicle.setLoungeDance() with a custom dance, but I don't really see how to
  8. @lias

    @lias Void-Bound Voyager

    Update! I'm getting... well, I'm getting somewhere with the patching experiment, that's for sure. I don't want to say anything definitive because it's a pretty weird loophole and I'll be flummoxed if it ends up working, but initial results are interesting, to say the least.

    I'll post a full analysis tomorrow after work.
    Cyel likes this.
  9. Cyel

    Cyel Zero Gravity Genie

    (Unrelated, but I really like your wording)
  10. bk3k

    bk3k Black Hole Surfer

    I think this post may be giving the wrong idea... possibly you may also have the wrong idea.

    The answer itself is correct, but the difference between { } and [ ] isn't the difference between objects and arrays. I tell you this because you're calling a function in LUA, so only the LUA syntax applies. You aren't sending JSON(despite what some iffy documentation might imply). Where data does need to be stored as JSON or read from JSON, Starbound's engine (likely some library) handles the conversion automatically.

    In JSON
    { } forms an object which is a data structure that is addressed with strings.
    [ ] forms an array which is a data structure addressed sequentially or numerically aka a list.

    In LUA
    { } forms a table which is a data structure that can be addressed with a string or number. This performs the equivalent purpose of both JSON's objects and arrays.
    [ ] is used to index a table aka read a certain piece of data from within it.

    That's the reason why OP's code didn't work.

    Furthermore you never use multiple data sets to index a LUA table, therefore a comma should never be involved. However you can do this -
    myTable = {
      my_nestedTable = {
      someNumber = 12,
    local testIndex = "someNumber"
    local testIndex2 = "my_nestedTable"
    local dump = ""
    dump = dump .. "\ntest 1 : " .. tostring( myTable["my_nestedTable"][1] )
    dump = dump .. "\ntest 2 : " .. tostring( myTable["my_nestedTable"][4] )
      --yes this is already a string but I'm trying to be consistent here
    dump = dump .. "\ntest 3 : " .. tostring( myTable[1] )
    dump = dump .. "\ntest 4 : " .. tostring( myTable["someNumber"] )
    dump = dump .. "\ntest 5 : " .. tostring( myTable[testIndex] )
    dump = dump .. "\ntest 6 : " .. tostring( myTable[3] )
    dump = dump .. "\ntest 7 : " .. tostring( myTable[testIndex2][2] )
    dump = dump .. "\ntest 8 : " .. tostring( myTable[testIndex2][1] == myTable.my_nestedTable[1] )
    will output
    test 1 : 5
    test 2 : cake
    test 3 : 15
    test 4 : 12
    test 5 : 12
    test 6 : nil
    test 7 : 42
    test 8 : true
    Now I will note something important here.
    JSON objects and JSON arrays can both be converted to a LUA table.
    A LUA table with only numeric indexes (simply a list) can be converted to a JSON array.
    A LUA table with only string indexes can be converted to a JSON object.
    myTable as used in my example CANNOT be converted to JSON because it contains both. LUA tables are more flexible than any data structure offered by JSON. So when you read in the documentation that it needs to be a JSON whatever, they really means a LUA table that can be converted to that JSON data structure, or in other words a LUA table that falls within the limitations of that JSON structure.
    Last edited: Apr 20, 2017
    MelOzone, @lias and Cyel like this.
  11. Cyel

    Cyel Zero Gravity Genie

    [ ]*?

    (thanks for the in-depth answer)
  12. bk3k

    bk3k Black Hole Surfer

    oops I did type the wrong brackets.
  13. @lias

    @lias Void-Bound Voyager

    Well, that was a bust. I thought it was a pretty good idea, but it stopped just short of actually accomplishing anything.

    Because the humanoid.config file is the only place I've ever been able to mess with arm rotation stuff, I figured the solution would have to be something to do with that. But the standard races' species files don't have a line for defining what particular -oid files they point to, instead I guess just defaulting to humanoid.config. So what I did was make a patch file that added that line to the human.species file, and had it point it to penguinoid.config. And it worked! My human characters and all the humans in the outpost were sunk into the ground up to their knees and had their arms in the wrong place, it was a hoot. Now that I knew it worked, I pointed it back to humanoid.config so it wouldn't mess with gameplay and prepped for phase 2.

    Unfortunately, phase 2 was not as successful, or even sort of successful. The plan was to use setStatusProperty to swap out the player's humanoidConfig destination for whatever I needed, now that I had the code where it needed to be thanks to the patch file.

    But, uh, nothing happened. There weren't even any errors in the log, just a complete absence of cool things and science happening. It was very anticlimactic. I thought for sure setStatusProperty could change things relating to stuff that comes from the .species files, because the example given in sblaud for replacing the player's hurt sound with a rocket explosion sound worked just fine, and I'm pretty sure that also gets defined from the species file.

    Is this a dead end, or did I mess something up? Where do the parameters drawn from humanoid.config go when they become part of the player, and how can I look at it?

    I'm not gonna lie. This is really, really cool and I deeply appreciate you taking the time to post it and help clarify things for me, but I'm having a very hard time parsing it. If it's not too much trouble, could you dumb it down for me some? It's pretty high concept for where I am right now in terms of understanding the things that make starbound tick. Could you put it into the context of something simpler? How do I apply this?

    Last edited: Apr 21, 2017
  14. bk3k

    bk3k Black Hole Surfer

    Hmm hard to know what you already know, so how to make sense of that? Forgive me for telling you things you know.

    Lets start with the table declarations.
    myTable = {
      my_nestedTable = {
      someNumber = 12,
    is equivalent to doing this
    myTable = {}
    myTable["my_nestedTable"] = {}
    myTable.my_nestedTable[1] = 5
    myTable.my_nestedTable[2] = 11
    myTable.my_nestedTable[3] = 37
    myTable.my_nestedTable[4] = cake
    myTable["someNumber"] = 12
    myTable[1] = 15
    myTable[2] = 42
    Clearly the former involves a lot less typing but they both get to the same place. At least I didn't do this
    myTable = {my_nestedTable = {5,11,37,"cake"},someNumber = 12,15,42}
    But that is also the same thing minus the whitespace. Lets move on.

    myTable["my_nestedTable"] is the same thing as myTable.my_nestedTable both represent different ways LUA allows you to address them so do what you prefer.

    tostring is an included function in LUA that turns other LUA types into strings, within limits. Trying to convert a table isn't going to work, as addressing the table will get you the unique identifier for the table. Now if you want a function to turn your tables (including nested tables) into nice strings for debug purposes, I can give provide that upon request. Likewise you can't turn function into strings as you'll only get the identifier.

    testIndex, testIndex2, and dump are all strings. dump though gets declared as an empty string.
    .. can be used to append strings
    local myString = "Hello " .. "World"
    myString is now "Hello World"

    "\n" is the most common example of an escape character. I suggest learning your escape characters but those is easily found online. That one creates a new line and so it useful for readability.

    So what else? Hmm maybe how I accessed nested table indexes?
    local someValue = myTable[testIndex2][1]
    can be done this less efficient way
    local temp = myTable[testIndex2]
    local someValue = temp[1]
    Imagine how phones work. Consider if you where dialing the following (USA based) phone number
    1 (309) 467-3164
    I don't know if anyone actually has that number... don't dial it.
    1 is the country code, but my fellow Americans probably just consider this what you hit for long distance
    309 is the area code
    467 is the exchange
    3164 is the specific number within that exchange.

    So lets look at this from the perspective of LUA tables
    local customerInfo = phoneNumbers[1][309][467][3164]
    local customerName =
    I'm assuming that under that number, they would have more information about the person who has that phone number in the form of a table. So you see how addressing more deeply nested tables works?

    The only line there that is remotely Starbound specific is the sb.logInfo() function that takes a string and dumps it into your log. That's pretty much how you get information into the outside world when all other means are disabled(for user safety sake).

    Now for what you don't understand yet, please ask specifically framed questions.
    @lias likes this.
  15. @lias

    @lias Void-Bound Voyager

    I'm not 100% there, but this is much more digestible. Thank you kindly, especially for the layman-friendly context, and please don't worry about talking down to me or anything as that's pretty much where I am. LUA is still super new to me because I'm generally just an art person and I'm just trying to learn out of necessity, as simple edits aren't taking me as far as they used to. I'm worming my way through the LUA reference guide and tutorials, but examples in context like this definitely help.

    I always thought you had to make tables out of JSON files, I didn't know you could do it all internally. The first example table you use is JSON, right? Using LUA for tables does look quite a bit more complicated and intimidating to the eyes of someone not used to it, though. I'm also a bit iffy on what the periods are doing. They're stand-ins for the brackets that reference other defined values in the file? Is that right?

    Again, thank you very much for taking the time to explain this to me.

    In other news, I managed to make what I was doing work for all of 5 happy minutes before I changed something and now it doesn't work anymore. I don't even know what I did differently to begin with, so I'm trying to retrace my steps and find the accidental solution.
  16. @lias

    @lias Void-Bound Voyager

    Turns out the "minor success" yesterday was just a glitch with the patch file that had nothing to do with the status effects I was trying, meaning my celebration was completely unwarranted.

    I'm about at the end of my rope. It's been over a week of constant blind effort and failure, and I haven't gotten anywhere. Any questions answered just raise further questions, things that I thought made sense don't, and it's becoming increasingly obvious I don't know nearly enough about any of this to start piecing together a working solution on my own. FFS, I bought the fourth edition of "programming with LUA" in the hopes that it could clear things up, and it's just complete jibberish. The book starts off friendly with the traditional "hello world" and then immediately takes a sharp left into something about factorials, and the rest of the book is largely the same. I understand it's a book for coders, by coders, but that's not much help to me, an idiot.

    At this point I've resigned myself to the fact that the only way this is going to happen is if I;
    1: start taking coding classes from scratch at the local college, which will take a year or two longer than I'm comfortable with as a solution,
    2: offer an exchange of services with someone who can code, something no one I've contacted has ever actually followed through on,
    3: hire a coder to do it, which would require finding someone who's already familiar with this dumb game and also willing to waste their important time on a frivolity like this. (PM me if you're out there)

    So unless somebody's looking for a quick buck or needs some top-notch pixel graphics for a mod or other project, it seems like I'm out of luck.
  17. Cyel

    Cyel Zero Gravity Genie

    No, from his post above:

    Note that you failing to do this particual thing might not be only because of your lack of "coding capacities" (from what you wrote you've tried quite a lot of things), but just that the game simply doesn't allow you to change this particular thing; while starbound offers a lot of things to mod, it's not uncommon to see some hard-coded /inaccessible / unchangeable things
  18. @lias

    @lias Void-Bound Voyager

    This is also very possible, though I've been fervently hoping it's not the case. I feel like it would help if I had a better grasp of what is and isn't possible, I'm kind of in the dark regarding what I can and can't change in relation to the player and all of the documentation I've found seems to be more for the LUA functions themselves and less how they can be used in different ways. A lack of practical application, if you will.

    Even given my limited capacity in understanding this, I feel like the answer has to be related to either the player file or the assembly thereof. From what I can gather, it's the conglomeration of bunch of tables of data drawn from the various config files and changes dynamically to accomodate things like status effects and movement parameters. I just wish I knew how it was constructed and what all of the internal values were so I knew what to reference when trying to change them. The closest I've found is this site, but I don't know when it was made or it it's even relevant anymore.

    To tell the truth, all these LUA functions feel like I'm being handed innumerable puzzle pieces of all different shapes and sizes, but I've only got a guess and a prayer as to what the finished product would look like, and no way of telling which pieces are even part of the puzzle I'm trying to complete.
  19. @lias

    @lias Void-Bound Voyager

    Update. After finding out how to look at deobfuscated player files, I don't think what I'm trying to do can be done. My hypothesis was flawed to begin with; because the player's ouchnoise was part of the .species file and could be edited by setStatusProperty, I thought I could change other parts of the species file, too. But for some reason in the player file it's rolled into the status section, something arm offset is not part of, making setStatusProperty useless for this.

    The only bright part of this is I can't find anything relating to arm offset or rotation anywhere in the player file, meaning it's... somewhere else, I guess? Which means that it could potentially still be found and changed UNLESS it was part of a renderer or animator that only got loaded once, which would support my earlier findings of being unable to change anything to do with .humanoid files dynamically. The only thing that came close to working was using the patch file to append the "/humanoidConfig" onto a species file that didn't have one, but I couldn't find any way to point it to something else after the fact.

    The prognosis isn't looking very good, basically.
    Last edited: Apr 22, 2017
  20. bk3k

    bk3k Black Hole Surfer

    1. That table isn't JSON. Indeed JSON cannot have both indexed and string addressed indexes. That's LUA. It looks funky though because I'm including different data types for example purposes. And it was intended for those that already sort of understand tables.

    2. Starbound does keep things persistently stored as JSON. All your Starbound text readable files that aren't .lua are themselves JSON. But you could just as easily load an external LUA file containing the information.
    3. Yes the periods are another way to access the contents of tables. Functionally
    are the very same thing.

    4. Some simple tables
    someTable = { }
    That's an empty table. If you instead did this
    someTable = { "string1", "string2", "etc" }
    it would be a table with 3 strings (as data, not for indexing). Then
    would return
    Just take it slow, and gradually do more complicated things. Try to make a very simple program, and dump the results with sb.logInfo() so that you can test your code. Playing around with actual code IMO is more useful than anything.

    I don't think you should consider looking at the vanilla scripts as many of them... are not written to be easily digestible. When I was teaching myself LUA(to mod this game), I found them pretty confusing and it might have done more harm that good. I can read them now, but that's just a simple matter of having more experience now.

    Instead read the scripts from different mods out there. See if some of their "real world" code is better for your learning purposes. Try to replicate a few things they do in your test code. Expect to fail numerous times. Failure is a harsh yet reliable teacher.
    @lias and Cyel like this.

Share This Page