SkillAgentSearch skills...

EasyDatapacks

A new minecraft datapack language.

Install / Use

/learn @emorgan00/EasyDatapacks
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

UPDATE 2023

Overview

EasyDatapacks is a new programming language for Minecraft. It looks a lot like the vanilla Minecraft commands we all know and love, except for a few big changes.

All in One File

Normally, datapacks are separated across many folders and files. Datapack creators need to keep track of many moving parts, such as the pack.mcmeta file, the files used to tag which functions are run at load time and at every tick, and so on. EasyDatapacks removes all of this hassle, and everything is in one file.

Defining Functions

Since everything is in one file, we need a way to create separate functions and run them independently. The solution to this is simple: simply use the python-inspired “def” keyword to define an independent function. Here’s an example:

def greet:
    say “Hello everyone!"

Indentation in EasyDatapacks is either a single tab, or 4 spaces.

Parameters?!

Normally, functions can only be run as-is and don’t accept any parameters. EasyDatapacks allows you to include entities parameters. (note: the “#p” at the end of the parameter is a clarifier. Ignore it for now, it will be explained later on.)

def greet player:
    tellraw player#p “Hello!”

Functions can take as many parameters as you want.

def impersonate A B:
    execute as A run tellraw B#p “Hello!”

Calling Functions

Guess what, functions aren’t functions anymore. They are commands. The /function command is no longer used. With def, you are creating a brand new command which you can use just like vanilla commands. Here’s an example:

def greet player:
    tellraw player#p “Hello!”

def example:
    tellraw @a “Here’s a demonstration of my new command.”
    greet @r

The above program will pick a random player and say “Hello!” to them when example is called.

Getting rid of /execute

The most complicated part of minecraft commands is probably the /execute command. It’s hard to use, lengthy, and can only run a single command. Because it’s so annoying, we’ve just decided to get rid of it. Instead, we use a syntax which looks just like the old /execute, but spans multiple lines and can accept many functions instead of just one. Here’s an example:

def greet player:
   tellraw player#p “Hello!”
   give player#p bread 1

def impersonate A B:
    as A:
        greet B
        tellraw B#p “I assure you, I am truly me!”

The above program will execute both greet B and tellraw B as A, something which is normally impossible in normal minecraft commands without retyping the execute command for each individual command you want to run. Just like in /execute, parameters can be chained together:

def example:
    at @p if block ^ ^ ^1 diamond_ore:
        tellraw @p “Just mine them already!”

This is especially useful for execute conditionals, because it introduces a whole new level of control flow into the program:

def example:
    if block 0 0 0 diamond_ore:
        tellraw @p “Yay! Diamonds!”
        at @p:
            summon fireworks_rocket ~ ~ ~

        tellraw @p “Here’s something to mine them with”
        give @p iron_pickaxe

    if block 0 0 0 coal_ore:
        tellraw @p “Coal ore :(”

If-Else

Normal minecraft commands already have an if statement, but we need an else to match the if. How this works should be fairly self-explanatory, but here’s the syntax:

def example:
    if block 0 0 0 diamond_ore:
        tellraw @p “Yay! Diamonds!”
    else:
        tellraw @p “Maybe another time.”

Else will also match with any other implicit execute statement. The way it works is simple: If the previous block of code is never run, then the else block will run.

def example:
    as @e:
        say "Here I am!"
    else:
        tellraw @a “There are no entities.”

Else can be used along with other implicit executions, though it must come first.

def example:
    as @e[type=!Player]:
        say "Here I am!"
    else as @a:
        say “There are no entities.”

Entity Variables

Suppose you want a function that chooses a random player, and then gives them a piece of bread and a sword. How would you write this using normal commands?

give @r bread 1
give @r iron_sword 1

The above program won’t work, because we won’t be choosing the same player every time. The only way to do it would be to use a more complicated system, probably with tags. However, this is a huge inconvenience and we would rather have a simple solution to this problem.

One way you could do it with EasyDatapacks would be to use a function:

def bestow_gifts player:
    give player#p bread 1
    give player#p iron_sword 1

def example:
    bestow_gifts @r

The above program would work, but it’s still a little too complicated and introduces a whole new function where we don’t need one. Instead, we can use a variable:

def example:
    player = @r
    give player#p bread 1
    give player#p iron_sword 1

This program will take a random player, and store it in the player variable. Now we can do whatever we want with our randomly chosen player, and know that we will be targeting the same player every time.

The scope of a variable works the same way as it does in normal programming languages.

Since entity variables refer to a set of entities (e.g. players = @a), it is also possible to add and remove entities to an entity variable as follows:

players = @a
players -= @p

The players variable will now hold all players except for @p. These are called augmented assignments, and work for both += and -=.

Note:

Entity variables can have selectors, just like @e, @p, etc. Just like this:

def example:
    player = @r
    tellraw player#p[tag=TheChosenOne] “You are the chosen one!”

Summon-to-Variable Shortcut

Suppose you want to summon an armor stand, and then immediately place it into a variable. You could do the following:

def example:
    summon armor_stand ~ ~1 ~ {ShowArms:1,Tags:["TemporaryTag"]}
    specialstand = @e[tag=TemporaryTag]
    tag specialstand remove TemporaryTag

However, this is way more complicated than it should be. Instead, you can use a built-in shortcut:

def example:
    specialstand = summon armor_stand ~ ~1 ~ {ShowArms:1}

The two programs above will do the exact same thing.

Clarifiers

Some commands require you to supply a selector which only includes players, or which only includes a single entity. Since a variable refers to one or more entities, something like

def example:
    player = @p
    tellraw player “hi”

actually won’t work. The function will fail to load because you can’t run tellraw on entities. To solve this problem, you need to use clarifiers. A clarifier is a # followed by some letters indicating what you want to clarify. For entities, this can be p, to indicate players, or 1, to indicate a single entity. You can combine both as #1p or #p1. You write it directly after the variable name, like this:

def example1:
    player = @p
    tellraw player#p “hi”
def example2:
    target = @r
    tp @a target#1

We had to use #1 on the target variable because you can only tp to a single entity.

The situation may also arise where you don't want a variable to be replaced with an entity query. For example, say you want to take a player and print their name like this: "[player] emorgan00". However, you want some specific coloring as well:

def say_my_name player:
    tellraw @a ["[",{"text":"player", "color":"blue"},"] ",{"selector":"player"}]

The "player" variable will be detected twice, although the first one is unintentional. The output will end up looking something like this: [@e[...some random stuff...]] emorgan00 The solution is to use the #v clarifier, which tells the compiler to just use the variable name instead of a selector:

def say_my_name player:
    tellraw @a ["[",{"text":"player#v", "color":"blue"},"] ",{"selector":"player"}]

When using clarifiers combined with selectors, the syntax should be as follows:

def example:
    players = @a
    tellraw players#p[distance=100] “hi”

Load and Tick

Most datapacks include two special functions: “load” and “tick”. Normally these are specified in the load.json and tick.json files respectively, but this is too complicated. In an EasyDatapacks program, simply name your function “load” or “tick”, and it will automatically work. Here’s an example:

def load:
    tellraw @a “Hello!”

def tick:
    tellraw @a “Tick!”

Compiling the above program would produce a fully functioning datapack which prints “Hello!” as soon as it is loaded, and then prints “Tick!” every game tick.

Delayed Assignments

One important thing to note is that free-floating commands outside of any function are totally ignored and will not be run in the datapack. For example:

tellraw @a “This message is never printed.”
def load:
    tellraw @a “Hello!”

There is one issue that can arise from this. Suppose you wanted an armor stand named “Global” which stored some special data, and you wanted every function to be able to be able to access that data. You could try to do this:

Global = summon armor_stand 0 0 0 {CustomName=”\”Global\””}
def load:
    scoreboard objectives add timePassed dummy
    scoreboard players set Global timePassed 0

def tick:
    scoreboard players add Global timePassed 1

However, this wouldn’t work, because the first summon command would never get run, and so Global would refer to nothing. Instead, you could try this:

def load:
    Global = summon armor_stand 0 0 0 {CustomName=”\”Global\””}
    scoreboard objectives add timePassed dummy
    scoreboard players set Global timePassed 0

def tick:
    scoreboard players add Global timePassed 1

This wouldn’t work either, though, because tick is outside the scope of Global.

The solution to this problem is to use a delayed assignment. This means you can dec

Related Skills

View on GitHub
GitHub Stars44
CategoryDevelopment
Updated1mo ago
Forks3

Languages

Python

Security Score

95/100

Audited on Jan 29, 2026

No findings