S2F - Basic LuA and Advancing Animation.

Discussion in 'Starbound Modding' started by The | Suit, Dec 23, 2013.

  1. The | Suit

    The | Suit Agent S. Forum Moderator

    Start to Finish - Basic LuA and Advancing Animation.

    Hello again, my second tutorial in the series.
    We are going to now learn basic LuA and animations.
    If you haven't seen my first tutorial on how to make pixel art and animate. Go there.
    http://community.playstarbound.com/...pixel-art-and-putting-it-into-the-game.57153/

    INDEX
    1. Part 1: On and off Scripting
    2. Part 2: Part based Animation
    3. Part 3: We shall see.

    Part 1: On and Off scripting.

    Overview:
    In Part one of the tutorial. We will see how to make an object turn its animation on and off when interacting with it.

    Before you start the tutorial you would have to at least read part 2 of the previous tutorial, which covers
    • Creating a recipe
    • Modifying an object file.
    • Creating a Mod Info File.
    • Modifying player config file.
    Chapter 1: Setting it up.
    Ok lets get started.
    First thing lets open your starbound folder.

    Code:
    C:\Program Files (x86)\Steam\steamapps\common\Starbound
    Go to your mods folder, and make sure its empty. Just backup any mods you have installed.
    [Not covering how to merge mods - because of pending update]

    Now create a new folder inside mods folder and lets name it sdish.

    Now we want to create a few folders inside sdish
    Code:
    Starbound\mods\sdish\objects\generic
    Code:
    Starbound\mods\sdish\objects\wired
    Code:
    Starbound\mods\sdish\recipes
    Now go to
    Code:
    C:\Program Files (x86)\Steam\steamapps\common\Starbound\assets\objects\wired\ironbeacon
    and copy
    • ironbeacon.animation
    • ironbeacon.lua

    to your corresponding mod folder.
    Rename the files
    • sdish.animation
    • sdish.lua
    Now go to
    Code:
    C:\Program Files (x86)\Steam\steamapps\common\Starbound\assets\objects\boss
    and copy
    • ironbeacon.object
    • ironbeacon.png
    • ironbeaconicon.png

    Place it in the corresponding objects folder. [boss folder not required]
    Rename the files
    • sdish.object
    • sdish.png
    • sdishicon.png
    Finally go to

    copy the ironbeacon.reciepe and place it in the associated mod folder.
    In total you would have copied 6 items.

    So our directory structure would look like

    [​IMG]

    [​IMG]

    [​IMG]

    Keep note at the path bar on top.

    Chapter 2: Code Clean up

    DISCLAIMER - If you know how to re-associate all the files to sdish. Feel free to skip this chapter. Otherwise read on

    Now we have all our files and renamed them. We are going to need to change the code to sdish for all of them.
    lets open up sdish.object first.

    Code:
    {
      "objectName" : "sdish",
      "rarity" : "Common",
      "objectType" : "wire",
      "description" : "A distress beacon. Who knows who might hear it?",
      "shortdescription" : "Sdish",
      "race" : "generic",
      "category" : "decoration",
      "printable" : "false",
      "apexDescription" : "A distress beacon. I hope the person who left it is okay.",
      "avianDescription" : "A distress beacon. Someone must be in trouble.",
      "floranDescription" : "Floran help as well as hunt. Sssometimes.",
      "glitchDescription" : "Analysis. This distress beacon is transmitting at a number of frequencies.",
      "humanDescription" : "This beacon's sending out a distres call.",
      "hylotlDescription" : "Someone needs help. Protecting the weak is a worthwhile pursuit.",
    
      "inventoryIcon" : "sdishicon.png",
      "orientations" : [
        {
          "dualImage" : "sdish.png:<color>.<frame>",
    
          "imagePosition" : [-16, 0],
          "frames" : 12,
          "animationCycle" : 2,
    
          "spaceScan" : 0.1,
          "anchors" : [ "bottom" ]
    
        }
      ],
    
      "animation" : "/objects/wired/sdish.animation",
      "animationParts" : {
        "beacon" : "sdish.png"
      },
      "animationPosition" : [-16, 0],
    
      "scripts" : [ "/objects/wired/sdish.lua" ],
      "scriptDelta" : 5
    
    }
    
    Any where it says ironbeacon replace it with sdish. Make sure the name matches the files you made accordingly.
    A quick and easy way to do it is to press Control + F [ in notepad++ - if you don't have read my first tutorial]

    • you will see a replace tab.
    • type in ironbeacon
    • choose replace as sdish
    • hit replace all

    [​IMG]

    Now double check to make sure its been all changed. Short description will need to be changed manually since there was a space. It should match the code provided above.

    Don't worry about the script location, since we made our directory architecture in mods too match we are safe.
    Also do not worry about the beacon in parts. Reason for it is described below.

    == Extra Lesson ==
    One new piece of code is there. Which wasn't covered in the previous tutorial
    [
    CODE] "animationParts" : {
    "beacon" : "sdish.png"
    },[/CODE]

    Animation parts
    Basically it is defining part of the object which is named in the associated frames file.
    In our case it is default. Which will associate with anyone name. But, if our png had multiple different images, each assigning a different part to our object. We would have to name each part accordingly and our frames file will handle the associations.

    For sake of example we will look at

    [​IMG]

    Code:
      "animation" : "turret.animation",
      "animationParts" : {
        "gun" : "turret.png",
        "bracket" : "turret.png",
        "beam" : "beam.png"
      },
    On first glance you will see the gun has 2 states and 2 parts shown.

    Parts are
    • Bracket [called neck in image, bracket in code. Artist and programmer had disagreements :p ]
    • Gun
    States are
    • Idle
    • Attack
    the frame code it is

    Code:
    {
      "frameGrid" : {
        "size" : [48, 23],
        "dimensions" : [4, 2],
    
        "names" : [
          [ "idle", null, null, "bracket" ],
          [ "attack.1", "attack.2", "attack.3", "attack.4" ]
        ]
      }
    }
    
    Size
    Syntax is [Single frame width in pixels, single frame height in pixels]

    Dimension
    Now both numbers are used. A quick reminder [horizontal frames, vertical frames] is the syntax.

    Names
    names wasn't covered before, essentially here you are now designating the name of each frame
    • Null - represents frames to be ignored
    • Idle and bracket - are single frames non animated
    • Attack.# - represents to play this frame in this order.
    the word attack can of course be changed to anything.
    Syntax being

    Code:
    name.#
    Naming is important since we will be calling these names from LuA.
    We will cover more of this particular topic next Part. I just covered this so you have an idea about what is going on.
    === END LESSON ===


    sdish.frames you don't need to touch.

    Lets open sdish.recipe now.

    Code:
    {
      "input" : [
        { "item" : "darkwoodmaterial", "count" : 1 }
      ],
      "output" : {
        "item" : "sdish",
        "count" : 1
      },
      "groups" : [ "plain", "all", "other" ]
    }
    
    We will want to change item output to sdish. Also you may have noticed I changed all the inputs to darkwood. I have done this for testing purposes. Since wood is easy to find and easy to test with. Feel free to follow suite or set your own. Of course you can change it later after testing.

    Some of you may have also noticed I changed the groups of crafting. Also for testing purposes. I wanted to be able to craft it anywhere to quickly test. Now that your recipe is done.
    [ Disclaimer - All this is thoroughly explained in the previous tutorial. Link found on top to this page. ]

    Now finally we need to deal with sdish.animation.

    Code:
    {
      "animatedParts" : {
        "stateTypes" : {
          "sdishState" : {
            "default" : "idle",
            "states" : {
              "idle" : {
                "frames" : 1,
                "cycle" : 0.15
              },
              "active" : {
                "frames" : 12,
                "cycle" : 0.7,
                "mode" : "loop"
              }
            }
          }
        },
    
        "parts" : {
          "beacon" : {
            "properties" : {
              "centered" : false
            },
    
            "partStates" : {
              "sdishState" : {
                "idle" : {
                  "properties" : {
                    "image" : "<partImage>:default.default"
                  }
                },
    
                "active" : {
                  "properties" : {
                    "image" : "<partImage>:default.<frame>"
                  }
                }
              }
            }
          }
        }
      }
    }
    
    We will want to change all "beaconStates" to "sdishStates"
    leave the part beacon as is - as mentioned before. It is being referenced by the object file.
    If you changed it on your own accord, it will have to be changed to what ever name you gave it in the objects file.

    Now the animation piece of the code looks very complex. But can be break it down easily.
    If you are using Notepad++ as recommended, you can easily break down the hierarchy by following the curly brackets.

    For those of you are lost. Go back to basic math where you had calculations in parentheses. Inside calculations are done first as opposed to out side.

    In programming its almost along the same lines. What is inside the top most bracket is considered part of the parent function.
    So in this case the hierarchy is

    1. Animated Parts
      1. stateTypes
        1. sdishState
          1. default
          2. states
            1. idle
            2. active
      2. parts
        1. beacon
        2. partStates
          1. sdishState
            1. idle
            2. active

    One thing to keep in mind each piece we define is only associated within the hierarchy it is in.

    Animated parts
    Required.

    Statetypes
    First we are defining which one is the default state from the states we define later.

    States
    We describe the states
    How many frames it has - which is defined in the frames file
    Cycle defines how fast to cycle through it.

    Mode
    Variations of modes will be listed.
    But how the animation runs. Loop would essentially be once it finishes the animation it starts from the beginning.

    Properties [under beacon parts. ]
    various properties are
    • offset : [x, y]
    • rotationGroup : "x", - not sure [?]
    • centered : false or true
    • zLevel : 0, 1, 2 [background middle foreground layer [?]]

    partStates
    Defined by the object file and described by the statetypes from the above section.
    In our case we only had 1 state. sdishState.

    But if you look at the turret.animation
    Code:
     "movement" : {
            "priority" : 0,
            "default" : "idle",
    
            "states" : {
              "idle" : {
                "frames" : 1
              },
              "attack" : {
                "frames" : 4,
                "cycle" : 0.25,
                "mode" : "loop"
              }
            }
          },
          "beam" : {
            "default" : "invisible",
    
            "states" : {
              "invisible" : { "frames" : 1 },
              "visible" : { "frames" : 1 }
            }
          }
    It has 3.
    • Movement
    • Attack
    • Beam
    Now back to our Sdishstate.
    We now define what are the states.
    We have Idle and Attack set up and now another properties.

    Properties [under states]
    Here we are defining the image and animation.
    Code:
    "image" : "<partImage>:default.default"
    Code:
    <part image>
    is referencing what image to use in you objects file.

    Code:
    :default
    is referencing which name in the Frames file.
    In our case we only have one name.

    Lets go back to our turret example from above. you would have remembered 3 names.
    • bracket
    • idle
    • attack

    now finally
    Code:
    .default
    only required if its an animated part otherwise not needed. No animation would be idle state of turret as previously mentioned.
    If there is only a single part in that image. .default is fine for the stream
    if the image contains multiple images as our turret used <frame> as opposed to .default
    this will play all the frames accordingly in order.

    Now we are done with the explanations.
    Final code should be same as the one provided earlier.
    So lets move onto the LuA shall we?

    Chapter 3: Getting the feet wet.
    Ok now open sdish.lua and delete everything inside. Explanations for it will be another time, in a further tutorial.
    Scary isn't it staring at a blank page for the first time.
    Don't worry

    Now here is the code we will be working with.
    Code:
    function init(args)
      entity.setInteractive(true)
      end
    
    function onInteraction(args)
            if entity.animationState("sdishState") == "idle" then
                    entity.setAnimationState("sdishState","active")
            else
                    entity.setAnimationState("sdishState","idle")
            end
    end
    
    Very simple, no?

    LUA code here is based on various functions. Each function defines what is going to happen in what condition.

    In our first line.
    Code:
    function init(args)
      entity.setInteractive(true)
      end
    int(args)
    We are saying on initialization what do we want to happen.

    entity.setInteractive(true)
    We are stating the object on intialization what will happen - so in our case true. It will be interactive on initalization.

    Now we end it.
    Because the function is about what happens when it is initalized. We will now describe what happens when its interacted with.

    Code:
    function onInteraction(args)
            if entity.animationState("sdishState") == "idle" then
                    entity.setAnimationState("sdishState","active")
            else
                    entity.setAnimationState("sdishState","idle")
            end
    end
    function onInteraction(args)
    Here we are defining what happens when we interact with the entity.

    if entity.animationState("sdishState") == "idle" then
    We are refrencing the state in Lua we did in animation.

    So we setup the value "idle"
    If you remember default state is Idle as referenced by the animation.

    then
    we are now stating what happens if its in idle by the next line.

    entity.setAnimationState("sdishState","active")
    we are changing the value of sdish state to active

    else
    entity.setAnimationState("sdishState","idle")


    If sdishState was not idle to begin with on interaction then we are setting the state to idle
    We are finished!
    of course end which closes else functions

    ======
    By now you should have a basic idea of how to make a basic playerconfig file and modinfo file which associates with items.
    If you don't know how please follow Part 2 of the first tutorial.
    http://community.playstarbound.com/...pixel-art-and-putting-it-into-the-game.57153/

    For those who wish can download the sample mod here. If you have any issues, you can compare what you did wrong.
    https://www.mediafire.com/download/sjmxfs1z4zqqjgi/mods3.rar

    =======
    Another tutorial done. 2 More parts will come based on this. Stay tuned.
    If you liked it, have any questions, comments, found a mistake. Feel free to Reply. Don't forget to share to others if found useful.
    Honorable mention to Pocico for assistance in LuA.
     
    Last edited: Mar 6, 2014
  2. The | Suit

    The | Suit Agent S. Forum Moderator

    Part 2 Reserved
     
  3. The | Suit

    The | Suit Agent S. Forum Moderator

    Part 3 Reserved
     
  4. zortbg

    zortbg Cosmic Narwhal

    Awesome!!!!
     
  5. The | Suit

    The | Suit Agent S. Forum Moderator

    Glad you liked it - you will need to update your code to follow the tutorial in Angry Koala.

    Notice:
    LuA reference code has changed in Angry Koala
    The reference Object has now become Entity.

    The tutorial has been updated accordingly.
    Will be updating first tutorial with new merge tutorial for config files tonight
     
    zortbg likes this.
  6. lornlynx

    lornlynx Cosmic Narwhal

    Thank you, good basic tutorial.

    Though there is a small mistake, there is an "end" too much at the end of the lua function, you get an EOF exception thrown at initialization if you don't remove it.
     
  7. The | Suit

    The | Suit Agent S. Forum Moderator

    Thx - I forgot about that for a long time
    fixed
     
  8. heinermann

    heinermann Scruffy Nerf-Herder

    I'd like to add something awesome to this tutorial. The following allows you to use the .animation files to modify some image variables, and also allows you to programmatically modify some image parameters via lua script.

    These are a set of modifiers that you can add to your image:
    Code:
    ?fade=<color>=<fraction_amount>
    ?brightness=<amt_percent>
    ?saturation=<amt_percent>
    ?hueshift=<amt_degrees>
    ?replace;<color1>=<color2>;
    ?addmask=<file>
    ?submask=<file>
    ?multiply=<color>
    ?border=<size>;<color1>;<color2>
    ?scalenearest
    ?scalebilinear
    ?scale=<value>                        <-- can't be a variable
    ?scalebicubic
    ?crop=<left>;<top>;<right>;<bottom>
    ?setcolor=<color>
    ?flip
    Append this to the image frame in the animation file and make cool things happen. For example:
    Code:
    "image" : "<partImage>:default.<frame>?scale=2"
    Will cause the image to appear twice as large.

    Most of these are undocumented and unused, this is just what I've found.
    The best part about this is that most of these can be programmatically modified with Lua script using tags.

    Example:
    Code:
    "image" : "<partImage>:default.<frame>?hueshift=<custom_hue>"
    In Lua:
    Code:
    if ( hue_degree >= 360 or hue_degree == nil ) then
      hue_degree = 0
    end
    entity.setGlobalTag("custom_hue", hue_degree)
    hue_degree = hue_degree + 1
    This will cause your image in the game to sequence through every hue/colour in real time without having to do any additional work.

    fade: Not entirely sure but I think it fades the image out by a given fraction to the given colour. (it may be from 0 to 1, 0 = no fade, 1 = exactly the colour you specified)
    brightness: The brightness of your image. -100 makes it black, 100 makes it white
    saturation: The colour saturation of the image. -100 makes it greyscale, 100 makes it unbearably colourful.
    hueshift: As described above. The hue shift goes from 0 to 360 degrees.
    replace: Replaces one colour with another (I think), for example you can have team colours while the others remain the same.
    addmask: One of the few ones that were actually used, see penguintank.animation. All transparency makes your image invisible.
    submask: Similar to addmask.
    multiple: unknown
    border: Adds a glowing border to the image.
    scalenearest: Not sure
    scalebilinear: Not sure
    scale: Scales the image in size. 0.5 = half size, 2 = 2x size
    scalebicubic: not sure
    crop: Assuming it crops your image.
    setcolor: Colours your entire image with the given colour.
    flip: Supposedly flips the image.


    EDIT: I forgot to mention that "color" is a color hex code (like in html) (3/6/8 characters)
     
    Last edited: Mar 7, 2014
  9. Kawa

    Kawa Tiy's Beard

    Just a hunch, given a non-1.0 scale value, the other three might serve to tell how?
    For reference:
    scales.png
     
    The | Suit likes this.
  10. BalsamicVinegar

    BalsamicVinegar Void-Bound Voyager

    I have a question. If I wanted to change the player scale, where would I put that bit of code? I tried putting it in the "frameGrid" part of the humanoid .frames, but only ended up with an invisible character. I'm sorry, I'm a bit new to this kind of stuff, but any help is much appreciated!
     
  11. Carlosw55

    Carlosw55 Void-Bound Voyager

    I'm not sure how to make it work. Could you explain where to paste it? inside what function or give an example please. Thank you!
     
    mappo likes this.
  12. Kurague

    Kurague Scruffy Nerf-Herder

    I am interested in learning how to change the charactr size too, would appreciate the help a lot, and a lot of people that want to do this, but cannot because they don't know how, too.
     
  13. No one knows because you cant.
     
  14. Kurague

    Kurague Scruffy Nerf-Herder

    Yes you can, and I have seen it in a multiplayer server. When I see the person I will screenshot and show it to you. The multiplayer server is modclean 100%
     
  15. Kurague

    Kurague Scruffy Nerf-Herder

    I found out how. You have to go to Starcheat, load a save, export to JSON, open with notepad++ and use "?scale=(Number of scale)" in every directive. This is how you scale your character and the others can see it. After this import the JSON save file, and then change your hitbox so you are not inside the ground.
     
    The | Suit likes this.
  16. ArtosVI

    ArtosVI Void-Bound Voyager

    How would you go about changing the hitbox?
     
  17. Kurague

    Kurague Scruffy Nerf-Herder

    Idk about that at all. It's a prob I cannot deal with xD
     
  18. n1njadragon

    n1njadragon Void-Bound Voyager

    @heinermann:

    Would you happen to know how to change the color of a projectile in json? I've been trying to figure out how I can use ?hueshift to do it through starcheat(or notepad++ to configure the item's json code). Would greatly appreciate any help you provide.
     
  19. prodamn

    prodamn Spaceman Spiff

    you can do it with starcheat, but you can alos do it without.

    1st: ____Starcheat____

    No clue... i haven't ever used that because it's just not that useful for me as modder, not cheater.

    2nd: __NON-Starcheat___

    open up the projectilefile: for instance here now bullet-1 (because i still have that open from yesterday)

    Code:
    {
      "projectileName" : "bullet-1",
      "frames" : "bullet-1.png",
      "animationCycle" : 0.25,
      "level" : 3,
      "frameNumber" : 1,
      "damageKindImage" : "icon.png",
      "pointLight" : false,
      "actionOnReap" : [
        {
          "action" : "config",
          "file" : "/projectiles/explosions/bulletexplosion/bulletexplosion.config"
        }
      ],
      "power" : 5.0,
      "damageKind" : "default"
    }
    
    yay i just noticed this wasn't necessary... we search for the entry which sets the ingame sprite.

    Code:
    "frames" : "bullet-1.png",
    now we can do what we want with that.
    choose one!

    Code:
    ?fade=<color>=<fraction_amount>
    ?brightness=<amt_percent>
    ?saturation=<amt_percent>
    ?hueshift=<amt_degrees>
    ?replace;<color1>=<color2>;
    ?addmask=<file>
    ?submask=<file>
    ?multiply=<color>
    ?border=<size>;<color1>;<color2>
    ?scalenearest
    ?scalebilinear
    ?scale=<value>                        <-- can't be a variable
    ?scalebicubic
    ?crop=<left>;<top>;<right>;<bottom>
    ?setcolor=<color>
    ?flip

    Code:
    "frames" : "bullet-1.png?flip?setcolor=<color>",
    woo.. in theory it should be fliped and have a different color.
     
  20. n1njadragon

    n1njadragon Void-Bound Voyager

    I've thought about the second method, but the issue I have is its server compatibility. Will it carry over to a server that doesn't have a mod pack with this info? Well, guess I'll just give it a go.
    Any idea how to flip it off the y axis instead of the x axis?
     
    Last edited: Jun 13, 2014

Share This Page