Tutorial: Adding a New Crop
A simple 1.6 guide to adding a new crop to the game using Content Patcher, adapted from 6480's Mouse-Ear Cress example.
Setting Up
The rest of this guide assumes you are aware of how to make a Content Patcher mod, but if not follow these steps first:
- Install SMAPI if you haven't already
- Install Content Patcher.
- Read the author guide for Content Patcher and try making a basic Content pack.
Additionally, it's recommended that you:
- Use a text editor with Json support, for example Visual Studio Code and Notepad++.
- Unpack the game files so that you can understand the layout of the data, in particular take a look at
Data/Objects
andData/Crops
. Crops also have a specific number of sprites that are allowed, and the base game crops serve as a good template. - Become comfortable with using debug commands from the SMAPI console, here are some relevant commands:
world_clear current removable
: clears every removable thing in your current area, useful for clearing your test save's farmdebug sleep
: instantly pass the daypatch reload <YourModUniqueId>
: reload your mod without quitting the game
Loading the Textures
First, we will need the sprites. For clarity and simplicity we put the objects on 1 sprite, and the crop on another sprite. Object sprites are 16x16 each, and crop sprites consist of up to 8 16x32 sprites (128x32 total). The first 2 sprites are seed variations, followed by up to 5 sprites for growth phases, and a final sprite reserved for regrowing crops.
To put these assets into the game, we need to do a Load to an asset name, prefixed with {{ModId}}
so that you don't conflict with another mod.
{
"Format": "2.7.0",
"Changes": [
{
"Action": "Load",
// Multiple textures at once for convenience. If you want, you can list one at a time with one "load" action block for each.
"Target": "{{ModId}}/objects, {{ModId}}/crops",
//Target is the custom texture name to use. This needs to be unique between mods, so it is highly recommended to include your *unique mod Id* as part of the path. Texture name can be anything
//You can also include multiple items or crops on the same spritesheet.
"FromFile": "assets/{{TargetWithoutPath}}.png"
//Using {{TargetWithoutPath}} automatically pulls from the .png image with the same name as the texture
//In this case, "assets/objects.png" and "assets/crops.png". You can use any folder name as long as your image and code match.
},
]
}
From this point on, we will refer to our two textures as {{ModId}}/objects
and {{ModId}}/crops
Adding Crop Objects
Then, let's add our objects: the seed, and the produced item. Generally you should use {{ModId}}_YourItem
format when assigning item ids so that your item won't override anyone else's.
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Objects",
"Entries": {
// SEED ITEM
"{{ModId}}_PhilSeeds": {
"Name": "{{ModId}}_PhilSeeds",
"Displayname": "{{i18n:PhilSeeds.name}}",
"Description": "{{i18n:PhilSeeds.description}}",
"Type": "Seeds",
"Category": -74, //crop seeds must be category -74 to plant crops
"Price": 40,
// Texture must exactly match the name of one of your loaded textures, NOT your .png
"Texture": "{{ModId}}/objects",
// Tells the game what position on the spritesheet (in this case, objects.png) to look for your item. Indexes start at 0.
"SpriteIndex": 0,
}
// PRODUCED ITEM
"{{ModId}}_Phil": {
// This is the internal name of the item, not the name shown to players.
// It is ecommended to match your Item ID exactly to prevent confusion with cooking/crafting recipes, but it can be anything.
"Name": "<nowiki>{{ModId}}_Phil",
// DisplayName and Description are set with i18n, so that they can be translated
// These i18n keys are automatically linked to the data in the i18n folder for translation purposes. If you dont intend to ever translate your mod, you can just put a normal string here instead, like "The Captured Essence of Early Spring"
// i18n keys only need to be unique inside your mod
"Displayname": "{{i18n:Phil.name}}",
"Description": "{{i18n:Phil.description}}",
"Type": "Basic",
// The category of Phil is flowers
"Category": -80,
// Money earned when player sells it
"Price": 100,
"Edibility": 5,
"Texture": "{{ModId}}/objects",
"SpriteIndex": 1,
// By default crops count for shipping, but this can be set to true if you don't want that
"ExcludeFromShippingCollection": false,
}
}
},
]
}
Adding the Crop
For our seed to become plantable, we must add the Data/Crops
entry matching the seed.
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Crops",
"Entries": {
"{{ModId}}_PhilSeeds": { //this must EXACTLY match the item id of your seeds item
// The crop grows in all 3 seasons
"Seasons": [
"spring",
"summer",
"fall"
],
// The crop has 5 phases that each takes 1 day, making it 5 total days to harvest
"DaysInPhase": [ // First two seed sprites on the crop image are not counted as a phase, instead they are seed variants
1,
1,
1,
1,
1
],
// For this example, we made a regrowable crop. Non regrowable crops use -1 in this field
// Regrowing crops show the second to last sprite when they have produce, and the final sprite when they are regrowing
"RegrowDays": 5,
"HarvestMinStack": 1,
"HarvestMaxStack": 2,
"HarvestItemId": "{{ModId}}_Phil",
"Texture": "{{ModId}}/crops",
"SpriteIndex": 0,
// Crops do not count for either of these achievements unless the corresponding field is set
"CountForMonoculture": false,
"CountForPolyculture": false,
}
}
},
]
}
Sell the Seed at a Shop
The player needs a way to obtain their seeds, shops is the typical place for this.
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Shops",
// Since Carpenter is an existing shop, we need to avoid overwriting the entire entry and only add 1 new item
"TargetField": [
"Carpenter",
"Items"
],
"Entries": {
// Add the seed item to robin's shop
"{{ModId}}_PhilSeeds": {
"Id": "{{ModId}}_PhilSeeds",
"ItemId": "{{ModId}}_PhilSeeds"
}
},
"MoveEntries": [
{
// Move the new seed entry in Robin's shop higher up. Optional
"Id": "{{ModId}}_PhilSeeds",
"AfterID": "(BC)200"
}
]
}
]
}
At this point, you have created a crop!