Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions .vitepress/sidebars/developers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,18 @@ export default {
},
],
},
// TODO - Finish
// {
// text: "API Documentation",
// link: "/developers/api-docs",
// },
{
text: "API Documentation",
// TODO: Write the API Docs page
// link: "/developers/api-docs",
collapsed: true,
items: [
{
text: "Custom Recipes",
link: "/developers/api-docs/recipes",
},
]
},
{
text: "Useful Tags",
collapsed: true,
Expand Down
327 changes: 327 additions & 0 deletions developers/api-docs/recipes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
---
title: Custom Recipes
description: How to write recipes for Create using datapacks and KubeJS.

next: false
---

# Custom Recipes
***Creating Custom, Creative Recipes with Create***

Create, like Vanilla and plenty of other mods, uses the Datapack JSON format introduced in 1.13.
This lets you further customize Create for whatever modpack you're playing with it on.
This article will describe how to [set up your datapack](#getting-started),
[add recipes with JSON](#adding-a-recipe),
and [add recipes with other mods](#adding-recipes-with-other-mods).

## What even *is* a Datapack?
Datapacks are a Vanilla-provided method to modify, add, and remove certain content from the game.
This includes World Generation, Advancements, Command Functions, Block/Mob/Loot drops,
and much more—more "data-driven" aspects of the game are added every Minecraft update.

We will be modifying Recipes with datapacks here.

If you want to learn more about Data Packs, we recommend reading up on the [Minecraft Wiki](https://minecraft.wiki/w/Data_pack).

## What do I need?
You will need basic knowledge on how to write JSON and how to create a Datapack in order to create your recipe.
You can study the [Creating a Datapack](https://minecraft.wiki/w/Tutorial:Creating_a_data_pack) page on the Minecraft Wiki and get the following tools:

### Applications
- Text Editor: Most operating systems nowdays usually provide this (Notepad on Windows, TextEdit on Mac, and it varies on Linux), but we recommend getting a fancier tool suited for code like this, like [VSCode](https://code.visualstudio.com/) and [Notepad++](https://notepad-plus-plus.org/). These will highlight your code and point out any *syntax* errors you have made in your JSON.

### Mods (Optional)
- [JEI](https://modrinth.com/mod/jei) **(Recommended)**: lets you quickly preview your recipes in-game without having to attempt making them.
- [Paxi](https://modrinth.com/mod/paxi) (Fabric+NeoForge): If you're a modpack creator or wish to test in multiple worlds at once, Paxi can let you load datapacks globally.
- [KubeJS](https://modrinth.com/mod/kubejs) (Neoforge): KubeJS lets you write JavaScript to add recipes with a bit more automation and ease than manually writing them. It also lets you add items for your recipes and functions as another global datapack loader.
- [KubeJS Create](https://modrinth.com/mod/kubejs-create/) is an addon for Create and KubeJS that allows you to make recipes even quicker. Base KubeJS can still do this with custom recipes, however.

## Getting Started
Once again, you should check out the [Creating a Datapack](https://minecraft.wiki/w/Tutorial:Creating_a_data_pack) page on the Minecraft Wiki. This provides good information on how to set up your datapack. However, **the wiki always reflects the latest version of Minecraft**, and you may encounter differences in the format between Minecraft versions.

:::info
This article details creation of recipes for NeoForge 1.21.1.
:::

![A screenshot of Finder, showing the basic structure of a datapack including the recipe and tags folder](/media/developers/api-docs/recipes/pack_blank.png?url)
This will be the basic structure of your datapack. Remember that the `recipe` folder is named `recipes` **before 1.21**.

`my_datapack_id` is an Alphanumeric string, **including** `_`. Change it to fit the **datapack** you're making, not the **mod** your recipes are targeting.

You also need a `pack.mcmeta` for your datapack to load.
```json [pack.mcmeta]
{
"pack": {
"pack_format": 48,
"description": "An example Create datapack"
}
}
```

When you have created your datapack, run `/reload` in chat.
This command requires Operator—it's a quick way to reload your recipes and tags without rejoining/restarting your server.

To confirm that your datapack has loaded, run `/datapack list`. If it doesn't show up on the list, check your setup; if it shows up red, run `/datapack enable "file/my_datapack_id"`.

[An example datapack setup with these recipes can be found here.](https://github.com/vercte/example_create_datapack)

## Adding a Recipe
This is where knowing JSON really comes in. For a guide on writing a Vanilla recipe, see the Minecraft Wiki for the [Vanilla Recipe Format](https://minecraft.wiki/w/Recipe).

To start, add a recipe to the Recipes folder, optionally inside a folder for organization:
![Almost the same Finder screenshot, now including recipe/deploying/enchanted_golden_apple.json](/media/developers/api-docs/recipes/pack_with_recipe.png?url)

This will be a **deploying** recipe.
```json [enchanted_golden_apple.json]
{
"type": "create:deploying",
"ingredients": [
{
"item": "minecraft:golden_apple"
},
{
"item": "create:experience_block"
}
],
"results": [
{
"id": "minecraft:enchanted_golden_apple"
}
]
}
```
Upon `/reload`, JEI will show this recipe:
![A deploying recipe, showing a Block of Experience being deployed on a Golden Apple to make an Enchanted Golden Apple.](/media/developers/api-docs/recipes/deploying_enchanted_golden_apple.png?url)

Congratulations! That's your first recipe!
Recipe types that use this format, with one input:
- Milling (millstone, crushing wheels) `create:milling`
- Crushing (crushing wheels) `create:crushing`
- Cutting (mechanical saw) `create:cutting`
- Deploying (deployer) `create:deploying`
- Haunting (soul fire, encased fan) `create:haunting`
- Splashing (water, encased fan) `create:splashing`
- Sandpaper Polishing (sandpaper) `create:sandpaper_polishing`
- Item Application (by hand; e.g. andesite casing) `create:item_application`

## Fluid Ingredients
Recipes that use a basin (compacting, mixing) and recipes that use a spout or item drain can have fluids in the recipe.
Recipes that take in **one** item and **one** fluid always include both in `ingredients`, in that order.

Another example recipe, for the Spout this time, in `recipe/filling/exposed_copper.json`:
```json [exposed_copper.json]
{
"type": "create:filling",
"ingredients": [
{
"item": "minecraft:copper_block"
},
{
"type": "fluid_stack",
"amount": 1000,
"fluid": "minecraft:water"
}
],
"results": [
{
"id": "minecraft:exposed_copper"
}
]
}
```

And the resulting recipe:
![A spouting recipe, showing a bucket of water being spouted on a Block of Copper to make Exposed Copper.](/media/developers/api-docs/recipes/filling_exposed_copper.png?url)

The key part here is the fluid ingredient:
```json
{
"type": "fluid_stack",
"amount": 1000,
"fluid": "minecraft:water"
}
```
`amount` is in Millibuckets, which means 1,000 millibuckets is a full bucket.
:::warning
On Fabric, fluid measurement uses Droplets instead, with 81,000 droplets to a bucket.
:::

## Extra Arguments
`heat_requirement`: Only Basin Recipes have this property. This can be `none`, `heated`, or `superheated`, and reflects blaze heating below it. This should be omitted on recipes that don't support it, and it can be omitted if `none`.

`processing_time`: Only applies to `create:milling`, `create:crushing`, and `create:cutting`. How long this duration really is in-game varies between recipe types and how fast the machines are running.

`chance` (inside a result): The chance, out of 100, that this result will be yielded.

## Sequenced Assembly
Sequenced Assembly is a much more complicated Create Recipe, involving a parent recipe and multiple processing recipes nested inside it.

They take in one ingredient (`ingredient`), turn it into a transitional item (`transitional_item`) during processing, and turn it into the results at the end.

A basic rundown of the arguments:
- `loops`: Required. How many times the sequence has to be done.
- `sequence`: Required. A list of compatible processing recipes to include in the sequence.
- These recipes have to return the `transitional_item` as a result.
- Valid recipes: `create:pressing`, `create:cutting`, `create:deploying`, `create:filling`
- If you want to make your own custom recipe types compatible with this, implement `IAssemblyRecipe`.
- `transitional_item`: The item to use while the recipe is in-progress (like the Incomplete Precision Mechanism).
- This can be any item, but if you want the custom progress bar, your item has to be a `SequencedAssemblyItem`.

Here's how Create uses it for the Sturdy Sheet:
```json [sturdy_sheet.json]
{
"type": "create:sequenced_assembly",
"ingredient": {
"tag": "c:dusts/obsidian"
},
"loops": 1,
"results": [
{
"id": "create:sturdy_sheet"
}
],
"sequence": [
{
"type": "create:filling",
"ingredients": [
{
"item": "create:unprocessed_obsidian_sheet"
},
{
"type": "fluid_stack",
"amount": 500,
"fluid": "minecraft:lava"
}
],
"results": [
{
"id": "create:unprocessed_obsidian_sheet"
}
]
},
{
"type": "create:pressing",
"ingredients": [
{
"item": "create:unprocessed_obsidian_sheet"
}
],
"results": [
{
"id": "create:unprocessed_obsidian_sheet"
}
]
},
{
"type": "create:pressing",
"ingredients": [
{
"item": "create:unprocessed_obsidian_sheet"
}
],
"results": [
{
"id": "create:unprocessed_obsidian_sheet"
}
]
}
],
"transitional_item": {
"id": "create:unprocessed_obsidian_sheet"
}
}
```
![A sequenced assembly recipe for the Sturdy sheet, showing Obsidian dust having lava being spouted on it and then pressed two times.](/media/developers/api-docs/recipes/sequenced_sturdy_sheet.png?url)

Writing Sequenced Assembly recipes can get quite tedious and prone to mistake, so it's advised to [set up Data Generation] for them if you're developing an addon.

## Modifying/Removing recipes with Datapacks
If you want to remove recipes with a datapack, you can use the `filter` section of your `pack.mcmeta`.
This section allows you to specify the IDs of recipes you would like to remove.

```json
{
"pack": {
"pack_format": 48,
"description": "An example Create datapack"
},
"filter": {
"block": [
{
"namespace": "create",
"path": "recipe/mixing/brass_ingot"
},
{
"namespace": "create",
"path": "recipe/mixing/andesite_alloy.*"
}
]
}
}
```
This example removes the recipes for the Brass Ingot and Andesite Alloy (from both Iron and Zinc nuggets) via mixing.

`filter.block` is an array which accepts an object with two optional keys:
- `namespace`: The namespace (`create`) in which the resource you want to remove is included. If unspecified, it applies to every namespace.
- `path`: The path (`recipe/mixing/brass_ingot`) where the resource you want to remove is located. If unspecified, it applies to every resource.

*These can be [regular expressions](https://en.wikipedia.org/wiki/regular_expression), if you know how to use them.*

If you wish to modify a recipe, remove it using this method and re-create the recipe in your datapack with
whatever modification you wish to apply.

## Managing Recipes with Other Mods
You can avoid datapack setup using mods like KubeJS and CraftTweaker to modify parts of the game.

### KubeJS
:::info
This section will assume you know JavaScript.
:::
[KubeJS](https://kubejs.com) is a mod that lets you write JavaScript to customize the behavior of your modpack.
Upon installing it and launching a world with it installed for the first time, a `kubejs` folder will be created
with a `server_scripts` directory inside it. This is where our recipe script will go.

We can listen to the `ServerEvents.recipes` event, which lets us add recipes using JavaScript.
This also lets us script the creation of recipes, instead of manually fully creating them.
Without an addon like [KubeJS Create](https://modrinth.com/mod/kubejs-create/), this uses the
[JSON format](#adding-a-recipe) inside `event.custom`.

Inside your script, placed inside the `.minecraft/kubejs/server_scripts` directory:
```js
ServerEvents.recipes(event => {
event.custom({
type: "create:deploying",
ingredients: [
{
item: "minecraft:paper"
},
{
item: "minecraft:light_blue_dye"
}
],
results: [
{
id: "create:empty_schematic"
}
]
});
});
```
Using the Deploying JSON format, this adds a recipe for the Empty Schematic:
![A deploying recipe, showing Light Blue Dye being deployed on Paper to make an Empty Schematic.](/media/developers/api-docs/recipes/deploying_empty_schematic.png?url)

To remove recipes, we can use `event.remove`, which you provide a filter to:
```js
ServerEvents.recipes(event => {
event.remove({ output: "create:andesite_alloy" }); // Removes all recipes with the output of Andesite Alloy
event.remove({ input: "minecraft:iron_nugget" }); // Removes all recipes that take in an Iron Nugget
event.remove({ type: "create:deploying", input: "#minecraft:planks" }) // Remove all Deploying recipes that take in wooden planks
event.remove({ not: { type: "create:mixing", input: "create:zinc_ingot" }}) // Remove all Mixing recipes that DO NOT take in Zinc Ingot
});
```
You can also pass in an array of objects to `event.remove` for multiple operations at once.
The object passed in checks for any property of a recipe that matches it, barring the `not` object.

:::info
The [Official KubeJS Tutorial for Editing Recipes](https://kubejs.com/wiki/tutorials/recipes) is a great place to learn more about this.
:::
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.