How to make your own playable Starbound species

By Kawa.

Requirements

The easy way out, and I'll bet this is what the devs did once they had the beginnings of the first species down, is to copy and adapt something that already exists. The whole point of this tutorial is to not require my felins and instead learn how to do it yourself from a vanilla copy of Starbound. As with (for example) items, your best choice is to find the existing thing that most closely matches what you want to make.

Let's make foxes.

The closest thing, physically speaking, to foxes are the apex. But in terms of the character creator and how it acts, perhaps the humans are the better choice. Specific label texts are wholly customizable, as you'll see. Why the humans though, when we want foxes? Again, you'll see.

There are a few different files and directories that make up a species. There's one directory in /humanoid which contains all the images for a given species, there's configuration and name generators in /species, there's animation data in /cinematics and /cinematics/respawn, and there's /quest data, just for starters. All things that you'll need to get the species to run at all. Others can refer to existing species data.

Now, let's begin.

Body stylin'

At this point, I'd suggest taking an existing directory in /humanoid whose contents most closely resemble what you're after already. You don't need the /hair directory (or directories) yet — we'll set those up in a moment. Now, taking care with the exact colors, you can edit your sprites.

Since we're making foxes, and foxes are basically similar enough to my felins, here's what I did: I took the avian bodies, chosen for having a pretty good coloration pattern, pasted in the human feet, and drew some tails. Then I took the human heads, recolored them to match the avian's body (which is darker), and edited the ears. For foxes, you might want to consider a pronounced muzzle?

You have to be careful with the color values because the data in /species uses those for palette swapping. If you change them, you'll have to make even more amendments to that data than strictly needed. What you can do is switch to a better-suited format — the PNG files don't have to be 32-bit RGBA with gamma correction and what-have-you, but can just as easily be tightly crunched no-nonsense 16-color indexed. I know mine are. It keeps the download size down a lot — you can shave a good 42 megabytes off of Starbound's vanilla assets if you crunch the lot.

Another important thing to keep in mind is that the species must have the same basic body shape as the rest of them. If they don't, items and equipment won't look right.

At this point you might want to look into hairs. The exact directory or file names you want to use don't matter much — human hair is all in one directory and named fem1 through fem56 and male1 through male62, hylotl hair is in one directory and named 1 through 40, yet apex have four different directories to account for gender and beards, and the avians... oh wow the avians.

For now though, let's just make a single hair directory and copy over a few nice ones from the other species. Mix and match all you want.

Species data

And now, our first foray into JSON-level modding. There's a bunch of .species files in /species. This is where the choice to use human data comes in, though we'll need to paste in some data from the hylotl as well.

Here's human.species, slightly snipped for clarity:

{
	"kind" : "human",
	"index" : 0,
	"nameGen" : [ "/species/humannamegen.config:names", "/species/humannamegen.config:names" ],
	"ouchNoises" : [ "/sfx/humanoid/humanhurt_male1.wav", "/sfx/humanoid/humanhurt_female1.wav" ],
	"defaultBlueprints" : {
		"tier1" : [
			{ "item" : "humantier1hammer" },
			{ "item" : "humantier1shortsword" },
			{ "item" : "humantier1broadsword" },
			{ "item" : "humantier1spear" },
			{ "item" : "humantier1axe" },
			{ "item" : "humantier1dagger" },
			{ "item" : "humantier1head" },
			{ "item" : "humantier1chest" },
			{ "item" : "humantier1pants" },
			//SNIP
		],
		//SNIP
	},
	"altOptionAsUndyColor" : true,
	"headOptionAsHairColor" : true,
	"genders" : [
	{
		"name" : "male",
		"image" : "/interface/title/male.png",
		"characterImage" : "/interface/title/humanmale.png",
		"hair" : [
			"male1", "male2", "male3", "male4", "male5", "male6", "male7", "male8", "male9", "male10",
			//SNIP
			"male60", "male61", "male62" ],
		"shirt" : [ "workoutchest", "coolchest", "conceptchest", "sweatervestchest" ],
		"pants" : [ "workoutlegs", "coollegs", "conceptlegs", "sweatervestlegs" ],
		"facialHairGroup" : "",
		"facialHair" : [ ],
		"facialMaskGroup" : "",
		"facialMask" : [ ]
	},
	{
		"name" : "female",
		"image" : "/interface/title/female.png",
		"characterImage" : "/interface/title/humanfemale.png",
		"hair" : [
			"fem1", "fem2", "fem3", "fem4", "fem5", "fem6", "fem7", "fem8", "fem9", "fem10",
			//SNIP
			"fem53", "fem54", "fem55", "fem56" ],
		"shirt" : [ "workoutchest", "coolchest", "conceptchest", "sweatervestchest" ],
		"pants" : [ "workoutlegs", "coollegs", "conceptlegs", "sweatervestlegs" ],
		"facialHairGroup" : "",
		"facialHair" : [ ],
		"facialMaskGroup" : "",
		"facialMask" : [ ]
		}
	],
	"bodyColor" : [
		{ "ffe2c5" : "ffe9d3", "ffc181" : "ffc181", "d39c6c" : "d39c6c", "c7815b" : "b97551" },
		{ "ffe2c5" : "fff6f6", "ffc181" : "f7d5d3", "d39c6c" : "d1aaa1", "c7815b" : "a27f70" },
		{ "ffe2c5" : "fff7ec", "ffc181" : "f9d3a9", "d39c6c" : "d3a57c", "c7815b" : "b37c5d" },
		//SNIP
	],
	"undyColor" : [
		{ "dc1f00" : "4d76ad", "be1b00" : "395187", "951500" : "20325b" },
		{ "dc1f00" : "7c41b8", "be1b00" : "6c2f90", "951500" : "471962" },
		{ "dc1f00" : "c63442", "be1b00" : "9b2724", "951500" : "6a1210" },
		//SNIP
	],
	"hairColor" : [
		{ "d9c189" : "525252", "a38d59" : "363636", "735e3a" : "161616" },
		{ "d9c189" : "50422f", "a38d59" : "36261e", "735e3a" : "170f0d" },
		{ "d9c189" : "7f5a39", "a38d59" : "5b3523", "735e3a" : "3b1f15" },
		//SNIP
	]
}

Starbound JSON files contain mostly Dictionaries, lists of data where each entry has a key string for identification rather than a number. Starbound looks for several of these.

The kind entry determines what the species is called. Change that to read "fox":

"kind" : "fox",

The index is a tricky one that I don't entirely get yet. For my felin species I set this one to 6, since the glitch are 5. I noticed that Uyuxo's mannequin mod and Mwarner's ursines use 6 too, and I honestly have no idea what that'd do. So remind me to amend this guide later, okay?

nameGen can be left as it is for now. We can come back to that later. Both entries in this list (which is what the [] mean — a simple numerically-indexed array of things) refer to the same file and contained data, but it's clear from the next line that they're male and female names respectively. Said next line, ouchNoises, is even more obvious than that.

defaultBlueprints is a dictionary onto itself. It lists the things you can make when playing this species and augments a similar list in player.config. Let's not get into this just yet.

The next part is a bunch of optional-ish physical-like properties:

altOptionAsUndyColor
Used by the hylotl, humans, glitch, floran, and apex.
headOptionAsHairColor
Used by the hylotl, humans, glitch, and floran. If missing, the hair takes on the color of the body.
altOptionAsHairColor
Used by the hylotl, glitch, and floran.
hairColorAsBodySubColor
Used by the hylotl and glitch.
headOptionAsFacialhair
Used by the avians and apex to implement their fluffs and beards.
altOptionAsFacialMask
Used by the avians to implement their beaks.

The "altOptionAs" keys determine if the top-right setting in the character creator should recolor the red bits ("asUndyColor"), recolor the pale brown bits ("asHairColor"), or be another image part ("asFacialMask").

The "headOptionAs" keys determine if the second from the top right setting should recolor the pale brown bits ("asHairColor") or be another image part ("asFacialhair").

That's basically all I managed to puzzle out so far. You might notice that the avian body sprites have red bellies, but they're white in game. We'll get to that in a moment. For now, let's leave the altOptionAsUndyColor and headOptionAsHairColor keys in place like this.

The genders key, like defaultBlueprints, is another complex one. But if you look at its two component parts individually it makes sense again. name is obvious. image refers to the male/female symbols and allows florans and glitch to be special snowflakes. characterImage refers to what the little portraits in the character creator should be. You can draw your own and change these references, or you can leave them as-is for now. Your choice. It's gonna get a little interesting now so I'm going to start a new paragraph.

The hair key lists all the hairs that this gender can have. If there is no hairGroup key, hair images are presumed to be in the hair directory. The apex define a different hairGroup for each gender with this key, storing the two sets in separate directories. This is where you get to plug in the file names (without the ".png" part!) for your hairs, so you might want to do that now.

The shirt and pants keys list various item names. Let's play it safe and leave these as-is. You can always come back to this later, but the defaults will suffice.

The facialHairGroup, facialHair, facialMaskGroup, and facialMask keys work in a similar way as the hairGroup and hair keys. You'll find they're empty for this copy of humans — since there's no headOptionAsFacialhair or altOptionAsFacialMask keys, they're not used anyway. You might want to peek at the avians at this point if you're interested.

The final keys — bodyColor, undyColor, and hairColor — map all these special color values in the sprite sheets to the actually chosen values. Each entry in each list is another dictionary on its own, and for each key/value pair the key is an RGB hex value to map from and the value the color to map to. This is where the the hylotl come in — the sprites we made earlier have darker colors than those listed in bodyColor at this time! So, open up hylotl.species, find the bodyColor list and copy the whole block over. Make sure it's a good fit! Any loose commas, missing brackets of any kind, and your game won't load any more! Fortunately, the red bits are the same across the board. Now, use your favorite non-MSPaint graphics editor or something to get some good color schemes for your foxes.

Now, I mentioned the avian sprites have red bellies, yet they're white in the game. This is because for avians, who lack any meaningful content in their undyColor and hairColor keys, the red bits are repeatedly listed in their bodyColor block.

Cinematics

Short one here. You can make do just copying /cinematics/respawn/human to /cinematics/respawn/fox and /cinematics/human to /cinematics/fox and you're basically done for.

Interface

If you decided to have custom portraits in the character creator, you'll find the originals in /interface/title, as that's what the species file (originally) specified. Use any means you wish to acquire these portraits.

The fun part

Now, we're going to edit some of the original files. Not just copies, but singletons! Let's start with player.config. There's only one interesting bit in this file, and that's the species key; a list of playable species, in no particular order. Add "fox" to the end, like this: "species" : [ "human", "glitch", "hylotl", "apex", "avian", "floran", "fox" ], There may be more there if you have any other custom species installed but that's the basic idea here.

The most interesting and intricate changes go in interface/windowconfig/charcreation.config. First, there's the textLabels key, a list of lists that determines, in order, what the selections in the character creator should be labelled as, including the header. Add the following line, so that it looks like this:

  "textLabels" : [
    [ "SKIN COLOR", "HAIR STYLE", "SHIRT", "PANTS", "UNDY COLOR", "HAIR COLOR", "SHIRT COLOR", "PANTS COLOR", "HUMAN", "PERSONALITY" ],
    [ "FEATHER COLOR", "PLUMAGE", "SHIRT", "PANTS", "BEAK STYLE", "FLUFF", "SHIRT COLOR", "PANTS COLOR", "AVIAN", "PERSONALITY" ],
    [ "FUR COLOR", "HAIR STYLE", "SHIRT", "PANTS", "SKIN COLOR", "BEARD STYLE", "SHIRT COLOR", "PANTS COLOR", "APEX", "PERSONALITY" ],
    [ "SKIN COLOR", "FOLIAGE", "SHIRT", "PANTS", "LEAF COLOR", "FLOWER COLOR", "SHIRT COLOR", "PANTS COLOR", "FLORAN", "PERSONALITY" ],
    [ "SKIN COLOR", "FINS", "SHIRT", "PANTS", "BELLY COLOR", "FIN COLOR", "SHIRT COLOR", "PANTS COLOR", "HYLOTLS", "PERSONALITY" ],
    [ "PAINT COLOR", "HEAD MOD", "SHIRT", "PANTS", "LIGHTS COLOR", "DETAIL COLOR", "SHIRT COLOR", "PANTS COLOR", "GLITCH", "PERSONALITY" ],
    [ "FUR COLOR", "HAIR STYLE", "SHIRT", "PANTS", "BELLY COLOR", "HAIR COLOR", "SHIRT COLOR", "PANTS COLOR", "FOX", "PERSONALITY" ]
  ],

Notice how we basically combined the apex and hylotl labels, and how the labels reflect those interesting keys in the species file. Again, take care with the commas!

The other change in that same file adds the actual button to select our new species. The species key, should be 'round line 147, specifically the buttons sub-key, defines which species buttons go where. Near the end, there's a recognizable entry for the glitch that we can add our own button to, making the whole look something like this:

"buttons" : [
	{
		"id" : 0,
		"image" : "/interface/title/humanfemale.png",
		"position" : [0, 0]
	},
	{
		"id" : 1,
		"image" : "/interface/title/avianfemale.png",
		"position" : [27, 0]
	},
	{
		"id" : 2,
		"image" : "/interface/title/sapefemale.png",
		"position" : [54, 0]
		},
	{
		"id" : 3,
		"image" : "/interface/title/plantfemale.png",
		"position" : [0, -26]
		},
	{
		"id" : 4,
		"image" : "/interface/title/aquaticfemale.png",
		"position" : [27, -26]
	},
	{
		"id" : 5,
		"image" : "/interface/title/robotfemale.png",
		"position" : [54, -26]
	},
	{
		"id" : 6,
		"image" : "/interface/title/foxfemale.png",
		"position" : [0, 26]
	}
]

Notice this: the id matches the index in the species files, and the image matches characterImage... that last one is probably not a requirement. This does mean there would be some measure of a conflict between species mods! We can't all have the same indices.

The next parts are basically hooking up ships and quests. We'll use existing ones for now, as making your own ship is a little out of scope. In universe_server.config, there's a key speciesShips. You can copy one of the entries already there and change the key to "fox":

"speciesShips" : {
	"apex" : "/ships/apex/dropship.structure",
	"avian" : "/ships/avian/dropship.structure",
	"floran" : "/ships/floran/dropship.structure",
	"human" : "/ships/human/dropship.structure",
	"hylotl" : "/ships/hylotl/dropship.structure",
	"glitch" : "/ships/glitch/dropship.structure",
	"fox" : "/ships/avian/dropship.structure"
}

A similar thing goes for codex/codex.config and quests/quests.config. When you feel up to the task, you can copy these three things and make your own.

And that's it. You should be able to play as a fox now.