datapack-py — Python-like → Minecraft 26.1-26.2 Datapack

Functions (click for usage)

Click a function on the left to see how to use it.

How to use

Write Python-like code, compile it, then put datapack.zip in the world's datapacks folder. Run /reload in game.

Two entry points

def init(): runs once on load. Code outside a def runs every tick.

Values

Who: me, players, all, nearest, or near(zombie, distance=8).
Where: here, below, above, rel(0,-1,0), pos(10,64,0).
What: write ids directly. diamond_block compiles as minecraft:diamond_block.

Actions

give(me, diamond, 3)
title(me, "Wave 1")
effect(me, speed, seconds=10)
summon(zombie, here)

Blocks: with / if

Indent under with or if. These compile to Minecraft execute commands.

with as_players():
    if block_is(below, gold_block):
        tell(me, "on gold!")

Raycast

raycast is built in. It casts from eyes or feet. Inside the block, here is the block position being aimed at; use offset to move along the look ray. through can be one block, a tag, or a list.

with as_players():
    with raycast(max=40, offset=-1,
                 through=[air, cave_air, water]):
        setblock(here, glowstone)

raycast_miss runs only if no solid block is hit before max range.

with as_players():
    with raycast_miss(max=20):
        summon(lightning_bolt, here)

raycast_entity finds the first matching entity near the ray. Inside the block, me is the hit entity and here is the ray position. Set stop_at_blocks=false for through-wall checks.

with as_players():
    with raycast_entity(entities(zombie), radius=1):
        effect(me, glowing, seconds=2)

raycast_entity_miss runs at max range when no entity is found.

Waiting (non-blocking)

sleep(20) waits 20 ticks. sleep("3s") waits 3 seconds. It schedules the rest of the function for later, so the game keeps running. Use it at top level, in def, or in with; avoid it inside if.

Variables

Assign values with normal Python-style syntax:

points = 0          # int   - LIVE
ready  = true       # bool  - LIVE
pi     = 3.14       # float - constant
name   = "Hero"     # string- constant
spawn  = vec3(0,64,0) # vec3 - constant

Live int/bool variables use scoreboards and can change while the pack runs:

points = points + 10
points = points * 2

Constants are fixed when you compile. Use them for config, names, and positions:

setblock(spawn, beacon)
greeting = "Hi " + name

Lists

Lists stay static unless you mutate them. Static lists compile directly into commands, which is the fastest path:

pass_blocks = [air, cave_air, water]
with as_players():
    with raycast(through=pass_blocks):
        setblock(here, glowstone)

If you call a mutating method, the list becomes dynamic and is stored in storage. Dynamic setup usually belongs in def init():

def init():
    pass_blocks = [air, cave_air, water]
    pass_blocks.append(glass)
    pass_blocks.insert(1, lava)
    pass_blocks.remove_at(0)
    pass_blocks.pop_end()
    count = len(pass_blocks)

Use persist before the name when a dynamic list should survive reloads. Put the starting value in def init(); it is only applied the first time.

persist pass_blocks
def init():
    pass_blocks = [air, cave_air, water]
with as_players():
    if block_is(below, gold_block):
        pass_blocks.pop_end()

Top-level assignments run every tick and will reset a dynamic list every tick, just like other top-level code.

Showing variables (f-strings)

Use f"..." strings when a message needs a variable value:

tell(me, f"Score: {points}")
actionbar(me, f"{name} has {points}!")

say() cannot show live variables; use tell() or actionbar().

Text colors & styles

Put color and style tags inside an f"..." string before the text they should affect:

tell(me, f"{gold}{bold}Score: {points}")
actionbar(me, f"{red}Low HP! {reset}{hp}/20")
title(me, f"{aqua}Wave {wave}")

Works in tell, title, actionbar, and item name/lore.

give(me, diamond_sword,
     name=f"{aqua}{bold}Frostbite",
     lore=[f"{gray}Frozen blade", f"{gold}+5 style"])

Colors: black, dark_blue, dark_green, dark_aqua, dark_red, dark_purple, gold, gray, dark_gray, blue, green, aqua, red, light_purple, yellow, white.

Styles: bold, italic, underlined, strikethrough, obfuscated. Aliases: underline, strike, magic. Use {reset} to go back to the command's default style.

Persistence

Live variables reset on reload unless you mark them with persist before first use:

persist coins      # kept across reloads
def init():
    coins = 0      # first load only
    tries = 0      # resets on reload
with as_players():
    if block_is(below, gold_block):
        coins = coins + 1

Only int/bool variables can persist.

Items & blocks

give accepts common item fields directly: name, color, lore, enchant, unbreakable, model, attributes, and more. Use components={...} for raw item components.

give(me, diamond_sword,
     name="Frostbite", enchant={sharpness:5},
     model="my_pack:frostbite", unbreakable=true)

model sets the modern item_model component, which is the normal way to give an item a custom model in 26.1-26.2. For advanced item model predicates, use structured custom_model_data with strings, floats, flags, or colors:

give(me, stick,
     custom_model_data={strings:["wand"]})

setblock accepts state={...} for block states, data={...} for block entity data, and command= for command blocks.

setblock(below, chest,
  data={Items:[{slot:0, id:"minecraft:diamond", count:5}]})

Raw commands

raw_command("...") emits a Minecraft command unchanged, without the leading slash. It is a fallback, not the recommended way to write packs. If you need it because a command is missing, comment on the Reddit feedback post.

raw_command("weather clear")

Tips

Edits autosave in this browser.
Reset to Example restores the starter script.
Start typing for autocomplete; use the arrow keys and Enter.
Click a function for its signature and an example.

Edit the code, then click "Compile and Download" to get datapack.zip.