Tutorial How to make and use custom Lua function

Discussion in 'Starbound Modding' started by Riuny, Aug 29, 2015.

  1. Riuny

    Riuny Big Damn Hero

    First of all, this instruction might need some basic knowledge about computer programming.
    But, I'll try to explain this as simple as I can.

    1.What is 'custom Lua function' ?
    It's pretty self-explanatory.
    It is a Lua function added by programmer, which does not exist as default Lua function.
    If you ever have opened any existing Lua file in starbound asset folder, you can find bunch of different custom Lua functions made by Starbound developers.

    EX)
    Code:
    function activate()
        tech.setParentDirectives("?multiply=00000000")
        tech.setToolUsageSuppressed(true)
        self.active = true
    end

    2.Why do I need custom functions?
    Let's say that you have made something like this.
    Code:
    if case == 1 then
        self.timer = 1.0
        self.State = 1
        tech.setAnimationState(animtype, anim1)
        world.spawnProjectile("bullet1",{mcontroller.position()[1]+self.xOffset*3, mcontroller.position()[2]}, entity.id(),{self.xOffset,0},false,{power = self.weaponDamage*1.0})
    
      
    elseif case == 2 then
        self.timer = 2.0
        self.State = 2
        tech.setAnimationState(animtype, anim2)
        world.spawnProjectile("bullet2",{mcontroller.position()[1]+self.xOffset*3, mcontroller.position()[2]}, entity.id(),{self.xOffset,0},false,{power = self.weaponDamage*0.5})
    
      
    elseif case == 3 then
        self.timer = 3.0
        self.State = 3
        tech.setAnimationState(animtype, anim3)
        world.spawnProjectile("bullet3",{mcontroller.position()[1]+self.xOffset*3, mcontroller.position()[2]}, entity.id(),{self.xOffset,0},false,{power = self.weaponDamage*0.2})
    
      
    elseif case == 4 then
        self.DAStimer = 4.0
        self.DASattackState = 4
        tech.setAnimationState(animtype, anim4)
        world.spawnProjectile("bullet4",{mcontroller.position()[1]+self.xOffset*3, mcontroller.position()[2]}, entity.id(),{self.xOffset,0},false,{power = self.weaponDamage*0.7})
    end

    This is a strip of code that sets timer, sets animation state, play animation and spawns projectile at a same time. All of these actions depend on the number value of 'case'. For example, if 'case' is '1' then this code sets timer to 1.0 sec, sets animation state to '1', play animation named 'anim1' and spawns projectile named 'bullet1'.

    Currently, this code has 4 different cases. But, what if you have to make 50 different cases? or even more? What are you going to do?

    Of course, you can just spam the old "copy & paste" trick. However, that is really inefficient way which will result in ridiculously lengthy code. So how are we going to make this a bit simpler and shorter? This is when the custom function kicks in.

    3.How do I make one?
    Now that we realized why do we need custom function, all we have to do is to make one. I'm going to use previous example.

    If you see each case of the code, you can find structural resemblance in them.


    1. set self.timer
    2. set self.State
    3. play animation
    4. spawn projectile

    These are the common things that every case has. So we're going to make this series of actions into a custom function. We're going to name this custom function as "action".

    Code:
    function action()
    end

    We've just made a frame of custom function, but we didn't put anything in it. For this custom function to work properly, it needs initial information. We're going to set following list as initial information

    1. time value that goes into self.timer
    2. state number that goes into self.State
    3. type of animation
    4. name of animation
    5. name of projectile
    6. damage multiplier of projectile


    Now that we decided what it needs, it is time for us to put this initial information into the function.

    Code:
    function action(timer, state, animtype, anim, projectile, multiplier)
    end
    Values can be named freely. You can just put them as a,b,c,d,e,f or anything you want.
    We've just told the computer that it needs 6 things to run this function properly. The next step is to tell the computer what to do with this information.

    Code:
    function action(timer, state, animtype, anim, projectile, multiplier)
        self.DAStimer = timer
        self.DASattackState = state
        tech.setAnimationState(animtype, anim)
        world.spawnProjectile(projectile,{mcontroller.position()[1]+self.xOffset*3, mcontroller.position()[2]}, entity.id(),{self.xOffset,0},false,{power = self.weaponDamage*multiplier})
    end

    Now this function will do following series of actions whenever it gets called.

    1. set self.timer
    2. set self.State
    3. play animation
    4. spawn projectile


    4.How do I use it?
    We made custom function. It is time to see it in action.
    By using custom function that we've just made, the original example code can be written like this.

    Code:
    if case == 1 then
            action(1.0,1,"animtype","anim1","bullet1",1.0)
        elseif case == 2 then
            action(2.0,2,"animtype","anim2","bullet2",0.5)
        elseif case == 3 then
            action(3.0,3,"animtype","anim3","bullet3",0.2)
        elseif case == 4 then
            action(4.0,4,"animtype","anim4","bullet4",0.7)
        end
    Look how simpler and shorter it is. All you have to do is type in 6 basic information, then computer does everything else for you. By using custom function, you can make your code a lot cleaner, shorter and simpler.

    That is all for this tutorial. If you have anything to ask about it, feel free to leave your comment in this thread. I'm not a professional programmer but I will answer your questions as best as I can.
     

Share This Page