Tutorial Creating a ship design

Discussion in 'Starbound Modding' started by Kayuko, Jun 3, 2015.

  1. Kayuko

    Kayuko Oxygen Tank

    So, since a very specific person was too lazy to study the vanilla assets enough I decided I might put that up here, as well.

    It'll be a very short explanation on how to create custom ship designs and how they work, this is not much work on the explanation-side since it's mostly about having the art of the design in the first place.

    As always, you need:
    1. Notepad++, Sublime Text 2 or any other text editor (except word, wordpad and such)
    2. Unpacked assets (there's a link on how to do that in the stickied mod-guides thread)
    3. Gimp and / or paint (I prefer using both, paint for plain blockKey editing and gimp for the layering option)

    Code:
    {
       "blockKey" : [
        {
          "value" : [255, 255, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : false
        },
    
        {
          "value" : [0, 0, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true
        },
    
        {
          "value" : [255, 0, 0, 255],
          "foregroundBlock" : true,
          "backgroundBlock" : true
        },
    
        {
          "value" : [0, 255, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipwall",
          "flags" : [ "shipLockerPosition" ],
          "object" : "humanshiplocker",
          "objectParameters" : {
            "treasurePools" : [ "humanStarterTreasure" ],
            "level" : 0.5,
            "unbreakable" : true
          },
          "objectResidual" : true
        },
     
        {
          "value" : [0, 128, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipwall",
          "object" : "humanshiplockerTier0",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [142, 255, 142, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipwall",
          "object" : "humantechstation",
          "objectParameters" : {
            "unbreakable" : true
          },
          "objectResidual" : true
        },
    
        {
          "value" : [0, 21, 128, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipwall",
          "object" : "researchstation",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [255, 87, 81, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "brokenhumanfuelhatch",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
     
        {
          "value" : [128, 44, 41, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "brokenhumanfuelhatchTier0",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [255, 90, 90, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "humanfuelhatch",
          "objectParameters" : {
            "unbreakable" : true
          },
          "objectResidual" : true
        },
    
        {
          "value" : [255, 255, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "apexshiplight",
          "objectResidual" : true
        },
     
        {
          "value" : [191, 191, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "apexshiplightBroken",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
     
        {
          "value" : [128, 128, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "apexshiplight",
          "objectParameters" : {
            "unbreakable" : true,
            "defaultLightState" : false
          }
        },
    
        {
          "value" : [255, 102, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : false,
          "object" : "humanshipdoor",
          "objectResidual" : true
        },
     
        {
          "value" : [128, 51, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : false,
          "object" : "humanshipdoorBroken",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [174, 137, 81, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "shipengine",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [156, 0, 255, 255],
          "anchor" : true,
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "humanteleporter",
          "flags" : [ "playerSpawn" ],
          "objectParameters" : {
            "unbreakable" : true
          }
        },
     
        {
          "value" : [79, 0, 128, 255],
          "anchor" : true,
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "humanteleporterTier0",
          "flags" : [ "playerSpawn" ],
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [167, 167, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "boosterflamehuman",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [168, 168, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "boosterflamehuman2",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [180, 180, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "boosterflamehuman3",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [166, 166, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "boosterflame",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [100, 100, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "bigboosterflameavian",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [200, 200, 200, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "bigboosterflamehuman",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [168, 168, 168, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "smallboosterflame",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [190, 190, 190, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "smallboosterflamehuman2",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [0, 255, 255, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "humancaptainschair",
          "objectDirection" : "right",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [122, 122, 122, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "invisiblelight",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
     
        {
          "value" : [255, 232, 128, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "object" : "invisiblesparker",
          "objectParameters" : {
            "unbreakable" : true
          }
        },
    
        {
          "value" : [255, 255, 144],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipwall"
        },
    
        {
          "value" : [255, 117, 144],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails"
        },
    
        {
          "value" : [255, 117, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipsupport"
        },
    
        {
          "value" : [255, 255, 220],
          "foregroundBlock" : true,
          "backgroundBlock" : false,
          "foregroundMat" : "hazard",
          "foregroundResidual" : true
        },
    
        {
          "value" : [255, 200, 220],
          "foregroundBlock" : true,
          "backgroundBlock" : true,
          "foregroundMat" : "hazard",
          "foregroundResidual" : true,
          "backgroundMat" : "apexshipdetails"
        }
      ]
    }
    
    This is the blockKey.config as it is found in "/ships/human"
    We will use this as a reference a lot later on.

    Code:
    {
      "config" : {
        "shipUpgrades" : {
          "capabilities" : [],
          "maxFuel" : 1000
        }
      },
    
      "backgroundOverlays" : [
        {
          "image" : "humanT1.png",
          "position" : [8, 14],
          "fullbright" : true
        },
        {
          "image" : "humanT1lit.png",
          "position" : [8, 14]
        }
      ],
    
      "blockKey" : "blockKey.config:blockKey",
      "blockImage" : "humanT0blocks.png"
    }
    
    This is the humant0.structure file.
    That's used to link the pngs (follow) to the blockKey.config and order / resize them properly.

    BackgroundOverlays is the thing you should turn your attention on for now.
    It basically says:

    Print the image "humanT1.png" first (because it's index 0 in the array) and light it up ("fullbright" : true)
    Next, print "humanT1lit.png" above the background image.

    humant8.png

    humant8lit.png

    There is a reason why "lit" is not the picture with the fullbright option:
    Since it overlays the humanT1.png file, which is in fullbright, and the file itself ("humanT1lit.png") is NOT drawn in 100% opacity (I think it's about 20%) you will gain a shinethrough effect where-ever the "humanT1lit.png" is non-solid (aka. it's opacity is low).
    This will passively light your ship up.

    humant8blocks.png

    This is where your blocks are distributed, the humant8blocks.png.
    As you saw earlier, that's directly linked to "blockKey.config:blockKey" (which does actually just mean the blockKey array in the blockKey.config file).
    1 Pixel in this map is 1 Block in the final ship, unlike the ship design itself, which is using actual sizes. (Want a 6x6 block ingame? draw a 6x6 block in the humant8.png).

    And that's why I said it's a short thing, because basically we're already setted here.
    Here are a few more additions:

    Code:
    {
          "value" : [0, 255, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipwall",
          "flags" : [ "shipLockerPosition" ],
          "object" : "humanshiplocker",
          "objectParameters" : {
            "treasurePools" : [ "humanStarterTreasure" ],
            "level" : 0.5,
            "unbreakable" : true
          },
          "objectResidual" : true
        }
    
    value = RGBA (Red, Green, Blue, Alpha), the color that'll be recognized as the specified block
    foregroundBlock = Boolean value telling the blockKey.config if there is a block in the foreground
    backgroundBlock = Boolean value telling the blockKey.config if there is a block in the background
    backgroundMat = Materialname (as found in the /tiles/materials folder) of the block that's used in the background
    foregroundMat = Matieralname (as found in the /files/materials folder) of the block that's used in the foreground
    flags = I don't even know why this is set, might have something to do with later development.
    object = Objectname as found in the /objects/ folder
    objectParameters = Special settings dependent on the type of the object (in this case it's a container)
    treasurePools = Which items are found in the locker (check /treasure/ for more infos)?
    level = That's where I'm not sure, either it's refering to the zLevel (depth) or the level of the treasure (starter weapon, for example)
    unbreakable = Boolean, telling the blockKey.config that this object can / can not be destroyed via normal means
    objectResidual = Boolean telling the blockKey whatever it's telling the blockKey.config.

    Code:
      {
          "value" : [128, 128, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "apexshiplight",
          "objectParameters" : {
            "unbreakable" : true,
            "defaultLightState" : false
          }
        }
    
    Those are the lights.
    I'm pointing them out for one reason: defaultLightState.
    If you first enter your ship your lights are broken, leaving the ship as unlit as possible.
    There is, however, a flickering light:

    Code:
    {
          "value" : [191, 191, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "apexshiplightBroken",
          "objectParameters" : {
            "unbreakable" : true
          }
        }
    
    and the counterpart that's used once the lights are lit:

    Code:
        {
          "value" : [255, 255, 0, 255],
          "foregroundBlock" : false,
          "backgroundBlock" : true,
          "backgroundMat" : "apexshipdetails",
          "object" : "apexshiplight",
          "objectResidual" : true
        }
    
    Then, there's another thing that's pretty important:

    Code:
    {
      "config" : {
        "shipUpgrades" : {
          "capabilities" : ["teleport", "planetTravel"],
          "maxFuel" : 1000
        }
      }
    
    Basically the capabilities tell the shipworld if you are authorized to use certain features, in this case teleportation (to the planet) and planetary travel.
    This is also where the maximum amount of fuel you can store in your hatch is set.

    "capabilities" : ["teleport", "planetTravel", "systemTravel"]

    This is a level 8 ships capabilities section. Everything that can be activated is activated, so you really don't have much to worry about here.

    All this pretty obvious knowledge should get you (yes you, specific person I mentioned in the beginning) going on your ship.

    NOTE: If you plan on patching the blockKey.config of an existing ship: THIS IS NOT POSSIBLE AT THE MOMENT! Don't even try it until it's fixed!

    [​IMG]
     
  2. Inf_Wolf14

    Inf_Wolf14 Parsec Taste Tester

    Considering the structure and process for creating the .blockkeys, wouldn't this also kinda fall under a dungeon tutorial also?

    I find the two very similar, excluding of course how the whole ship tier progression works.

    I mean defining the RGB pixel values is kind if a pinnacle for both those topics. :3
    :3
     
  3. Kayuko

    Kayuko Oxygen Tank

    Yes and no, that's actually something that shouldn't require a tutorial in the first place.
    But the difference between the blockKey config and the .dungeon files are rather big.

    For comparisation, that's how a .dungeon line looks like:

    "brush" : [["clear"], ["back", "<blockname>"], ["front", "<blockname">]]

    I know it >>should<< be obvious if you read the dungeon tutorial, but it seems like this wasn't quite sufficient for said person. :p
     
    lazarus78, The | Suit and Inf_Wolf14 like this.
  4. Hyko

    Hyko Astral Cartographer

    I get the feeling I may be that lazy person (to be fully honest I have no clue how to even get the vanilla assets in the first place), that being said, thanks a ton for putting this up, it helps a lot!
     
    Kayuko likes this.
  5. Kayuko

    Kayuko Oxygen Tank

    Nah, the lazy person is actually a Torchic. x:
    If you're modding you should get the vanilla assets however, give this thread a check:

    Click me, nyaaa~
     
    UnknownX and Hyko like this.
  6. greenRAM

    greenRAM Giant Laser Beams

    I've been playing around with my really big ship design where there's going to be some digging between ship tiers. Is there any easy way to prevent the game from replacing dug up materiel between tiers?

    I'll try adding replacing blocks with background only materiel between each tier if there isn't an easier way.
     
  7. Kayuko

    Kayuko Oxygen Tank

    The only way you could achieve not replacing blocks between ship tiers would probably be removing thing from the tilemap.
    That's nothing that'd work individually tho, so no, there's not really a viable way to do so yet. ._.
     
  8. Mackinz

    Mackinz The Waste of Time

    I know you are not naming names, but I think I know who you are referring to in the first sentence of your tutorial. :fireball:
     
  9. Kayuko

    Kayuko Oxygen Tank

    Hihihi x'3
    I have no clue what you're talking about. :'D
     
    Inf_Wolf14 likes this.
  10. graycatgrayhat

    graycatgrayhat Pangalactic Porcupine

    Thank you for the info, well going about my work I notice the lit images and wondered how they worked.
     
    Kayuko likes this.
  11. lazarus78

    lazarus78 The Waste of Time

    *waits for Kayuko to post so I don't get ninjad again*


    Basically you have 2 images.

    The first one is the base layer, and is set to "fullbright", meaning all of it is 100% visible. The "lit" image, contrary to its labeling, is used to mask (cover) areas where you DONT want fully illuminated parts. So the uncovered parts of the first layer appear to glow. Basically akin to the batman spotlight. Its bright where there isn't anything covering. So you can use this to make glowy lines like the Hylotl ship has.


    For ships, they make most of the "lit" image to be partly transparent so that some of the brightness comes through so you can see your ship shape instead of it being pitch black, while the rooms of the ships are not transparent so they stay dark.
     
    Last edited: Jun 10, 2015
  12. graycatgrayhat

    graycatgrayhat Pangalactic Porcupine

    I am attempting to apply the "lit" idea in function to the Logistics Frigate Reborn and failed at first but should with some practice be able to with ease. In my case to light the ship hull using invisible lights causes major lag or spotty lighting if I reduce the amount of them so using "lit" overlays might be the best option.
     
  13. lazarus78

    lazarus78 The Waste of Time

    Indeed it would be better. Back in Koala before the "lit" layer, they used lights.

    Just poke around the existing ships and see how they do it. Its rather simple.

    Code:
    "backgroundOverlays" : [
        {
          "image" : "hylotlT8.png",
          "position" : [14, 36],
          "fullbright" : true
        },
        {
          "image" : "hylotlT8lit.png",
          "position" : [14, 36]
        }
      ],
    
     
    Kayuko likes this.
  14. ravidor.pro124

    ravidor.pro124 Scruffy Nerf-Herder

    thnks very much!
    i messed up with my ship cus ive installd a mod and the ship dident change
    ive deleted the ship files and it works but the ship reboot and all that yadda yadda dident exist
    now i can check the capabilities names to modify the things back on thks very much
     
  15. Panthera Pardus

    Panthera Pardus Subatomic Cosmonaut

    Hello Together,

    and Thank You Kayuko for this little Tutorial. It showed me that it is much easier to design an own ship, than I thought.
    By the Way, I don't think that this Tutorial is unnecessary. Because, People like Me (inexperienced in modding and with no interest in creating a dungeon) would search for a Tutorial like this. And not for a Dungeon Tutorial, but this is just my opinion.

    Kayuko don't become mad at me, but I also have a little suggestion to make. Maybe it would be a good idea to mention that the "...bloks.png" file is also responsible for the inner ship boundaries. I mean the Boundary between the playable and the non-playable Area of the ship. I am writing this,because my little testwork in the "...blocks.png" file didn't work. And i wasted some hours, while I was searching for ship boundary values. A whole lot of files later, I realised that my work and thoughts were correct. I simply used the wrong file. The first human ship on which you can inspect the cockpit, is the Tier2 ship, and not the Tier1 ship. :facepalm: (for Me)

    Therefore, Kayuko, thank you again for this Tutorial. Have a nice Day.

    Joy and Happiness
    Panthera Pardus
     
    kittentamer likes this.
  16. zubarus

    zubarus Star Wrangler

    hi ho
    old but i hope..

    can one me help ?
    i have a costum ship .. so how i make the right "...blocks.png" ?
    i mean the position and all...
     
  17. lazarus78

    lazarus78 The Waste of Time

    All information in this thread is applicable. Ships have basically never changed since implementation.
     
  18. zubarus

    zubarus Star Wrangler

    .. and so say me how to make easy "..block.png"
    ach drecks englisch...

    so i have a 1000xs 300 p ship..
    waht size have the "block.png" ?
    and waht say the positon exacly?
     
  19. lazarus78

    lazarus78 The Waste of Time

    Have you attempted to ltinker with the existing ships to see how they actually work? Thaty alone would answer 99% of your questions.

    But anyway. One pixel is one in game block. The positioning is entirly based on however you want, but generally, just take your ship image resolution and divide it by 8.
     
    bk3k likes this.
  20. zubarus

    zubarus Star Wrangler

    thx this was waht i needet.. ( just take your ship image resolution and divide it by 8.)
     

Share This Page