Updated:

The finished layout

mypack/
├─ pack.mcmeta
└─ data/
   ├─ mypack/
   │  └─ function/
   │     ├─ hello.mcfunction
   │     ├─ load.mcfunction
   │     └─ tick.mcfunction
   └─ minecraft/
      └─ tags/
         └─ function/
            ├─ load.json
            └─ tick.json

mypack is your namespace. Use only lowercase letters, numbers and _.

1. pack.mcmeta

{
  "pack": {
    "pack_format": 48,
    "description": "My first datapack"
  }
}

pack_format tells the game which version the pack is for: 48 is Java 1.21–1.21.1 and 61 is 1.21.4. It changes with most versions, and newer versions changed the file format further, so check the number for your version. Make sure Windows did not save it as pack.mcmeta.txt.

2. A function file

say The datapack works
give @s minecraft:diamond 1

Save this as data/mypack/function/hello.mcfunction. One command per line, no leading slash; lines starting with # are comments.

3. Add it to a world

  1. Copy the mypack folder into .minecraft/saves/WorldName/datapacks/.
  2. Run /reload in the world.
  3. Check /datapack list.
  4. Run /function mypack:hello.

After editing, /reload again. When sharing as a zip, pack.mcmeta must be at the top level of the zip.

4. Run on load and every tick

{
  "values": ["mypack:load"]
}

Functions listed in data/minecraft/tags/function/load.json run when the world opens and on /reload. tick.json (with "mypack:tick") runs every tick, 20 times a second, so keep it light. For timed actions, /schedule is lighter than tick.

Common problems

Check your command

The Command Error Doctor checks common syntax mistakes in your browser.