Hack Your Habitat: An Engineer's Guide to the Save File

Where are my save files?
Good question, rookie. If you are serious about hacking your Habitat for fun and/or profit, you'll need to know where to start. Here's where you can find the files:

Inside this folder will be other folders, one for the quick save feature and one for each save game you've created in the game. Inside those folders are what you are after --,   (Earth),   (Moon),   (Mars). These files are giant blobs of JSON, that's a human readable, highly structured text file format. This will make it easier for you to hack your Habitat. No need for fancy tools; a simple text editor will do.

Let's break down these beauties, and see what's under the hood.

Version 0.6 of the system introduced multiple areas; we no longer haveta hang 'round that mud ball we used ta call home. Now, we can go to the Moon or Mars. With this new found freedom comes major changes to the files. This file used to hold all of the data, but it is now a slimmed down shell pointing to the  files. Here's how she looks now:

{  "save ver":"0.5", "save name":"0.6 Playing", "player level":0, "player XP":10, "current level index":0, "resources": {     "omni":5000, "fuel":5000, "electricity":5000, "citizens":7 } ,   "player roots": {     "habitat root 0": {     ...      },      "habitat root 1": {     ...      },      "habitat root N": {     ...      }   }  ,   "levels": {     "level0": {        "LevelIndex":0, "Name":"Earth orbit", "SkyBoxType":"earth", "Visited":false }    ,      "level1": {        "LevelIndex":1, "Name":"Lunar orbit", "SkyBoxType":"moon", "Visited":false }    ,      "level2": {        "LevelIndex":2, "Name":"Mars orbit", "SkyBoxType":"mars", "Visited":false }  } }

There's some familiar bits and bobs in here, but we'll cover them all as review, rookie.

Your
Now, we can have some fun. We're still fiddling with the numbers to see how hard we can push them, but this gives you a good idea of how to customize your resources. Bumpin' up the number o' citizens means ya can recruit more engineers. That means more people for me to train... Lot's o' overtime pay there!

Player Roots
The  block contains all the data about every habitat you've built. It starts counting from zero because that's how them computer science-y people like ta do things. Ya ask me, that sort a thinkin' is what got us up in this mess in the first place. They are going to be named like this:

"habitat root 0": { ... }

Inside this  block will be a   block defining core stats of the habitat, a   block defining where in the universe it is and where it is facing, one or more   blocks defining what objects make up your habitat, and a   block defining how everything is tied together.

"root": {        "is prebuilt":true, "habitat owner":"Player", "boosterAllotment": 1, "weaponAllotment":1, "productionAllotment":1 }

Not much to hack at here; you can try fudging the allotment values. Or, it might just blow the whole thing up. Won't know until ya try.

The transform block you see here is also used in other areas like  and.

"transform": {        "name":"Habitat", "position": {           "x":0, "y":0, "z":0 }       ,         "rotation": {           "x":0, "y":0, "z":0, "w":1 }       ,         "scale": {           "x":1, "y":1, "z":1 }     }

Standard stuff here, though I'm not sure I'd want to mess with these numbers much...

In this big ol' universe, it helps to know where the heck you are. The  block does just that:

"position": { "x":41.678684234619141, "y":24.06121826171875, "z":-19.161212921142578 }

We're still trying to figure out what these numbers mean; it ain't like dusting crops. One wrong calculation, and we might jump right into a sun or something.

Now that you know where you are, you better know which way you are facing. The  block does that for you:

"rotation": { "x":0.06299261748790741, "y":0.18773448467254639, "z":0.012065368704497814, "w":-0.98012357950210571 }

Again, we're not sure what these numbers will do if you change them; might end up staring down the business end of one them weird space ducks...

One thing to note here... Node IDs start from zero and count up without reseting across nodes. That means if one habitat stops at node 19, the next habitat will pick up with node 20.

"node #13: BoosterRocket": {        "prefab name":"BoosterRocket", "ugc id":"null", "transform": {           "name":"BoosterRocket(Clone)", "position": {              "x":-82.961662292480469, "y":1.3511998653411865, "z":231.64805603027344 }          ,            "rotation": {              "x":-0.0099369538947939873, "y":0.9821012020111084, "z":0.019801361486315727, "w":-0.18704685568809509 }          ,            "scale": {              "x":1.0000001192092896, "y":1.0000001192092896, "z":1.0000002384185791 }        }        ,         "health": {           "max health":400, "current health":400, "health per sec":0 },        "hats": {        },         "hotkey assignment":-1, "unique name":"" }

Pretty standard stuff here; the name of the item seems to be an internal name. What you see on screen might be named differently. We'll keep a list mapping the various names to each other, as we discover them. You can fiddle with the  values if you want to reconfigure your setup out of the normal engineering UI. We're not sure what  is supposed ta mean. Might be related to the new elemental effects I've heard about. Haven't flown through them gas clouds yet to find out. Only one hat ya can wear out in the cold of space... Don't even get me started on ... This seems to hold the name given to your Habitat; otherwise, it is always blank, which is far from unique, if ya want my opinion.

The  list comes in a sequence of pairs:

"weld points": {        "node connection #0 base point": {           "name":"Weld Point 1", "weld connection id":"node #13: BoosterRocket" }       ,         "node connection #0 end point": {           "name":"Weld Point 4", "weld connection id":"node #14: HabSectionContainer2x2" },        ...      }

Each pair starts with a base point block and ends with an end point block. It can be tough to read these; let me try to break it down. The  /   keys define an individual connection where   is just counting up from zero. The inside of each block defines the point where the connector piece is welded onto the node.

In the example above, the connector starts at  of a booster rocket and ends at   of a storage container. Those computer guys do like their jokes; from what we can tell, the weld points start counting at one instead of zero. Hurray for consistency... We're still sorting out where point one starts and if it counts clockwise or counterclockwise from that point.

you can live in
Starting with index 0 (silly programmers always start with that number...), each  block simply outlines the name, what type the level is, and whether or not you've visited that level. The odd thing is Earth, level 0, reads  even though you start there...

Overall Format
Here's how a level file breaks down:

{  "LevelIndex":0, "Name":"Earth orbit", "LevelVisited":false, "SkyBoxType":"earth", "player roots": {  },   "loose nodes": {     "loose node 0": {     ...                  },      "loose node N": {     ...                  }

},  "engineers": {     "count":3, "engineer 0": {     ...      }     ,      "engineer N": {     ...      } }

We'll cover each section in more depth below, but you can see that it starts with some base data about the level -- index, name -- that sort of guff.

When 0.6 introduced this block, the level file had this block populated. Now, 0.7 has reversed this; the overall save game file contains the data. The current level you are has an empty block, and the other levels do not have this block at all.

Version 0.6 finally brought some stability to the universe... The  block contains an entry for every piece of junk generated when you start your game. That's right... When you load up your game, it's no longer a crap shoot for what you can build with. You'll have the same stuff floating around; that is, if you haven't fiddled with the bits. Again, starting from 0:

"loose node 0": {        "prefab name":"MiningTown Beta", "gateway index":0, "unique name":"", "transform": {           "position": {              "x":-86.169013977050781, "y":0, "z":-1183.415283203125i }          ,            "rotation": {              "x":0, "y":0, "z":0, "w":1 }          ,            "scale": {              "x":1, "y":1, "z":1 }        }      }

Again, these blocks are telling you what is where. The interesting item in this block is the ; these are always tied to a   of. The value is the index of the level you'll hop to when using it. We haven't yet tried setting this up on something other than a. Back door like that might open up one of them quantum singularities or worse...

Again, starting from 0, you'll find an  block for each engineer floating around the cosmos:

"engineer 0": {        "position": {           "x":479.51043701171875, "y":9.7535943984985352, "z":-192.66798400878906 }       ,         "rotation": {           "x":0.0033145349007099867, "y":0.52820920944213867, "z":0.0082756904885172844, "w":0.8490675687789917 }       ,         "gender":"Female", "voice":0, "health": {           "max health":150, "current health":149.37991333007813, "health per sec":0 }       ,         "tether target node id":"node #16: HabFuelTrailer", "tether connection state":"Connected" }

Conclusion
That's all I got fer ya. It's a big universe out there; have some fun hacking at this junk and seeing what happens. Who knows what neat stuff you might be able to pull off.

Cheers, chummer.