Skip to content

Introduction to Patching

EnderTurret edited this page Nov 7, 2024 · 1 revision

If you're new here, welcome to Patched! Writing patches can seem intimidating at first, but this guide aims to introduce the patching process step by step until (hopefully) you're comfortable enough to write your own patches.

Let's start with setting up Patched, so that we have an environment we can write patches in. (Modders may skip this step if they do not have a pack.mcmeta file.)

First, we'll need to enable patching in our data (or resource) pack, like so:

// pack.mcmeta
{
  "pack": {
    // ...
  },
  "patched": {
    "format_version": 1
  }
}

The important part is the patched block we've added to our pack.mcmeta. It tells Patched that this pack (or mod) would like to patch things — and is required for doing so. The format_version identifies the Patched metadata schema version, or in other words, what version of Patched the pack is written for. Patched will refuse to load packs written for newer format versions, and may have limited support for older ones.

Note

In older versions of Patched (older than 5.1.0+1.20.4 and 3.3.0+1.20.1), enabling patching works somewhat differently. Instead of the patched block, one has this stanza:

// pack.mcmeta
{
  "pack": {
    // ...
    "patched:has_patches": true
  }
}

If you would like your pack to run on say, 1.19.2, you will need to add this to your pack.mcmeta in addition to the patched block.

In any case, now that we have enabled patching, we now need something to patch. For this guide we'll do something interesting: making amethyst geodes generate in the Nether. Here's the pack so far:

Nether Geodes
├ data
└ pack.mcmeta

Now, how do we write a patch? To begin with, we need to identify the file we're patching. Patches must be named after the file in question, ending in .patch.

The Nether has a few biome options, but for simplicity let's do the Nether Wastes:

Nether Geodes
├ data
│ └ minecraft
│   └ worldgen
│     └ biome
│       └ nether_wastes.json.patch
└ pack.mcmeta

Now that we have our file, we can write the patch:

// nether_wastes.json.patch
{
  "op": "add",
  "path": "/features/2/-",
  "value": "minecraft:amethyst_geode"
}

What's all this? What is op, or path, or value? Let's break this patch down:

To start with, op is the operation being performed, in this case add. There are a number of operations available, and this one simply adds a value to the json file. The value is what will be added, in this case the string minecraft:amethyst_geode. The path specifies where in the file we're adding the value. Different operations have different parameters (you can learn more by reading their corresponding pages), but these are the parameters the add operation has.

This explained op and value pretty well, but what is path? Yes, it identifies the location to add to, but what does /features/2/- mean? Let's take a brief diversion.

JSON paths

A json path, such as the one mentioned earlier (/features/2/-) specifies the location of a json element in the json document. A json document is simply a json file, like a biome or loot table. A json element is any of the following:

  • a boolean, true or false
  • an integer (whole number), like 7
  • a float (floating-point number, basically any non-whole number), such as 2.1
  • a string, like "minecraft:amethyst_geode"
  • an array (also known as a list), represented by pairs of brackets: []
  • an object, represented by pairs of braces: {}

Json paths represent paths through the json document to a desired element. Json paths have a syntax to them:

  • Json paths consist of a series of path elements separated by slashes (/).
  • Json paths may be either empty (identifying the root element) or begin with a slash.
  • A path element may be numerical (2), string-based (features), or an end-of-array marker (-).
  • A numerical path points to either the element at that index in an array, or the element associated with that key in an object. For example, 1 refers to the second entry in the array [0, 1] or the value true in the object { "1": true }.
  • A string-based path points to the element associated with that name in an object. For example, test refers to some text in this object: { "test": "some text" }.
  • An end-of-array marker points to after the last value of an array (or the value of - in an object). It can only be used with the add operation.

For example, let's break down /features/2/-. Since it contains slashes, there's multiple components:

  • features, pointing to the features value in the root element
  • 2, pointing to the third entry in the features array
  • -, pointing to just after the last entry in the array identified by /features/2

The two pointing to the third entry may seem confusing, but it's important to remember that arrays in JSON are zero-indexed — that is, the first entry is 0. This is all we'll cover on JSON paths right now. If you'd like to learn more, take a look at the JSON path page.

Back to patching

Now that we have a basic understanding of the path field, let's look at the patch again:

// nether_wastes.json.patch
{
  "op": "add",
  "path": "/features/2/-",
  "value": "minecraft:amethyst_geode"
}

To summarize what we now know, this patch adds "minecraft:amethyst_geode" to the end of the array identified by the path /features/2. Specifically, this is the LOCAL_MODIFICATIONS feature generation step.

Let's try running the game with our new data pack! Before we check the world generation, we should check to make sure our pack has been recognized by Patched:

> /patched list packs
There is 1 pack with patching enabled:
  file/Nether Geodes

> /patched list patches file/Nether Geodes
There is 1 patch in file/Nether Geodes:
minecraft:worldgen/biome/nether_wastes.json.patch

This shows that Patched has recognized our pack, and knows there's a patch in it. To check if it's applied correctly, we can use the following:

> /patched dump file minecraft:worldgen/biome/nether_wastes.json
<contents of nether_wastes.json>

Now that we know it's applied correctly, it's time to see if amethyst geodes now generate in the Nether Wastes. Note that amethyst geodes spawn between Y 6 and Y 30 (or around that area anyway), so you will need to look near the bottom of the Nether. (This could be fixed by using a custom placed feature, but that's out of scope for this guide.)

Here's our geode:

A screenshot of an amethyst geode that has generated beneath the lava ocean of the nether wastes biome

Clone this wiki locally