Adding new buildable objects

## Introduction

This article serves as a tutorial to adding new buildable objects. This means that we will create a custom object and make it appear in the build menus. It is possible to add custom models, but for the sake of this tutorial we will make reuse a table object that already exists in-game resources but not normally available to be built.

There are three steps to follow in order to make an object available to build from the build menus:

1. Adding the buildable object entry in **BASEBUILDINGTABLE.MBIN**;
2. Adding the buildable object entry in **NMS\_REALITY\_GCPRODUCTTABLE.MBIN**;
3. Making the buildable object available to acquire in game.

The use of NMS Modding Station is recommended, and shall be used in this article for demonstration when relevant. If you haven't set it up already, make sure you do so as explained in Accessing Game Assets.

### Locating BASEBUILDINGTABLE.MBIN and NMS\_REALITY\_GCPRODUCTTABLE.MBIN

First of all, create a new project in NMS Modding Station. Call it however you prefer (i.e. TestTable). From the Unpacked Game Files tab, navigate to **METADATA\REALITY\TABLES**, select **BASEBUILDINGTABLE.MBIN** and **NMS\_REALITY\_GCPRODUCTTABLE.MBIN**, right click on them and select *Copy to Project Files*. This will make sure that the files are now copied in your mod folder (please note that the entire folder structure will be carried over by NMS Modding Station). If you are not using NMS Modding Station, make sure you manually recreate the folder structure.

Now that the files are copied to your mod folder, you need to decompile the MBIN files as outlined in Accessing Game Assets.

## 1. Adding entry in BASEBUILDINGTABLE.MBIN

We are now ready to edit the decompiled files. We will start from BASEBUILDINGTABLE.MBIN (which will now be decompiled as BASEBUILDINGTABLE.exml). The objective is to duplicate the structure from an existing object already present in the exml file, and edit the parameters to create a custom one.

#### Creating a building entry

Open BASEBUILDINGTABLE.exml with the text editor of your choice (Notepad++ is recommended). Navigate to the “**Objects**” nested entry (which should be around line 20), select the entire content of the first “**GcBaseBuildingEntry.xml**” entry, and then paste it in order to create a duplicate. This duplicate will act as the template for our new entry we will use for our custom buildable table. The entry should look something like this:

```
<Property value="GcBaseBuildingEntry.xml">
  <Property name="ID" value="W_WALL" />
  <Property name="HasProduct" value="True" />
  <Property name="SnapPoints" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/PLANETS/BIOMES/COMMON/BUILDINGS/PARTS/BUILDABLEPARTS/BASICPARTS/BASIC_WALL.SCENE.MBIN" />
  </Property>
  <Property name="Model" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/PLANETS/BIOMES/COMMON/BUILDINGS/PARTS/BUILDABLEPARTS/BASICPARTS/MESHES/WOOD/BASIC_WALL.SCENE.MBIN" />
  </Property>
  <Property name="InactiveModel" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/PLANETS/BIOMES/COMMON/BUILDINGS/PARTS/BUILDABLEPARTS/BASICPARTS/MESHES/WOOD/BASIC_WALL_LOD.SCENE.MBIN" />
  </Property>
  <Property name="Type" value="GcBaseBuildingObjectTypes.xml">
    <Property name="BaseBuildingObjectType" value="BuildingFoundation" />
  </Property>
  <Property name="DecorationType" value="GcBaseBuildingObjectDecorationTypes.xml">
    <Property name="BaseBuildingDecorationType" value="Normal" />
  </Property>
  <Property name="Biome" value="GcBiomeType.xml">
    <Property name="Biome" value="Lush" />
  </Property>
  <Property name="RegionSpawnLOD" value="2" />
  <Property name="BuildableOnBase" value="True" />
  <Property name="BuildableOnFreighter" value="False" />
  <Property name="BuildableOnPlanet" value="False" />
  <Property name="BuildableUnderwater" value="True" />
  <Property name="GlobalLimit" value="0" />
  <Property name="SystemLimit" value="0" />
  <Property name="PlanetLimit" value="0" />
  <Property name="RegionLimit" value="0" />
  <Property name="PlanetBaseLimit" value="0" />
  <Property name="FreighterBaseLimit" value="0" />
  <Property name="BaseLayoutRadius" value="2" />
  <Property name="CheckCollision" value="True" />
  <Property name="CollisionScale" value="0.5" />
  <Property name="CollidesWithPlayer" value="True" />
  <Property name="CanPlaceOnItself" value="True" />
  <Property name="Group" value="BASIC_W" />
  <Property name="DontStore" value="False" />
  <Property name="ComplexityCost" value="920" />
  <Property name="InactiveComplexityCost" value="290" />
  <Property name="ForceExtraIdx" value="-1" />
  <Property name="GroupSnappingLimit" value="0" />
  <Property name="CanChangeColour" value="True" />
  <Property name="CanChangeMaterial" value="False" />
  <Property name="CanPickUp" value="False" />
  <Property name="ScanRadius" value="0" />
  <Property name="RemovesAttachedDecoration" value="True" />
  <Property name="EditsTerrain" value="False" />
  <Property name="BaseTerrainEditShape" value="Cube" />
  <Property name="TerrainEditBaseYOffset" value="0" />
  <Property name="TerrainEditTopYOffset" value="0" />
  <Property name="TerrainEditBoundsScalar" value="1" />
</Property>

```

#### Understanding and editing “GcBaseBuildingEntry.xml” entries

The xml file has many properties, and we will now describe the most important, or frequently used ones:

* **ID**: the ID of the object. Each object should have a unique object ID, the length of this value must not exceed 16 characters, for demonstration, it shall be modified to “**TESTTABLE**”;

* **Model**:
	+ **Filename**: the file location of the object to be added. For this particular case, the location of the object is located at **MODELS/PLANETS/BIOMES/COMMON/BUILDINGS/PARTS/BUILDABLEPARTS/DECORATION/TABLE1.SCENE.MBIN**, and shall be changed to such;

* **BuildableOnBase, BuildableOnFreighter, BuildableOnPlanet**: boolean properties deciding if the object can be built within planetary player base limits, inside the player freighter base, and outside planetary player base limits (a.k.a in the fields);

* **GlobalLimit, SystemLimit, PlanetLimit, RegionLimit**: properties restricting the number of this object which can be built in the entire galaxy, one system, one planet, and one “region” (a general area covering a certain amount of distance). A value of 0 refers to an unlimited amount;

* **PlanetBaseLimit, FreighterBaseLimit**: properties setting the limit number of this objects which can be built in the planetary player base and in the player freighter. A value of 0 refers to an unlimited amount;

* **CheckCollision**: boolean value deciding if the game will also check whether the object can be placed base on scene collision data, rather than just from the mesh itself;

* **Group**: property deciding which group the object is put in inside the build menus. For demonstration purposes, the object shall be put in a custom group named **ADDIT**. We will setup this group in the next step of the tutorial, so keep this name in mind;

After editing your custom entry, it should look something like this:

```
<Property value="GcBaseBuildingEntry.xml">
  <Property name="ID" value="TESTTABLE" />
  <Property name="HasProduct" value="True" />
  <Property name="SnapPoints" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/PLANETS/BIOMES/COMMON/BUILDINGS/PARTS/BUILDABLEPARTS/BASICPARTS/BASIC_WALL.SCENE.MBIN" />
  </Property>
  <Property name="Model" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/PLANETS/BIOMES/COMMON/BUILDINGS/PARTS/BUILDABLEPARTS/DECORATION/TABLE1.SCENE.MBIN" />
  </Property>
  <Property name="InactiveModel" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/PLANETS/BIOMES/COMMON/BUILDINGS/PARTS/BUILDABLEPARTS/BASICPARTS/MESHES/WOOD/BASIC_WALL_LOD.SCENE.MBIN" />
  </Property>
  <Property name="Type" value="GcBaseBuildingObjectTypes.xml">
    <Property name="BaseBuildingObjectType" value="BuildingFoundation" />
  </Property>
  <Property name="DecorationType" value="GcBaseBuildingObjectDecorationTypes.xml">
    <Property name="BaseBuildingDecorationType" value="Normal" />
  </Property>
  <Property name="Biome" value="GcBiomeType.xml">
    <Property name="Biome" value="Lush" />
  </Property>
  <Property name="RegionSpawnLOD" value="2" />
  <Property name="BuildableOnBase" value="True" />
  <Property name="BuildableOnFreighter" value="False" />
  <Property name="BuildableOnPlanet" value="False" />
  <Property name="BuildableUnderwater" value="True" />
  <Property name="GlobalLimit" value="0" />
  <Property name="SystemLimit" value="0" />
  <Property name="PlanetLimit" value="0" />
  <Property name="RegionLimit" value="0" />
  <Property name="PlanetBaseLimit" value="0" />
  <Property name="FreighterBaseLimit" value="0" />
  <Property name="BaseLayoutRadius" value="2" />
  <Property name="CheckCollision" value="True" />
  <Property name="CollisionScale" value="0.5" />
  <Property name="CollidesWithPlayer" value="True" />
  <Property name="CanPlaceOnItself" value="True" />
  <Property name="Group" value="ADDIT" />
  <Property name="DontStore" value="False" />
  <Property name="ComplexityCost" value="920" />
  <Property name="InactiveComplexityCost" value="290" />
  <Property name="ForceExtraIdx" value="-1" />
  <Property name="GroupSnappingLimit" value="0" />
  <Property name="CanChangeColour" value="True" />
  <Property name="CanChangeMaterial" value="False" />
  <Property name="CanPickUp" value="False" />
  <Property name="ScanRadius" value="0" />
  <Property name="RemovesAttachedDecoration" value="True" />
  <Property name="EditsTerrain" value="False" />
  <Property name="BaseTerrainEditShape" value="Cube" />
  <Property name="TerrainEditBaseYOffset" value="0" />
  <Property name="TerrainEditTopYOffset" value="0" />
  <Property name="TerrainEditBoundsScalar" value="1" />
</Property>

```

#### Adding a custom group entry

So far we have worked with the building entry of the table. Now we will create a custom group that the entry is part of (you should remember that we already assigned a group to it in the previous step!).

In the same exml file, navigate to the “**Groups**” nested entry. We will now do the same thing as we did before, and duplicate an existing entry to have a skeleton already in place. Copy a “**GcBaseBuildingGroup.xml**” entry and paste it. The group entry should look something like this:

```
<Property value="GcBaseBuildingGroup.xml">
  <Property name="ID" value="STRUCTURE" />
  <Property name="ParentGroup" value="" />
  <Property name="Name" value="UI_BUILD_STRUCT_GRP" />
  <Property name="Icon" value="TkTextureResource.xml">
    <Property name="Filename" value="TEXTURES/UI/FRONTEND/ICONS/BUILDABLE/GROUPS/BUILDGROUP.STRUCTURE.DDS" />
  </Property>
</Property>

```

These are the two most important properties to keep in mind:

* **ID**: the ID of the group. This property corresponds to the “**Group**” property the we declared in the building entry;

* **Name**: the name of the group. It can correspond to the language files for translations in different languages, or named in plain text and appearing in the build menu in the language written.

We will edit these two properties to match the building entry. the modified entry should look like this:

```
<Property value="GcBaseBuildingGroup.xml">
  <Property name="ID" value="ADDIT" />
  <Property name="ParentGroup" value="" />
  <Property name="Name" value="Additional Objects" />
  <Property name="Icon" value="TkTextureResource.xml">
    <Property name="Filename" value="TEXTURES/UI/FRONTEND/ICONS/BUILDABLE/GROUPS/BUILDGROUP.STRUCTURE.DDS" />
  </Property>
</Property>

```

This concludes the editing phase for BASEBUILDINGTABLE.exml.

## 2. Adding entry in NMS\_REALITY\_GCPRODUCTTABLE.MBIN

We will now go and edit NMS\_REALITY\_GCPRODUCTTABLE.MBIN in a very similar way. Our goal is to make sure that the buildable object we created in BASEBUILDINGTABLE.exml is correctly referenced in this file. Once again we will duplicate the structure from an existing object already present in the exml file, and edit the parameters to create a custom one.

#### Creating a building entry

Select the entire content of a “**GcProductData.xml**” entry, and then paste it in order to create a duplicate. This duplicate will act as the template for our new entry we will use for our custom buildable table. It is suggested to copy an entry of an existing *buildable object* entry, instead of a *crafted product*, when creating a new buildable object entry for ease of modification. The entry should look something like this:

```
<Property value="GcProductData.xml">
  <Property name="Id" value="BUILDBED" />
  <Property name="Name" value="BLD_BED_NAME" />
  <Property name="NameLower" value="BLD_BED_NAME_L" />
  <Property name="Subtitle" value="VariableSizeString.xml">
    <Property name="Value" value="BLD_BED_SUBTITLE" />
  </Property>
  <Property name="Description" value="VariableSizeString.xml">
    <Property name="Value" value="BLD_BED_DESCRIPTION" />
  </Property>
  <Property name="Hint" value="" />
  <Property name="DebrisFile" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/EFFECTS/DEBRIS/TERRAINDEBRIS/TERRAINDEBRIS4.SCENE.MBIN" />
  </Property>
  <Property name="BaseValue" value="600" />
  <Property name="Level" value="1" />
  <Property name="Icon" value="TkModelResource.xml">
    <Property name="Filename" value="TEXTURES/UI/FRONTEND/ICONS/BUILDABLE/BUILDABLE.BED.DDS" />
  </Property>
  <Property name="Colour" value="Colour.xml">
    <Property name="R" value="0.172549" />
    <Property name="G" value="0.4862745" />
    <Property name="B" value="0.6235294" />
    <Property name="A" value="1" />
  </Property>
  <Property name="SubstanceCategory" value="GcRealitySubstanceCategory.xml">
    <Property name="SubstanceCategory" value="BuildingPart" />
  </Property>
  <Property name="Category" value="GcProductCategory.xml">
    <Property name="ProductCategory" value="BuildingPart" />
  </Property>
  <Property name="Rarity" value="GcRarity.xml">
    <Property name="Rarity" value="Common" />
  </Property>
  <Property name="Legality" value="GcLegality.xml">
    <Property name="Legality" value="Legal" />
  </Property>
  <Property name="Consumable" value="False" />
  <Property name="ChargeValue" value="0" />
  <Property name="Requirements">
    <Property value="GcTechnologyRequirement.xml">
      <Property name="ID" value="COM1" />
      <Property name="InventoryType" value="GcInventoryType.xml">
        <Property name="InventoryType" value="Substance" />
      </Property>
      <Property name="Amount" value="30" />
    </Property>
  </Property>
  <Property name="Cost" value="GcItemPriceModifiers.xml">
    <Property name="SpaceStationMarkup" value="0" />
    <Property name="LowPriceMod" value="0.25" />
    <Property name="HighPriceMod" value="0.5" />
    <Property name="BuyBaseMarkup" value="0.2" />
    <Property name="BuyMarkupMod" value="0" />
  </Property>
  <Property name="SpecificChargeOnly" value="False" />
  <Property name="NormalisedValueOnWorld" value="0.01190119" />
  <Property name="NormalisedValueOffWorld" value="0.01190119" />
</Property>

```

#### Understanding “GcProductData.xml” entries

The xml file has many properties, and we will now describe the most important, or frequently used ones:

* **ID**: ID of the object. It corresponds to the ID entry of the respective object we created in BASEBUILDINGTABLE.MBIN. In our case we will use “**TESTTABLE**”, following what we did in the previous paragraph;

* **Name, NameLower, Description**: Name of the object in all uppercase, normal form, and its description. It can correspond to the language files for translations in different languages, or named in plain text. These are the strings that appears in the build menu;

* **Icon**: location of the icon image file. The file must be in DDS format, and must contain an ALL UPPERCASE DDS file extension;

* **SubstanceCategory**:
	+ **SubstanceCategory**: the substance category the entry belongs to. As a buildable object, this property should have the value of “**BuildingPart**”;
* **Category**:
	+ **ProductCategory**: the product category the entry belongs to. As a buildable object, this property should also have the value of “**BuildingPart**”;

* **Requirements**: the cost of building the object. Each ingredient should have its separate entry, and a maximum of three types of ingredient can be inputted. Each of these ingredients will have the following properties:
	+ **ID**: refers to the ID of the type of ingredient. See this table for a list of substances;
	+ **InventoryType**: refers to the type of substance. It is either “**Substance**”, generally an element, or “**Product**”, generally an item;
	+ **Amount**: refers to the number of ingredient required to build the object. The amount must be larger than 0.

Our modified table entry should look something like this:

```
<Property value="GcProductData.xml">
  <Property name="Id" value="TESTTABLE" />
  <Property name="Name" value="TABLE" />
  <Property name="NameLower" value="Table" />
  <Property name="Subtitle" value="VariableSizeString.xml">
    <Property name="Value" value="Table" />
  </Property>
  <Property name="Description" value="VariableSizeString.xml">
    <Property name="Value" value="A very normal table." />
  </Property>
  <Property name="Hint" value="" />
  <Property name="DebrisFile" value="TkModelResource.xml">
    <Property name="Filename" value="MODELS/EFFECTS/DEBRIS/TERRAINDEBRIS/TERRAINDEBRIS4.SCENE.MBIN" />
  </Property>
  <Property name="BaseValue" value="600" />
  <Property name="Level" value="1" />
  <Property name="Icon" value="TkModelResource.xml">
    <Property name="Filename" value="TEXTURES/UI/FRONTEND/ICONS/BUILDABLE/BUILDABLE.TABLE001.DDS" />
  </Property>
  <Property name="Colour" value="Colour.xml">
    <Property name="R" value="0.172549" />
    <Property name="G" value="0.4862745" />
    <Property name="B" value="0.6235294" />
    <Property name="A" value="1" />
  </Property>
  <Property name="SubstanceCategory" value="GcRealitySubstanceCategory.xml">
    <Property name="SubstanceCategory" value="BuildingPart" />
  </Property>
  <Property name="Category" value="GcProductCategory.xml">
    <Property name="ProductCategory" value="BuildingPart" />
  </Property>
  <Property name="Rarity" value="GcRarity.xml">
    <Property name="Rarity" value="Common" />
  </Property>
  <Property name="Legality" value="GcLegality.xml">
    <Property name="Legality" value="Legal" />
  </Property>
  <Property name="Consumable" value="False" />
  <Property name="ChargeValue" value="0" />
  <Property name="Requirements">
    <Property value="GcTechnologyRequirement.xml">
      <Property name="ID" value="COMRARE1" />
      <Property name="InventoryType" value="GcInventoryType.xml">
        <Property name="InventoryType" value="Substance" />
      </Property>
      <Property name="Amount" value="10" />
    </Property>
  </Property>
  <Property name="Cost" value="GcItemPriceModifiers.xml">
    <Property name="SpaceStationMarkup" value="0" />
    <Property name="LowPriceMod" value="0.25" />
    <Property name="HighPriceMod" value="0.5" />
    <Property name="BuyBaseMarkup" value="0.2" />
    <Property name="BuyMarkupMod" value="0" />
  </Property>
  <Property name="SpecificChargeOnly" value="False" />
  <Property name="NormalisedValueOnWorld" value="0.01190119" />
  <Property name="NormalisedValueOffWorld" value="0.01190119" />
</Property>

```

This concludes the editing phase for NMS\_REALITY\_GCPRODUCTTABLE.exml.

## 3. Making the object available to acquire in game

Now that our exml files have been edited correctly, we need to make sure we can actually see our test table in-game. There are multiple ways in which we can include the blueprint of our custom object, and you can use whichever works best for you:

* **Default Save Data**: adding the blueprint into DEFAULTSAVEDATA.MBIN and DEFAULTSAVEDATACREATIVE.MBIN. These files are the default save data that is loaded when starting the game. The blueprint will be immediately given to the player;

* **Vendor's List**: adding an entry into PURCHASEABLEBUILDINGBLUEPRINTS.MBIN. This will add the blueprint into the vendor’s list in the planetary player base;

* **Rewards**: adding the blueprint into REWARDTABLE.MBIN. This will add the blueprint as a reward from interacting with various objects in game, such as dead sentinels, alien conversations, and custom objects.

#### Adding entry into Default Save Data

As we did at the beginning of the tutorial, open NMS Modding Station, locate **DEFAULTSAVEDATA.MBIN** and **DEFAULTSAVEDATACREATIVE.MBIN** in **METADATA\GAMESTATE** and copy both files to your project location. After doing this, decompile them and open either one of the files. Search for the nested property “**KnownProducts**”, copy and paste an “**NMSString0x10.xml**” entry to create a duplicate. The entry should look something like this:

```
<Property value="NMSString0x10.xml">
  <Property name="Value" value="TESTTABLE" />
</Property>

```

Edit the “**Value**” value, and copy the entry to the other default save file under the **KnownProducts** property. In other words, make sure that both files have the same entry.

#### Adding entry into Vendor's List

Navigate to **METADATA\REALITY\TABLES** to find **PURCHASEABLEBUILDINGBLUEPRINTS.MBIN**. Decompile it and open it with your text editor. Copy and paste an “**NMSString0x10.xml**” entry. The entry should look something like this:

```
<Property value="NMSString0x10.xml">
  <Property name="Value" value="`TESTTABLE`" />
</Property>

```

Edit the “**Value**” value to whatever you prefer.

**NOTE:** No Man's Sky hides every 6th entry of this table. If your added entry is hidden in game, create a dummy entry in NMS\_REALITY\_GCPRODUCTTABLE.MBIN, and reference it in the slot in PURCHASEABLEBUILDINGBLUEPRINTS.MBIN which would be hidden by the game.

#### Adding entry into Rewards

(Due to the sophistication and many ways of adding entries into **REWARDTABLE.MBIN**, new entry should be created.)

## Finally, Compile Your Mod!

Now you have completed all the necessary steps to have your buildable table ready. We now have to compile the mod. For information on how to do it, check here.