{"id":13822196,"url":"https://github.com/emorgan00/EasyDatapacks","last_synced_at":"2025-05-16T15:33:22.254Z","repository":{"id":111716178,"uuid":"192988485","full_name":"emorgan00/EasyDatapacks","owner":"emorgan00","description":"A new minecraft datapack language.","archived":false,"fork":false,"pushed_at":"2023-06-04T14:41:34.000Z","size":190,"stargazers_count":42,"open_issues_count":3,"forks_count":3,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-08-04T08:07:55.238Z","etag":null,"topics":["command-line","datapack","minecraft","minecraft-datapack"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emorgan00.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-06-20T21:17:10.000Z","updated_at":"2024-01-08T20:34:33.000Z","dependencies_parsed_at":"2023-07-11T19:35:02.037Z","dependency_job_id":null,"html_url":"https://github.com/emorgan00/EasyDatapacks","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorgan00%2FEasyDatapacks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorgan00%2FEasyDatapacks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorgan00%2FEasyDatapacks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorgan00%2FEasyDatapacks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emorgan00","download_url":"https://codeload.github.com/emorgan00/EasyDatapacks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225436585,"owners_count":17474171,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line","datapack","minecraft","minecraft-datapack"],"created_at":"2024-08-04T08:01:47.996Z","updated_at":"2024-11-19T22:32:37.648Z","avatar_url":"https://github.com/emorgan00.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"[UPDATE 2023](https://github.com/emorgan00/EasyDatapacks/issues/12#issuecomment-1575594336)\n\n## Overview\n\nEasyDatapacks 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.\n\n### All in One File\n\nNormally, 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.\n\n## Defining Functions\n\nSince 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:\n```\ndef greet:\n    say “Hello everyone!\"\n```\n\nIndentation in EasyDatapacks is either a single tab, or 4 spaces.\n\n## Parameters?!\n\nNormally, 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.)\n```\ndef greet player:\n    tellraw player#p “Hello!”\n```\nFunctions can take as many parameters as you want.\n```\ndef impersonate A B:\n    execute as A run tellraw B#p “Hello!”\n```\n## Calling Functions\n\nGuess 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:\n```\ndef greet player:\n    tellraw player#p “Hello!”\n\ndef example:\n    tellraw @a “Here’s a demonstration of my new command.”\n    greet @r\n```\nThe above program will pick a random player and say “Hello!” to them when example is called.\n\n## Getting rid of /execute\n\nThe 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:\n```\ndef greet player:\n   tellraw player#p “Hello!”\n   give player#p bread 1\n\ndef impersonate A B:\n    as A:\n        greet B\n        tellraw B#p “I assure you, I am truly me!”\n```\nThe 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:\n```\ndef example:\n    at @p if block ^ ^ ^1 diamond_ore:\n        tellraw @p “Just mine them already!”\n```\nThis is especially useful for execute conditionals, because it introduces a whole new level of control flow into the program:\n```\ndef example:\n    if block 0 0 0 diamond_ore:\n        tellraw @p “Yay! Diamonds!”\n        at @p:\n            summon fireworks_rocket ~ ~ ~\n\n        tellraw @p “Here’s something to mine them with”\n        give @p iron_pickaxe\n\n    if block 0 0 0 coal_ore:\n        tellraw @p “Coal ore :(”\n```\n\n## If-Else\n\nNormal 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:\n```\ndef example:\n    if block 0 0 0 diamond_ore:\n        tellraw @p “Yay! Diamonds!”\n    else:\n        tellraw @p “Maybe another time.”\n```\nElse 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.\n```\ndef example:\n    as @e:\n        say \"Here I am!\"\n    else:\n        tellraw @a “There are no entities.”\n```\nElse can be used along with other implicit executions, though it must come first.\n```\ndef example:\n    as @e[type=!Player]:\n        say \"Here I am!\"\n    else as @a:\n        say “There are no entities.”\n```\n## Entity Variables\n\nSuppose 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?\n```\ngive @r bread 1\ngive @r iron_sword 1\n```\nThe 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.\n\nOne way you could do it with EasyDatapacks would be to use a function:\n```\ndef bestow_gifts player:\n    give player#p bread 1\n    give player#p iron_sword 1\n\ndef example:\n    bestow_gifts @r\n```\nThe 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:\n```\ndef example:\n    player = @r\n    give player#p bread 1\n    give player#p iron_sword 1\n```\nThis 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.\n\nThe scope of a variable works the same way as it does in normal programming languages.\n\nSince 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:\n```\nplayers = @a\nplayers -= @p\n```\nThe `players` variable will now hold all players except for `@p`.\nThese are called augmented assignments, and work for both `+=` and `-=`.\n\n### Note:\n\nEntity variables can have selectors, just like @e, @p, etc. Just like this:\n```\ndef example:\n    player = @r\n    tellraw player#p[tag=TheChosenOne] “You are the chosen one!”\n```\n## Summon-to-Variable Shortcut\n\nSuppose you want to summon an armor stand, and then immediately place it into a variable. You could do the following:\n```\ndef example:\n    summon armor_stand ~ ~1 ~ {ShowArms:1,Tags:[\"TemporaryTag\"]}\n    specialstand = @e[tag=TemporaryTag]\n    tag specialstand remove TemporaryTag\n```\nHowever, this is way more complicated than it should be. Instead, you can use a built-in shortcut:\n```\ndef example:\n    specialstand = summon armor_stand ~ ~1 ~ {ShowArms:1}\n```\nThe two programs above will do the exact same thing.\n\n## Clarifiers\n\nSome 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\n```\ndef example:\n    player = @p\n    tellraw player “hi”\n```\nactually 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:\n```\ndef example1:\n    player = @p\n    tellraw player#p “hi”\ndef example2:\n    target = @r\n    tp @a target#1\n```\nWe had to use `#1` on the target variable because you can only tp to a single entity.\n\nThe 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:\n```\ndef say_my_name player:\n    tellraw @a [\"[\",{\"text\":\"player\", \"color\":\"blue\"},\"] \",{\"selector\":\"player\"}]\n```\nThe \"player\" variable will be detected twice, although the first one is unintentional. The output will end up looking something like this:\n`[@e[...some random stuff...]] emorgan00`\nThe solution is to use the `#v` clarifier, which tells the compiler to just use the variable name instead of a selector:\n```\ndef say_my_name player:\n    tellraw @a [\"[\",{\"text\":\"player#v\", \"color\":\"blue\"},\"] \",{\"selector\":\"player\"}]\n```\n\nWhen using clarifiers combined with selectors, the syntax should be as follows:\n```\ndef example:\n    players = @a\n    tellraw players#p[distance=100] “hi”\n```\n\n## Load and Tick\n\nMost 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:\n```\ndef load:\n    tellraw @a “Hello!”\n\ndef tick:\n    tellraw @a “Tick!”\n```\nCompiling 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.\n\n## Delayed Assignments\n\nOne 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:\n```\ntellraw @a “This message is never printed.”\ndef load:\n    tellraw @a “Hello!”\n```\nThere 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:\n```\nGlobal = summon armor_stand 0 0 0 {CustomName=”\\”Global\\””}\ndef load:\n    scoreboard objectives add timePassed dummy\n    scoreboard players set Global timePassed 0\n\ndef tick:\n    scoreboard players add Global timePassed 1\n```\nHowever, 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:\n```\ndef load:\n    Global = summon armor_stand 0 0 0 {CustomName=”\\”Global\\””}\n    scoreboard objectives add timePassed dummy\n    scoreboard players set Global timePassed 0\n\ndef tick:\n    scoreboard players add Global timePassed 1\n```\nThis wouldn’t work either, though, because tick is outside the scope of Global.\n\nThe solution to this problem is to use a delayed assignment. This means you can declare a variable without actually storing anything in it, basically saying “here’s the scope of this variable, but I’m saving it for later”. Here’s the syntax:\n```   \nGlobal = #e\ndef load:\n    Global = summon armor_stand 0 0 0 {CustomName=”\\”Global\\””}\n    scoreboard objectives add timePassed dummy\n    scoreboard players set Global timePassed 0\ndef tick:\n    scoreboard players add Global timePassed 1\n```\nNow, the scope of Global is across the whole program, and it can be accessed anywhere, but we don’t assign an armor stand into it until the load function.\n\nDelayed assignments also work for integer variables, and are used in the same way, just with `#i`.\n\n## Repeat Loops\n\nSuppose you want to run one of your functions 5 times. Rather than actually typing out the function call 5 times, just use the repeat command:\n```\ndef choose5randomplayers:\n    repeat 5:\n        tag @r add Tagged\n    as @a[tag=Tagged]:\n        say “We are the chosen ones!”\n```\nnote: If you are trying to use a repeat loop which repeats many times, consider using a while loop instead. While loops are more advanced and offer more versatility and features. Repeat is really just a shortcut for when you want something to be run a few times.\n\n## While Loops\n\nMost programming languages have some sort of `while` loop. EasyDatapacks also implements a while loop, which works just like `if`:\n```\ndef goforward:\n    while entity @p:\n        say \"yep, @p is here\"\n```\nThere is also a `whilenot` keyword which works just like `unless`:\n```\ndef goforward:\n    whilenot block 0 0 0 stone:\n        say \"0 0 0 isn't stone\"\n```\n**Warning!** For people who are less experienced with programming, please be very careful when using while/whilenot loops. The loops will automatically be restricted to 65536 calls by Minecraft to prevent crashing, but accidentally producing an infinite loop can still cause extreme lag.\n\nFor more complex programs, some users may want the conditionals of while/whilenot loops to use other execute subcommands. For these situations, there is the `loop` command, which is slightly more cumbersome to use but is significantly more powerful. Syntactically, `loop` works just like the `execute` command, but will repeatedly be called until it fails. Here's an example:\n```\ndef movetowall:\n    loop at @p if block ~ ~ ~ air:\n        tp @p ^ ^ ^0.1\n```\nYou may notice that `while` is simply a shortcut for `loop if`, and `whilenot` is short for `loop unless`. Please also note that the danger posed by `while` is increased in calls to `loop`, as using a selector in a subcommand with multiple entities can cause the loop to fork each call.\n\n## Break and Continue\n\nMany programming languages with loops will also have two important keywords: break and continue. EasyDatapacks offers both of these for while and whilenot loops. break will cause a loop to immediately exit, and continue will cause a loop to restart from the beginning. Here is an example of how to use them:\n```\ndef movetowall:\n    while entity @s:\n        unless block ^ ^ ^0.1 air:\n            say “I reached a wall! Time to stop moving!”\n            break\n        tp @s ^ ^ ^0.1\n```\n\n## Integer Variables\n\nThe minecraft scoreboard already allows you to work with integer variables, but EasyDatapacks offers several shortcuts for quickly working with ints without having to worry about entities or objectives. Declaring an integer variable works just like declaring a entity variable:\n```\ndef example:\n    score = 10\n```\nThe scoreboard also allows you to change variables with augmented assignments, and that is implemented here as well:\n```\ndef example:\n    score = 10\n    score *= 2\n    score /= 10\n```\nAnything that is available with the /scoreboard operation command is allowed.\n\nOf course, variables can be assigned to other variables, and used to augment other variables:\n```\ndef example:\n    a = 10\n    b = 20\n    a *= b\n    b = a\n```\nInteger variables can also be mixed with scoreboard commands:\n```\ndef example:\n    scoreboard objectives add score dummy\n    magicnumber = 10\n    scoreboard players operation @p score *= magicnumber\n    scoreboard players operation magicnumber += @p score\n```\nFinally, integer variables can be incorporated into if, else, while, and whilenot statements. There are five comparison operators available:\n\n`\u003c, \u003c=, ==, =\u003e, \u003e`\n\nComparison is always between an integer and a constant, and is done as follows:\n```\ndef example1:\n    a = 10\n    while a \u003e 0:\n        say \"this will be repeated 10 times\"\n        a -= 1\n\ndef example2:\n    a = 100\n    if a == 100:\n        say \"a is equal to 100\"\n\ndef example3:\n    a = 10\n    as @e unless a \u003c= 0:\n        say \"integer comparisons can also be used in chained execute statements!\"\n```\nTwo variables can also be compared:\n```\ndef example:\n    a = 10\n    b = 15\n    while a \u003c b:\n        a += 1\n```\n\n## Integer Clarifiers\n\nThere are clarifiers for integer variables just like for entity variables. Integer variables can use the `#v` clarifie, but also have a `#t` clarifier, which stands for \"text\". Normally an integer variable will evaluate to a selector and score, for use in hybrid scoreboard commands etc. When you want to actually print a score to the chat as part of a JSON array, the syntax is different. Using the `#t` clarifier will cause the variable to be replaced with a JSON component which returns the score as text:\n```\ndef example:\n    a = 100\n    tellraw @a [\"The value of a#v is currently \", a#t]\n```\nThis would cause the following to be printed to chat:\n`The value of a is currently 100`\n\n## Integers as Parameters\n\nInteger parameters work exactly as you might expect. When calling a function that has an integer parameter, it looks something like this:\n```\ndef example1:\n    speak_n_times 10\n\ndef example2:\n    b = 10\n    speak_n_times b\n```\nBoth of the above are valid.\n\nDefining a function that takes an integer as a parameter is a little more complicated, as you will need to use clarifiers, since all parameters refer to entities by default. Tagging a parameter with `#i` will cause it to refer to an integer.\n```\ndef speak_n_times n#i:\n    while n \u003e 0:\n        say \"This message will be repeated n times!\"\n        n -= 1\n\ndef example:\n    speak_n_times 10\n```\nFor readability purposes, it is recommended that you also tag you entity parameters with `#e`, like this:\n```\ndef greet_n_times player#e n#i:\n    while n \u003e 0:\n        tellraw player#p \"Good morning!\"\n        n -= 1\n\ndef example:\n    greet_n_times @r 10\n```\n\n## Clarifiers in Parameters\n\nIf you know in advance that a parameter will always be a player or a single entity, you may find it simpler to use the corresponding clarifier in the function declaration. EasyDatapacks does in fact support this. For example, the two following functions are equivalent:\n```\ndef greet1 player:\n    tellraw player#p \"Hello!\"\n    give player#p bread 1\n\ndef greet2 player#p:\n    tellraw player \"Hello!\"\n    give player bread 1\n```\n\nPlease note that the `#p` status of the `player` variable would be overwritten if you were to reassign another entity to the variable. For example, the following would not work:\n```\ndef greet player#p:\n    player = @p\n    give player bread 1\n```\n\n## Variables as JSON Text Components\n\nSuppose you want a function which takes a player as input, and then prints that player's name to the chat. Vanilla commands allow you to convert entity names and scores to test as part of a JSON array, which is what we will need to use to make this work. However, unlike a command parameter, entity selectors appear in JSON as text. Thankfully, EasyDatapacks will also parse any JSON inputs in your program and detect variables or parameters, incorporating them accordingly.\n\nHere is how the above example could be written:\n```\ndef say_my_name someplayer:\n    tellraw @a [{\"text\": \"Hi, my name is \"}, {\"selector\":\"someplayer\"}]\n\ndef example:\n    say_my_name @p\n```\nThe \"someplayer\" parameter will be detected and the function will print the input's name as desired. This also works for variables:\n```\ndef example:\n    someplayer = @r\n    tellraw @a [{\"text\": \"Hi, my name is \"}, {\"selector\":\"someplayer\"}]\n```\n\n## Text Strings\n\nEasyDatapacks has two data types which are used at run-time, but it also has a third data type which is handled only at compile time: Strings.\n\nA string is any piece of raw text which can be inserted into a command at any location. For example, consider the following program:\n```\ndef example:\n    my_favorite_food = chicken\n```\nBecause `chicken` isn't a number or entity, it's just a piece of raw text stored in the variable `my_favorite_food`. This raw text can be used anywhere in a command, such as in the following:\n```\ndef example:\n    my_favorite_food = chicken\n    give @p my_favorite_food 1\n```\nThis would give me 1 piece of chicken.\n\nStrings can be parameters as well. To indicate that a parameter is a string, use the `#s` clarifier, like this:\n```\ndef give_kindly player#p item_a#s item_b#s:\n\n    give player item_a 1\n    give player item_b 1\n\n    tellraw player [\"Here, take this \", \"item_a\", \" and \", \"item_b\", \"!\"]\n\ndef load:\n\n    give_kindly @p chicken bread\n```\nThe above program would give me 1 chicken and 1 bread, and then say `Here, take this chicken and bread!`\n\n## Resolving Type Conflicts\n\nSuppose you have the following program:\n```\ndef example:\n    x = 10\n    y = 15\n    z = 20\n    tp @p x y z\n```\nIt should be clear that this program isn't going to work, as `x`, `y`, and `z` are all integers, not strings, and you can't teleport a player based on scoreboard scores. In order to resolve this, we will need to let the compiler know that we want to our variables to have the string data type:\n```\ndef example:\n    x#s = 10\n    y#s = 15\n    z#s = 20\n    tp @p x y z\n```\nThis will work. In general, if something isn't the data type you want it to be, you can place a clarifier on the variable or parameter name to fix it. If no clarifier is supplied, the compiler will \"guess\" what data type you are using, but that guess can sometimes be wrong, like in the above example.\n\nFor those who may be wondering, the following are all also valid:\n```\ndef example:\n    player#p1 = @p\n    stand#e = summon armor_stand ~ ~ ~\n    number#i = 15\n    text#s = @e\n```\n\n## Parameter Defaults\n\nSuppose you want to have a function that has an optional argument, called `shout`, which you call in two different ways:\n```\nshout \"Hello\"\n# prints \"Hello!!!!\"\n\nshout \"Goodbye\" blue\n# prints \"Goodbye!!!!\" in blue\n```\nAs you can see, the argument for the color is optional. To create a function like this, we can use parameter defaults. We will have a parameter for our function called `color`, which has a default value of `white` when not provided. Here is what the syntax looks like:\n```\ndef shout message#s color#s=white:\n    tellraw @a [{\"text\":\"\",\"color#v\":\"color\"},message,\"!!!!\"]\n```\n\n## Subcommands\n\nSo far we've only dealt with functions defined at the outermost level. However, it is also possible to define functions within other functions. This is easily the most complicated section, so be sure you understand all the other features of the language before moving on. It is also, though, one of the most powerful tools you have to define commands which work just like the vanilla commands native to the game.\n\nLet's take a simple example of a command we want to make, with three subcommands. The command will be called `kit`, and will have 3 subcommands, `food`, `weapon`, and `both`. The command will also take a player parameter before the subcommand, and the `food` subcommand will take a string parameter containing a number. It will be called in the following ways:\n```\nkit @p weapon\nkit @p food 32\nkit @p both\n```\nNow let's look at how to define this command. At the highest level, the command is called `kit`, and has one player parameter. So let's define it as such:\n```\ndef kit player#p:\n    # haven't written this part yet\n```\nNext, we add each of the subcommands, defined _within_ `kit` (order doesn't matter). Let's start with the first two:\n```\ndef kit player#p:\n\n    def weapon:\n        give player iron_sword 1\n\n    def food num#s:\n        give player bread num\n\n    # still have to write \"both\"\n```\nNow, we can run the first two example calls above. All that's left to do is write the `both` command. Since `both` is within `kit`, we don't need to redundantly call `kit` or give a player parameter, we can just call `weapon` and `food` directly:\n```\ndef kit player#p:\n\n    def weapon:\n        give player iron_sword 1\n\n    def food num#s:\n        give player bread num\n\n    def both:\n        weapon\n        food 16\n```\nAnd we are done.\n\nSubcommands can be nested as deep as you want, giving you the opportunity to create vast, complex commands with many different uses.\nParameter defaults can only be used with the last subcommand in a nested chain.\n\n## Subcommand Default Outer Content\n\nWhen a subcommand of a command is run, we jump straight into the sub-content without ever running the content of the original command. For example:\n```\ndef outer:\n\n    def inner:\n        say \"This is the content of inner\"\n\n    say \"This is the content of outer\"\n```\nIn the above, if we were to call `outer inner`, only the inner message would be printed. However, if all we typed was `outer`, then only the outer content would be printed. This allows you to create \"default\" content for if a function is called without any subcommand. Take the example from earlier:\n\n```\ndef kit player#p:\n\n    def weapon:\n        give player iron_sword 1\n\n    def food num#s:\n        give player bread num\n\n    def both:\n        weapon\n        food 16\n\n    say \"Oops, you forgot to specify a subcommand!\"\n```\nIf `kit @p` was called, the \"oops\" message would be printed.\n\n## Including Other Files\n\nFor larger projects, you may wish to spread your code out across multiple files. You can compile all of these at once by listing them all out when you compile (more on this in the \"Compiling\" section), but this can be quite tedious if have more than 1 or 2 files. Instead, you can just `include` one file at the top of another file, and only compile the second file. This may sound confusing, so here's a worked example:\n\nLet's say you have two files, called `main.mcf` and `extra.mcf`. The contents of each file is as follows:\n\nmain.mcf\n```\ndef load:\n    give_food player\n```\n\nextra.mcf\n```\ndef give_food player#p:\n    give player chicken 32\n```\n\nBoth files are stored side-by-side in the same folder. Right now, if we compile `main.mcf`, it won't work because give_food isn't defined in that file. We can fix this by including `extra.mcf` at the top of `main.mcf`, as follows:\n\nmain.mcf\n```\ninclude extra.mcf\ndef load:\n    give_food player\n```\n\nIf the file you want to include isn't in the same folder, you can still include it by specifying the relative path to that file, for example:\n```\ninclude ../path/to/extra.mcf\n```\n\n## Copying Files\n\nSome complex datapacks require other files to work other than the bare _.mcfunction_ files. For instance, you might have a function which detects any type of chest, and thus uses a file called _chests.json_ with the following contents:\n```\n{\n    \"values\":[\n        \"minecraft:chest\",\n        \"minecraft:trapped_chest\",\n        \"minecraft:ender_chest\"\n    ]\n}\n```\nIn order for the datapack to work, the file should be located at `data/\u003cdatapackname\u003e/tags/blocks/chests.json`. However, before compiling our datapack, that directory doesn't exist yet! One way to solve this would be to compile once, and then move the file to the proper directory, and then compile again. A better option, though, would be to use the `file` command, which simply copies a file from one place to another.\n\nIf _chests.json_ was right alongside our source file, we would use it like this:\n```\nfile chests.json data/\u003cdatapackname\u003e/tags/blocks\n```\nThe first parameter is the relative path to the file we want to copy, and the second parameter is the folder we want it to end up in.\n\nIf you want to copy all of the files in a directory, you can use the `*` character as follows:\n```\nfile path/to/data/* path/to/destination\n```\n\n## Comments\n\nComments in EasyDatapacks work exactly the same as in normal commands. Just put a \"#\"\" at the beginning of the line, and everything on that line will be ignored. Comments can also be placed at the end of a line. Just enter a space, then a \"#\", then another space, and everything onwards will be ignored.\n\n## Additional Notes\n\nCurrently, any sort of recursion in functions is disallowed due to limitations with data storage in entities. Implementing recursion would introduce a huge amount of complexity to parameter storage, likely leading to immense lag in some cases. In theory, a limited form of recursion could be added without severe drawbacks, but we have opted not to include any recursion as it would likely rarely be used anyway.\n\nSyntactically, one of the most hard-to-get-used-to features introduced by EasyDatapacks is the use of a colon before an indented statement. Because of this, although the use of these colons, especially after \"def\" statements, is highly recommended for consistency and readability, the following code is completely valid and will be successfully compiled:\n```\ndef function var\n    as var\n        say Hello\n```\nAgain, some users may find it easier to omit colons for implicit execute statements (such as \"as var\" above), but this is not considered part of the formal syntax protocol for EasyDatapacks.\n\n# Compiling\n\nEasyDatapacks uses a compiler written in python. The file which you create will be compiled into a set of .json, .mcmeta, and .mcfunction files, which together form a complete datapack. All you need to provide is the destination folder where you want your datapack to reside, and the path to the file(s) which contain the source code for your datapack.\n\nCode on GitHub: https://github.com/emorgan00/EasyDatapacks\n\n## Installing\n\nFirst things first, you'll need to install EasyDatapacks:\n```sh\n$ pip install --user git+https://github.com/emorgan00/EasyDatapacks\n```\nOnce you're done installing, be sure that the location of the datapack.exe executable is within your system PATH variable. If it isn't, there will be a warning somewhere in the output of the command above.\n\nIf the installation was successfull, typing `datapack` on the command line should output \"A command is required\". \n\n## Compiling\n\nTo use the command line interface, run:\n\n`$ datapack build -o \u003cdestination-folder\u003e \u003cinput-file\u003e`\n\nThis will take the file in `input-file` and compile it into a datapack located at `destination-folder`. Here is an example of what this might look like:\n\n`$ datapack build -o path/to/MyWorld/datapacks/mydatapack path/to/mydatapack.mcf`\n\nIf you omit the `-o`, or `--output`, option, the output directory defaults to the name of the first file\nwithout its extension.\n\nNote that I have adopted the .mcf extension for programs in EasyDatapacks, as a shorter version of .mcfunction. I would recommend using the same.\n\nAdditionally, you can add one of the following flags:\n```\n-v, --verbose: print out all generated commands.\n-n, --nofiles: don't generate any files.\n-z, --zip: compress the generated datapack into a zipped folder.\n```\nUse a flag like this:\n\n`$ datapack build -v -o \u003cdestination-folder\u003e \u003cinput-file\u003e`\n\nYou can also compile multiple files at once, like this:\n\n`$ datapack build -o \u003cdestination-folder\u003e \u003cfile1\u003e \u003cfile2\u003e \u003c...\u003e`\n\nCompiling multiple files works exactly as if all the code from the separate files was all in one file.\n\nThere's also the `link` command, which easily symlinks a given datapack folder into your `.minecraft`\nfolder, so you can develop it without having to copy it over there every time:\n\n`$ datapack link \u003cdatapack-destination-folder\u003e \u003csave-name\u003e`\n\nEvery time you update that directory, those updates will also be carried out on the datapack in the\n`.minecraft` directory.\n\n# Examples\n\nHere are a few examples of fully working datapacks written with EasyDatapacks:\n\n[String Functions](https://github.com/emorgan00/EasyDatapacks/blob/master/examples/strings.mcf): A brief example of the various things you can do with raw text.\n\n[Raytracing](https://github.com/emorgan00/EasyDatapacks/blob/master/examples/simple_raytracer.mcf): A super simple ray tracing program.\n\n[Subcommands](https://github.com/emorgan00/EasyDatapacks/blob/master/examples/subcommands.mcf): An example of how to use subcommands.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femorgan00%2FEasyDatapacks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femorgan00%2FEasyDatapacks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femorgan00%2FEasyDatapacks/lists"}