Tutorial: Adding a Recipe

From The Stardew Modding Wiki
Jump to navigation Jump to search

It is very easy to add recipes to Stardew Valley using Category:Json Assets. You can use Vanilla items or items you or another mod you have installed created with JA.

If you would like to make a video based on this tutorial, you are welcome to do so! Afterwards, please edit the page to add a link to your video for users who prefer to learn that way. :)

Future infobox info: CopperSun, May 6 2021

Getting Ready[edit | edit source | hide | hide all]

  1. Install Smapi if you haven't already.
  2. Install Json Assets.
  3. Get Notepad++, Visual Studio, or another text editing program designed for reading code. (You'll be using it for Json files.)
  4. Look over the official documentation for Json Assets recipes.

Finding Examples[edit | edit source | hide]

Examples are really the key to understanding any mod or coding project. Fortunately, there are plenty available.

  1. A good mod to start with is Milkshakes, which adds six basic recipes using vanilla ingredients and shows how to use an item category ("Milk: Any").
  2. To see how to combine a new crop with new recipes, take a look at Cocoa Plant and Chocolate Cooking.
  3. This tutorial was developed in conjunction with the Okay Recipes mod. While that mod is a convenient, simple example, it also takes advantage of some odd game code regarding categories which causes the recipes to look a little funny. Once you understand how recipes work, however, it will make perfect sense what's happening. :)

Creating a Manifest[edit | edit source | hide]

Every mod needs a manifest, so let's make ours!

  1. First, create a new folder in Stardew Valley\Mods and name it whatever you want your mod to be called. "Recipe Test" is a perfectly fine name for now.
  2. In this folder, create a new file called "manifest.json"
    1. You can create this file any way that works for you. I usually right-click inside of the folder and choose "New->Text Document" and then rename the file (including the extension!). You could also create it by choosing "New" inside your text editing program of choice.
  3. Open manifest.json in your editing program. I'll be using Notepad++.
    1. We're starting with the Manifest because it is short, easy, and every mod needs one to run with Smapi.
    2. The manifest documentation on the official wiki is very clear and simple, so start by looking at that.
  4. Here what we'll be using:
    {
       "Name": "Your mod name",
       "Author": "Your user name",
       "Version": "1.0.0",
       "Description": "Short description of your mod.",
       "UniqueID": "YourName.YourModName",
       "UpdateKeys": [],
       "ContentPackFor": {
          "UniqueID": "spacechase0.JsonAssets",
      }
    }
    
  5. It's important to include the first { and last }. These brackets/braces (technically "curly braces" if you have a pedantic friend) tell Smapi where your file begins and ends. All json files utilized by SMAPI use them.
  6. Copy that text into your manifest.json file exactly as it appears. Change the appropriate text to be for your own mod.
    1. Version is what version of your mod you are on. Generally, you will start with 1.0, then if after you release your mod you have an update you might call that 1.1, and so on. The version number in the manifest is how Smapi can tell if your mod has a newer version available or not.
    2. Leave UpdateKeys empty for now (but make sure to keep the "[ ]"!). You can fill it in later with a key from Nexus or wherever you release your mod.
    3. It's very important to list any frameworks that your mod requires to run in the ContentPackFor section. We're using Json Assets, so you can see that that is listed with its UniqueID of "spacechase0.JsonAssets".
  7. Save your file.
  8. Triple-check that you got all the right brackets and commas in the right places by uploading your manifest.json file at https://smapi.io/json.
  9. Congrats! You just made a json file and that counts as programming. :)



Creating Your Recipe[edit | edit source | hide]

Now we get to actually get cooking programming!

Go into your folder ("Recipe Test" or whatever you named it) and create a new folder inside of it. Name this folder "Objects".

  1. All new JA objects go in a folder named accordingly. If we were making crops, we'd make a folder called "Crops".
  2. No, you can not name this folder anything but "Objects". It's very important. Get the capitalization right, too.
  1. Folder structure for your recipes. "Recipe Test" is the name of your mod in this scenario.
    Inside your Objects folder, make another folder. This one should be the name of your recipe. Your folders should now look something like the picture on the right, except instead of "Basic Smoothie" and "Quick Veggie Stew" you'll have whatever you want your own recipes to be.
  2. Let's say your recipe is for "Garlic Green Beans" and the recipe calls for 2 green beans, 1 garlic bulb, and 1 bottle of oil. (This is, by the way, a delicious dish you can order at Chinese restaurants, though they probably just call it green beans). In that case, name your folder "Garlic Green Beans"
  3. Inside your recipe folder, create a new file called "object.json." Do this the same way you made your manifest.json file earlier.
    1. This is how all JA objects work. You name the folder what the item is, and in that folder you put an object.json file (and a picture, but we haven't gotten that far yet).
  4. Open up object.json in your text editor (again, I'll be using Notepad++) and copy in all this code exactly. It looks a little long, but that's just because we're spelling out a lot of effects very specifically.
    {
    	"Name": "Garlic Green Beans", //The name of our recipe and what it produces
    	"Description": "Green beans fried with oil and garlic. Yummy!", //A description which will appear when you click on the item
    	"Category": "Cooking", //This goes in the cooking menu, not the crafting menu
      
    	"Edibility": 60, //This will set how much health your recipe will give when consumed. The exact math is a little arcane, and also affects the energy gained.
    	"EdibleIsDrink": false, //This is food, so it's not a drink. Drinks and food can both give buffs at the same time.
      
    	"EdibleBuffs": {
    					"Farming": 0,
    					"Fishing": 0,
    					"Mining": 0,
    					"Luck": 0,
    					"Foraging": 0,
    					"MaxStamina": 0,
    					"MagnetRadius": 0,
    					"Speed": 0,
    					"Defense": 2, //Our garlic green beans will buff defense by 2
    					"Attack": 0,
    					"Duration": 120, //The buff will last for 120 seconds (aka 2 minutes)
      },
      
    	"Price": 150, //Selling garlic green beans will give 150g
      
    	"IsColored": false, //there aren't different colored vesions of our dish
      
    	"Recipe": {
    			  "ResultCount": 1, //Making this recipe will give you ONE dish of garlic green beans
    			  
    			  "Ingredients": [
    								{
    								   "Object": "Green Bean", //This recipe requires green beans
    								   "Count": 2, //specifically, it requires 2 of them
    								},
    								{
    								   "Object": "Garlic", //It also requires one garlic bulb
    								   "Count": 1,
    								},
    								{
    								   "Object": "Oil", //And one bottle of oil
    								   "Count": 1,
    								}
    			      ],
    			   
    			   "IsDefault": "False", //The player does not know this recipe by default at the start of the game
    			   
    			   "CanPurchase": "True", //this recipe can be purchased
    			   "PurchaseFrom": "Gus", //This recipe can be bought from Gus			   
    			   "PurchasePrice": 100, //Gus will charge a mere 100g for this recipe
    			   
    			   "PurchaseRequirements": ["f Gus 250"], //The player must have 1 heart (250 friend points) with Gus before the recipe will be available.
    			},
      
    	"GiftTastes": { //Anyone we do not set will default to how they feel about cooking in general. As cooking is a 'universal like,' most NPCs gifted our green beans will like them.
    					"Love": [ "Pam", "Alex", ], //Pam and Alex will love our recipe
    					"Like": [ "Leah", "Lewis", ], //Leah and Lewis will like it
    "Neutral": [ "Emily", ], //Emily feels neutral about our dish
    					"Dislike": [ "Jas", "Vincent", ], //Jas and Vincent dislike our recipe
    					"Hate": [  "Haley", ],	//Haley will hate our dish
    	},
    }
    
  5. First, some general notes about jsons:
    1. Just like manifest.json, object.json needs to start with { and end with }.
    2. Json files don't care about "white space" (blank spaces) unless they're inside quotation marks. Most people prefer to line up brackets visually so it's easy to see where they go.
    3. Any text following // is a "comment," which means it is not read by the program. You can put whatever comments you want in your code. It's a good idea to remind yourself what each section does!
  6. "Name": "Garlic Green Beans",
    1. This is not just the name of our dish and recipe, but how JA and the game will identify our recipe in any other mods.
    2. It is important that this name be unique - if another mod also tries to add "Garlic Green Beans", Smapi will give an error and neither will be added.
    3. Notice that each of these lines uses a key and a value. The key is the first part in quotation marks - "Name" - and the value is the second part - "Garlic Green Beans". You will see this in approximately every json file ever.
  7. "Description": "Green beans fried with oil and garlic. Yummy!",
    1. This is flavor text (pardon the pun). Write whatever you want here, but don't make it too long or people with smaller monitors will have trouble reading everything when they look up your item.
  8. "Category": "Cooking",
    1. Your recipe can be for food (cooking) or other stuff (crafting). This determines which menu it will go in. Since we are making a food dish with food, this is obviously "Cooking".
  9. "Edibility": 60,
    1. This determines how much health the player will regain when the consume our garlic green beans. The math is a little arcane, so see the official wiki for a proper breakdown. Generally, just put a lower number for less health and a higher number for more health. :)
    2. This will also determine how much energy the player regains, again using arcane math so again look at the official wiki if you want to be super precise about the energy in your dish.
  10. "EdibleIsDrink": false,
    1. Is this a drink? No, it's not, so we set this value to false.
    2. This mostly comes into play regarding buffs. A player can have buffs from one food item and one drink item at the same time, but consuming a new food will override the previous food's buffs.
  11. "EdibleBuffs": {
    1. This is an array of all the possible buffs our recipe can have. Our garlic green beans have set "Defense": 2, so the player will receive a +2 to defense. We could theoretically give buffs to every stat, but that not only tends to get overpowering quickly but also looks unwieldy on the screen. But your recipes' effects are up to you!
    2. The last line in the array is "Duration": 120, This is how long our buffs will last in seconds. We've set the duration to 120 seconds, so the buff will last for two minutes.
    3. Don't forget that because this is an array we need that closing brace and comma!
  12. "Price": 150,
    1. These garlic green beans will fetch 100g when sold via the shipping bin or to any shop that will buy them.
  13. "IsColored": false,
    1. You know how tulips and some other items in the game can be different colors? If our garlic green beans could also be yellow or red we would set this to true, but because our dish will always look the same green color we set this to false.
  14. "Recipe": {
    1. Okay, this is the heart of the recipe, the recipe section! Notice that opening {, we'll need a closing one later.
    2. We're going to be specifying several things here, so make sure you're careful with your braces and commas so that Smapi knows exactly what you want to have happen.o
  15. "ResultCount": 1,
    1. This is how many plates of garlic green beans the player will get when using our recipe. For most recipes, it's just 1.
  16. "Ingredients": [
    1. Here we have the start of our ingredients array. We're going to list each ingredient and how many of it is required for our recipe.
    2. As always, we'll need a closing ] later to let Smapi know when we're done with this array.
  17. {
    1. Notice that each ingredient and count is enclosed in a pair of braces, and a comma follows each closing brace. This is how Smapi knows which count goes to which ingredient.
  18. "Object": "Green Bean",
    1. Our recipe has three ingredients: green beans, garlic, and oil. Here we are specifying the green beans.
    2. There are three ways to do this!
      1. Name - We have used the ingredient's name ("Green Bean"). We must get the spelling and capitalization exactly right when using this method. If we had an ingredient created by a mod - say, a purple bean, we could use that name the exact same way, "Purple Bean". This is why JA and Smapi will not let you have duplicate item names.
      2. Item ID - We also could have used its ID number, 188. If you do this, you don't need the quotation marks and our code would look like "Object": 188,. Because of the way JA currently works, item IDs are set at game load so you can not use an item ID with a modded item.
      3. Category - If our dish was called "Garlic Vegetables", we could have used the vegetable category, -74, instead to require 2 vegetables of any kind. There are three categories that vanilla SDV recognizes for cooking: -5 shows as "Egg (Any)", -6 shows as "Milk (Any)" and -4 is "Fish (Any)". You can still use the other categories, but you will get some weird displays as seen in Okay Recipes.
  19. ],
    1. We're closing our ingredients array, but we're still inside the recipe braces here.
  20. "IsDefault": "False",
    1. This sets whether the player knows this recipe by default at the beginning of the game. False means the player will have to buy it, learn it from an NPC, or otherwise acquire the recipe.
  21. "CanPurchase": "True",
    1. Our recipe is available to be purchased. If not, we would set this to "False".
  22. "PurchaseFrom": "Gus",
    1. Our Recipe can be purchased from our good friend at the saloon, Gus. For a list of other options, see the JA documentation.
  23. "PurchasePrice": 100,
    1. Gus will sell us the recipe for the very reasonable price of 100g.
  24. "PurchaseRequirements": ["f Gus 250"],
    1. Before Gus will sell us the recipe, however, we must have at least one heart (250 friendship points) with him.
    2. For a list of event conditions, see the official wiki.
  25. },
    1. Now we're finally done with the recipe section of our recipe and can move along - after we close our brace, of course!
  26. "GiftTastes": {
    1. In the gift tastes section, we can specify who loves and hates our dish.
    2. Naturally, any NPC listed in the love section will love the dish, in the like section will like the dish, and so on.
    3. You can even name custom NPCs here, like Sophia from SVE. If the player does not have that NPC installed, Smapi will just ignore the code.
      1. Yes, this is another example of why everything and everyone needs unique names in your mods
    4. If you do not specify if an NPC likes the dish, they will default to neutral - unless they have a category preference. And it so happens that "cooking" as a category is a universal like. Therefore, most NPCs will "like" any recipes you make unless you specify otherwise.

Setting up Localization Options[edit | edit source | hide]

  1. If you'd like to make your mod compatible with translations (recommended!), add the following to your object.json file:
    	  "NameLocalization": {
        // "es": "",
        // "ko": "",
        // "de": "",
        // "fr": "",
        // "hu": "",
        // "it": "",
        // "ja": "",
        // "pt": ""
        // "ru": "",
        // "tr": "",
        // "zh": ""
      },
      "DescriptionLocalization": {
        // "es": "",
        // "ko": "",
        // "de": "",
        // "fr": "",
        // "hu": "",
        // "it": "",
        // "ja": "",
        // "pt": ""
        // "ru": "",
        // "tr": "",
        // "zh": ""
      }
    
  2. The languages are:
    1. ES: Spanish (Español)
    2. KO: Korean (한국어)
    3. DE: German (Deutsch)
    4. FR: French (Français)
    5. HU: Hungarian (Magyar)
    6. IT: Italian (Italiano)
    7. JA: Japanese (日本語)
    8. PT: Portuguese (Português)
    9. RU: Russian (русский)
    10. TR: Turkish (Türkçe)
    11. ZH: Chinese
  3. You can use hyphenated codes to distinguish between different dialects: for example, pt-BR refers to Brazilian Portuguese and zh-CN refers to Simplified Chinese.
  4. Remove the // for any languages you want to add and put the name and description inside the quotes. For example, here is a JA item that adds a Japanese translation:
    "NameLocalization": {
        // "es": "",
        // "ko": "",
        // "de": "",
        // "fr": "",
        // "hu": "",
        // "it": "",
         "ja": "スズキ",
        // "pt": ""
        // "ru": "",
        // "tr": "",
        // "zh": ""
      },
      "DescriptionLocalization": {
        // "es": "",
        // "ko": "",
        // "de": "",
        // "fr": "",
        // "hu": "",
        // "it": "",
         "ja": "スズキを 釣り上げた! 鈴木…じゃなくて、鱸なのね!",
        // "pt": ""
        // "ru": "",
        // "tr": "",
        // "zh": ""
      }
    
  5. A couple of closing braces and that concludes our code! But we're not quite done yet...

Illustrating Your Recipe[edit | edit source | hide]

  1. Last but not least, it's time to figure out what your dish will look like.
    1. There are a lot of ways to go about this, but this is the basic method. I am not very good at art so I don't have a lot of suggestions for making your food look tasty. :(
  2. First, either unpack the game files (quick and easy) or hit the wiki and find a recipe that looks close enough to what you want to base your new recipe on.
    1. If you unpacked the content, open up the file Stardew Valley\Content (unpacked)\Maps\springobjects.png and find a dish to base your own on. Does it make sense that all sorts of random things are in that one png? No, but that's where they are anyway. ¯\_(ツ)_/¯
  3. Now open up a new file in the photo editing program of your choice. Many people swear by Aesprite, Photoshop will work great, Gimp, whatever. Just make sure it's capable of transparency (where the image is on a transparent background, not a solid white one).
  4. Click "new" and make a png that's 16 pixels by 16 pixels exactly.
  5. Copy the dish you're using as an example into your new 16 x 16 square. If you grabbed it from springobjects.png, it should fit perfectly.
  6. Color it to look however you want.
    1. If you're really bad at art and just want to put in a placeholder for now while you test your recipe, it's perfectly fine to just make a red rectangle or something. The game doesn't care and won't judge your interpretation of what "Garlic Green Beans" looks like.
  7. When you're done, save your transparent 16x16 pixel png to the same folder as your object.json file. Name it "object.png" exactly.
    1. This is how JA will know that this picture goes with the recipe you just made in object.json.
  8. That's it! You're done! Load up Smapi and give your recipe a try!

What's next?[edit | edit source | hide]

You can add any number of recipes to the same mod. Just make sure each recipe gets its own folder inside the Objects folder and that each recipe has its own object.json and object.png. You can also look at other cooking mods for ideas, and read through the Json Assets documentation for options not covered in this introductory tutorial. Once you've made some recipes, you might also be interested in sending them via the mail, which is very easy with Category:Content Patcher. Get creative!

PS: Interesting in writing a tutorial for this wiki? We'd love to have you! No qualifications are needed. Just create a new page, call it "Tutorial: Doing a Thing" (name as appropriate), and start sharing your knowledge. :)