Tutorial HOW TO: Custom techs!

Discussion in 'Starbound Modding' started by SuperMandrew, Dec 11, 2013.

  1. SuperMandrew

    SuperMandrew Cosmic Narwhal


    EDIT: THIS TUTORIAL IS OUTDATED. The main ideas are the same, but the way techs are added in the game is slightly different. Please look at how either the current techs in game are implemented, or my 2D Fighter mod which can also be used as a reference. I'll try to update this when I get some free time.

    Hey all,

    As you may have seen from my previous posts, I love techs, and modding them!

    So today I'll walk you through the basics of making your own tech. To start, let's do something basic, like adding the ability to dash while in the morph ball. Also, let's put a bubble around the morph ball, because why not. :)

    What you will need:
    - A text editor, preferably one with multiple programming language support (I use Notepad++)
    - Basic programming knowledge helps, but is not required
    - Patience, as you'll likely crash the game with no error message at some point
    - Creative mind - for creating creative techs! :)

    To begin, navigate to the assets folder of the Starbound directory, then the tech folder. Create your own folder, I'm calling it bubbleball.

    Now, go to the morphball folder and copy all the files over to your bubbleball folder. Next, rename these files morphball.animation, morphball.lua, morphball.recipe, morphball.tech, and morphball.techitem to bubbleball.animation, bubbleball.lua, etc respectively - keep ball.frames and ball.png the same. Now navigate to the booster folder in the tech folder, and copy bubble.png also over to your bubbleball folder.


    Now to begin creating the tech.
    First open bubbleball.techitem in Notepad++. You'll see some parameters in there, and this is just for the actual description of the tech itself that you'll see in game.
    Change the item name from morphballTech to bubbleballTech, leave the rarity and inventoryIcon alone for now, and change the description to something with a lame pun, like "Unbelievabubble!" and change the short description to "Bubbleball". Leave inspection kind, and finally change the tech module to "bubbleball.tech" - NOTE: this is calling the tech file which has parameters that will be used via the code for the tech, so this is important to have no spelling errors.

    Save this file and close it! Step one done, not so bad right?


    Moving on...
    Open up bubbleball.tech next. Whoa, this looks intimidating. But don't worry, we'll be moving nice and slow. Okay, let's look at some important lines and describe what they do:
    - "script" : this points to a LUA file that has code detailing how the tech works and interacts with the game
    - "actions" : these are actions defined to be used in the LUA file - when we look at the LUA file later, we'll be seeing this actions in more detail. Essentially, you'll want an action for every time the tech will need to do something different, such as shooting a gun or activating a special mode
    - "animator" : this points to the .animation file that outlines how the graphics will interact with the tech, like the bubble we'll be adding

    Okay, after that you see some custom movement parameters- I'm not 100% sure, but I'd be willing to bet that these are hard-coded parameters. What do I mean by that? Well, if you look lower in the file you'll eventually see "energyCostPerSecond" : 35. This is a custom parameter- you can change the name to "SuperMandrewRocks" : 35, and as long as you use that same parameter name in the LUA file later, it will work properly. However, these hard-coded parameters above are important for their names. If you changed "jumpSpeed" to "bumpSpeed", it would almost certainly not work (or at least the jump speed would not change).

    So because we want to add a dash in to our ball form, go ahead and find the dash tech folder and open up dash.tech. We'll need to be adding the custom parameters from that, so copy everything from "maximumDoubleTapTime" from that file on down (except the closing bracket). BEFORE PASTING IT, scroll down to the bottom of bubbleball.tech and add a comma after "bomb", outside the quotes. Start a new line and paste all our dash parameters in there. Before closing this file, look back at dash.tech. See those two actions? We need those in our actions too, so go ahead and add a comma after "morphballBomb" and append those other two actions. Also.. add a "t" in "dashRight" - I'm not sure why that's not there. So we should have five actions now! Well done, we can close this file.

    Here's what my file looks like, so you can double check:


    Okay, now that we've finished editing bubbleball.tech, let's move on to bubbleball.animation. Opening it up, you'll see three major sections as of now: animatedParts, parts, and particleEmitters. Since we want to add a bubble to our character, let's see if we can have two images being displayed at once.

    First, in the animated parts section, in stateTypes, create a new entry after morphball (be sure to add the comma after the closing bracket in morphball!), and create a section called "bubble". Make it similar to morphball, but instead of having states only have default, instead make states only have two empty states: off and on (not forgetting the comma after off either!). In the parts section, you'll see a first "morphball" - add a comma after the closing bracket and start a new line. Call it "bubble", and start a new bracket. Then add "partStates": { followed by "bubble" : { Then add another line: "on" : {, and then "properties" : {, then finally two more lines, "centered" : true and "image" : "bubble.png".

    Finally, since we'll be adding the ability to dash, let's make it so that bubbles appear when we dash! If you open up the booster folder for techs and then bubbleboost.animation, you'll see a similarly formatted .animation file. Integrate both parts of these into our own bubbleball.animation file respectively (also change the word persistentSound to immediateSound) - you should have modified "animatedParts" and "particleEmitters" right here. This is kind of complicated to explain, so here's my final bubbleball.animation file for you to compare with:



    Now we open.. bubbleball.lua. Dun-dun-dun!! This file in particular can be very daunting at first, as there's a lot of code going on, and it's not in the same format as the previous files we've looked at. Don't worry, we're not editing much yet. Right now, forget about adding the dash move, let's just get the bubble showing when we go into morph ball mode.

    Scroll down until you find this line in the function update:
    if not data.active and args.actions["morphballActivate"] then
    ^ this line essentially say this: if we're not in ball form and we received the command to turn into ball, do the following (lines of code after)

    Inside that block (after the then and indented properly), add one line:
    tech.setAnimationState("bubble", "on")
    ^ this says, hey look at our tech, and we want to change the animation state. What state do we want to change? "bubble", and we want to switch it to "on".

    Scrolling down further you'll find this line:
    if not world.rectCollision(ballDeactivateCollisionTest) then
    ^ this line is checking to make sure if we deactivate, we don't get stuck somewhere in the game. After this line, add this:
    tech.setAnimationState("bubble", "off")
    ^ this line says essentially the same as our previously added line, but that we want to change the state to off.

    Okay! Save the file and close it (for now, we'll come back).

    Open up bubbleball.recipe, and change this line:
    "input" : [ ],
    "input" : [
    { "item" : "torch", "count" : 1 }

    Also add "plain" and "all" to the groups section, as seen below.

    This allows us to craft our tech easily with one torch, for testing purposes. :)


    Finally.. navigate back to the Starbound/assets/ folder, and open up player.config. Scroll down until you see:
    { "item" : "copperarmorhead" },
    Copy that line, and paste it in a new line right next to it. Change it from "copperarmorhead" to "bubbleballTech". This allows our character to know how to craft the tech initially without having to learn anything.

    Okay! Test it out, and you should have a working morphball that shows a bubble around it! If not, go back and check your files against mine, and if you're having problems, post here.

    On to the next step: adding the dash. Open up dash.lua - at the top you'll see function init(). Copy everything inside it, and post it within function init in bubbleball.lua.


    Modifying the input:

    Go ahead and copy everything from the input function in dash.lua, except for the line "return nil" (and end). This is our way of reading the double tap to dash. However, in bubbleball.lua, we need to be careful that we don't always hit a return statement before checking for other inputs (as a return statement will exit the function immediately). So, after data.primaryFireLast = args.moves["primaryFire"], add this check:

    if move ~= nil then
    return move

    This says that if a bomb has been placed, then return it. Otherwise, keep going.

    Since we only want to dash while in ball form, add an if statement:

    if data.active then


    Inside this if statement, post your code from the input from dash.lua. Finally, after the last end, add one more line "return move" (which could also be return nil).

    Here's what my input file looks like:


    Now the update function. Find this line:
    world.spawnProjectile(ballBombProjectile, tech.position(), tech.parentEntityId())
    The next line should be "end". Copy the update function from dash.lua and paste it here, and change these lines:

    tech.setAnimationState("dashing", "on") --> from "dashing" to "boosting"
    tech.setParticleEmitterActive("dashParticles", true) --> from "dashParticles" to "boostParticles"

    Also change the lines just a few below them which are very similar (except they turn the graphics off).

    At the end, we want to see if we dashed or not. Looking at the code, how do we know this? Well, a variable called usedEnergy is only used by the dash in this function, and it's initialized to 0. So, if that value is still 0, we haven't dashed and don't need to drain any extra energy. We accomplish the energy drain like this:

    if usedEnergy ~= 0 then
    return usedEnergy

    After that line, just leave the rest of the lines, which should be:

    return energyCostPerSecond * args.dt
    return 0




    Okay, and we're done! Boot up the game, and try out your new dashing bubble ball! Woo! If you have any questions, feel free to post them here. I'll attach my final files for comparisons at the end too. Remember, in order to test the morphball, it requires args.moves["special"], which is the F key!

    Now that you've finished, I want to see some kickass techs appearing! Show me a morph ball that leaves a trail of damaging fire, or an aura that heals everyone near you, or the phaselocking skill from Borderlands 2 :)

    EDIT: Okay I did the fire one for you..


    Pro-tip: You can even air-dash in your new bubble ball!

    Alternative download if attachment isn't working: http://www31.zippyshare.com/v/46090745/file.html

    Attached Files:

    Last edited: Mar 12, 2014
  2. Dr.Narwhal

    Dr.Narwhal Big Damn Hero

    Awesome tutorial!
    SuperMandrew likes this.
  3. SuperMandrew

    SuperMandrew Cosmic Narwhal

    Thanks much! Took awhile, but I hope it can help people! :)
  4. LadyKianna

    LadyKianna Big Damn Hero

    Thank you for this! Maybe I'll add in some tech myself. :3
    SuperMandrew likes this.
  5. Ceetee

    Ceetee Void-Bound Voyager

    Thank you very much! Im currently making a mod revolving around player created (but less efficeint) tech, and this will be super useful. You are a huge help!
    Bonoshman and SuperMandrew like this.
  6. SuperMandrew

    SuperMandrew Cosmic Narwhal

    Glad to be of assistance. If you have any questions, I'll do my best to try and answer them! :)
  7. Jake.n

    Jake.n Tentacle Wrangler

    so how would i make one that would make you stand still but up your deffence, so you wouldn't use it while you moved. or even uped your deffence and you could move?
  8. Pedguin

    Pedguin Big Damn Hero

    This attachment cannot be shown at this time. Please try back later. :(
  9. SuperMandrew

    SuperMandrew Cosmic Narwhal

    Last edited: Dec 12, 2013
  10. aMannus

    aMannus Space Kumquat

    Thank you very much for writing this out. I'll be trying to make my own flight tech fairly soon, and it's very handy to have a guide like this around. It doesn't help my knowledge with LUA is limited, although looking at the current tech, the code doesn't seem crazy complicated. Pretty sure this statement will bite me in the ass when I try to work with it though..
    Bonoshman and SuperMandrew like this.
  11. AVtime

    AVtime Void-Bound Voyager

    Awesome guide. Very clear, informative, and clever. Thanks much!
    SuperMandrew likes this.
  12. Mortair Cookie

    Mortair Cookie Void-Bound Voyager

    It's a great guide and it helped me a lot but... I have a question. I tried to modify the morphball files so that they'd not give me any mobility but I'd be able to drop something when I press F, and pressing F would take some energy. With my limited understanding of this code and Lua, I wasn't really able to figure out how to make that happen. I would be so very grateful if you could explain how can I make that happen. n.n
  13. SuperMandrew

    SuperMandrew Cosmic Narwhal

    How far did you get? Does the game crash right now with your added code, or does F just turn you from human to morphball and back, and ignore your code about dropping something?

    I'd work first on getting the dropping part to work- the mobility reduction can be done later. The problem I'm imagining right now is that F would be used to both transform and drop something, but then.. how would you transform out? Instead of that, how about using the G key to drop something?

    Check out these two lines in the input function:

    elseif data.active and args.moves["primaryFire"] and not data.primaryFireLast then
    elseif data.active and args.moves["special"]==2 and not data.primaryFireLast then
    data.primaryFireLast = args.moves["primaryFire"]
    data.primaryFireLast = args.moves["special"] == 2
    G should now drop bombs while in morphball mode instead of clicking.
    Last edited: Dec 14, 2013
  14. Mortair Cookie

    Mortair Cookie Void-Bound Voyager

    Sadly I'm not very far, I have what I want to drop and the visual effects ready, but I was unable to change the Lua at all. I apologise about the misunderstandment though, I meant I wanted there to be only a single action, and that would be dropping the item, it would be a one time thing like a dash and there wouldn't be anything to activate/deactivate.

    So I made something like this and I'm testing it now.
      if args.moves["special"] == 1 and not data.specialLast then
        move = "morphballBomb"
        return nil
    Though I am wondering if something like this would be easier.

      if args.moves["special"] == 1 and not data.specialLast then
         world.spawnProjectile(ballBombProjectile, tech.position(), tech.parentEntityId())
        return nil
    Last edited: Dec 14, 2013
  15. SuperMandrew

    SuperMandrew Cosmic Narwhal

    Really not sure, but the standards seem to be simply handle the input as best as you can in the input section: as in, as soon as you get an input, figure out what kind of action it's going to send to the update function, and in the update function do an if statement based on what the actions possible that you want to handle.

    In this case, in your input function you probably want a simple:

    if args.moves["special"] == 1 then
      return "morphballBomb"
    return nil
    And in your update function just do an if args.actions["morphballBomb"] and do what you want inside that.
  16. One!

    One! Scruffy Nerf-Herder

    Im sorry, but can u help me, i trying to modding but this is so hard for me.
    And my first question: where i can find "Dash" animation? I wanna change color of this tech.
  17. Eathed

    Eathed Pangalactic Porcupine

  18. One!

    One! Scruffy Nerf-Herder

    Thx alot.
  19. Nekoyoubi

    Nekoyoubi Subatomic Cosmonaut

    Hey, great tutorial! I started working on a tech last night, and I was hopeful that you could steer me in the right direction on what I would think would be a pretty simple thing to do, but the world of modding never ceases to amaze me. I seem to be having a lot of trouble getting access to the player from the tech and I was wondering if you might be able to help me out with that if you get a second. I'm simply trying to affect the player's health and I con't seem to do anything with "entity.heal()" as I've seen in some other files. Is there a reference back to the player from the tech that I can use, or possibly a global way to get to the player's "entity" by chance? Thanks much in advance!
  20. Bonoshman

    Bonoshman Big Damn Hero

    Thanks for the tutorial! I'm using this for my 'rare boss drops' mod, and I'm trying to draw the player inside a UFO glass. I have no idea how to approach this, could you give some advice?
    (Fairly noobish modder, so if it's obvious, sorry for wasting your time.)

Share This Page