Starbound Modding Howto ~ Chapter One: A Simple Decoration

An up-to-date primer by Kawa.

A short introduction

Starbound modding involves a few basic tools and concepts. First of all, there are basically three different types of file for you to worry about: JSON data, Lua scripts, and PNG images. Second, while all three can be replaced, JSON can also be patched. Note that although Lua scripts always have a .lua extension, and PNG files are likewise always .png, JSON files have various different extensions which usually change how the game uses them.

I strongly suggest, now that I mention file extensions, that if you use Windows, you make sure "Hide extensions for known file types" is disabled. It's a stupid default setting to have and disabling it will make your life so much easier. Incidentally, I use Unix path notation throughout this document, so the slashes go forward (/) instead of back (\). This is mostly because any file references in configs and such will be in Unix notation.

Starbound loads its data from a few different sources, being pakfiles and directories. They're effectively identical as far as the game's concerned, and the base assets are in fact in a pakfile. By default, the game loads from the assets and mods.pak file and every valid directory, which boils down to assets/packed.pak, everything in assets/user and basically everything in mods, such as mods/somemod.pak, mods/unpackedmod, etc, with each file that has the same relative path as an earlier file replacing said file.

Importantly, the file system is abstracted away. When something in the game references objects/bonus/devstatuegeorge/devstatuegeorge.object, what's returned can theoretically come from any loaded asset source, but by default it'll be the copy found in assets/packed.pak.

When loading a JSON data file, any file with the same relative path but with .patch appended to it gets applied to the base file, in the same order as the asset sources. Thus, if a mod has a file objects/bonus/devstatuegeorge/devstatuegeorge.object.patch, that will be applied to devstatuegeorge.object before it is used by the game. If a mod has a file objects/bonus/devstatuegeorge/devstatuegeorge.object without the .patch extension, that'll be used instead of the original. The same replacement rule applies to the other two file types.

For more about JSON and JSON Patch, please check out my Labs.

Down to brass tacks

First thing you should do is unpack the base assets. If you can handle a command line, you can use one to navigate to the Starbound directory and type win32\asset_unpacker assets\packed.pak unpacked ...assuming you run Windows. The win64 directory has no unpacker in it, but osx and linux do so go nuts. Now, unpacking all that data takes quite a while and the unpacker is silent until it's finished or something goes wrong so you might as well minimize that window and continue with the rest of this.

Second thing you should do is set up a mod folder. Find Starbound/mods and make a new directory in it. What name this directory has isn't very important, as long as it's clear. I'll assume it's tutorial.

As it is, Starbound will dutifully try to load anything found in this new folder, but if you were to check storage/starbound.log, you'd find mention of an "unnamed asset source". This is correct behavior. If you'd rather have your asset named, skip ahead to the chapter on metadata.

Now, a nice starting point for learning how to make new content for Starbound would be a bit of decoration. Like that statue of GeorgeV I mentioned a couple times before.

Since actually drawing the damn thing goes a little out of scope for this tutorial, I'll just go over some basic rules and provide you with some artwork I'd whipped up earlier:

So. First thing you do to add a new object is go to your mod's directory and make an objects directory in there, and another in there to hold your new object. Usually, the directory and object have the same name. Let's go with tutorialstatue. So call your new directory that.

The easiest way to do this stuff is by example, so let's cheat a little. Assuming the unpacking process has finished or is far enough along, go to unpacked/objects/bonus/devstatuegeorge and copy all four files in it into mods/tutorial/objects/tutorialstatue. Delete devstatuegeorge.png (cackling optional) and devstatuegeorge.frames (because we'll get into that mess later and it's really not needed now), and rename devstatuegeorge.object to tutorialstatue.object and devstatuegeorgeicon.png to just icon.png.

As I said, making the new artwork is somewhat out of scope so here's the promised art I whipped up earlier:

<ChlorideCul> Kawa, I'm all for a guide, if you can keep tentacle stuff out of it :P
...Oh okay, spoilsport.

Just right-click and save that into the tutorialstatue directory. *grumble*

Editing the object file, considering how much what we just copied matches what we'll produce, is easy enough. That's a good rule when stealing basing new content on old; find the thing(s) that best matches what you want to make and build from that. The other rule is to not trust old mods, which may very well use outdated values and such. And so, here's the full content of devstatuegeorge tutorialstatue.object, with comments added by me:

{
  "objectName" : "devstatuegeorge",                // This is important. It should be absolutely unique.
  "colonyTags" : ["pretty","valuable"],            // This isn't -as- important, but colony deeds will use it.
  "rarity" : "Legendary",                          // This determines the colored border (if any) around the inventory icon.
  "description" : "A tribute to GeorgeV! Developer Ultimate! ALL HAIL GEORGE!!!",
  // That was the tooltip text and default/fallback inspect description. We are -so- changing that.
  "shortdescription" : "GeorgeV Dev Statue",       // This is the object's "friendly" name, the header in the tooltip.
  "category" : "decorative",                       //
  "price" : 200,                                   // How much does this cost, by default?
  "printable" : false,                             // Consider this a kind of in-game copy-protection. Defaults to true, which
                                                   // would let you inspect it, and then produce more of it from pixels.

  "apexDescription" : "ALL HAIL GEORGE!!!",        // These are inspect descriptions for the various playable species.
  "avianDescription" : "ALL HAIL GEORGE!!!",       // You can add your own if you want. Personally, I do this in my
  "floranDescription" : "ALL HAIL GEORGE!!!",      // "Felins Object+" mod.
  "glitchDescription" : "ALL HAIL GEORGE!!!",
  "humanDescription" : "ALL HAIL GEORGE!!!",
  "hylotlDescription" : "ALL HAIL GEORGE!!!",

  "inventoryIcon" : "devstatuegeorgeicon.png",     // This is a 16x16 pixel icon representing the object.
  "orientations" : [                               // Important stuff in here, placement data.
    {
      "dualImage" : "devstatuegeorge.png:<color>", // This is actually kinda wrong. There is only gray.

      "imagePosition" : [-8, 0],                   // The object is 24 pixels wide. We shift it eight pixels to the left
                                                   // from the cursor position, and none up or down.
      "frames" : 1,                                // No animation, so just the one frame.
      "animationCycle" : 1.0,                      // Not important when there's no animation, but this would be speed.

      "spaceScan" : 0.1,                           // Automatic tile boundary detection threshold. Ignore this for now.
      "anchors" : [ "bottom" ]                     // Where can the object, in this orientation, be placed? On the ground!

    }
  ],

  "npcToy" : {}                                    // For NPC interaction use. It's of no use to NPCs.
}
Okay, so there's a little mistake of sorts in here, in that a single-color object has <color> in it. We'll get back to that. First, let's change all instances of devstatuegeorge to tutorialstatue. Use your editor's "replace all" feature. The first line should now be "objectName" : "tutorialstatue", and the dualImage line should be "dualImage" : "tutorialstatue.png:<color>",.

As a quick aside, the : in the dualImage value means to use a particular frame from that image. But there's just the one, and we left out devstatuegeorge.frames when we copied all that stuff. So in due time we'll change that. First, let's go down the file.

The objectName has already been changed by the "replace all" and what doesn't matter much can be skipped, so we're at the description. Now, I like to have this and shortDescription listed in the opposite order -- it makes more sense if you ask me -- but that doesn't matter much. Come up with a short description of the new statue and write it in here. Next, let's rename the object to match its new appearance by changing the value of shortdescription. If you want to go through the extra effort, you can also change the species-specific inspection descriptions, but you might as well remove them. It'll still work -- the game'll just use the generic description instead.

Now we get to the graphics! Change the inventoryIcon value from "devstatuegeorgeicon.png" to just "icon.png", since that's what we called the file, and the dualImage value to "tutorialstatue.png", that is, removing the :<color> stuff at the end.

That's basically it then, we're done with the first chapter. The only thing left to do is test this. Start up your game and type /admin, then -- while holding the mouse cursor close to your character and away from the ground -- /spawnitem tutorialstatue. If all went right, you should recieve a new object that you can place, facing either left or right:


Download the expected result for this lesson -- unpack it into mods, or just use it to compare your own work.


Last updated: 2016-08-26 16:30