Last active
December 29, 2024 02:08
-
-
Save Ellivers/762822ee452f1beb058f044ec3139d73 to your computer and use it in GitHub Desktop.
Revisions
-
Ellivers revised this gist
May 12, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -84,7 +84,7 @@ Functions in data packs can easily lead to bad performance. Here is a list of so "predicate": { "equipment": { "mainhand": { "items": "minecraft:feather" } } } -
Ellivers revised this gist
Jan 11, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -99,7 +99,7 @@ Functions in data packs can easily lead to bad performance. Here is a list of so However, predicates will not help if you only use them to check using the `nbt` key. This is an example of something that does *not* help performance: ```json { "condition": "minecraft:entity_properties", "entity": "this", -
Ellivers revised this gist
May 17, 2021 . 1 changed file with 11 additions and 9 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ ## Structuring and Consistency An organized structure to your data pack's folders and file names always helps you understand your code better and leads to less bugs. Place files that have something in common in the same folder, and name them based on what their purpose is. Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). @@ -11,7 +11,7 @@ If you are unsure of how a good structure could look, you could take a look at s ## Commenting Comments are very important and a huge help when working with functions, as well as any code in general. Ideally, every function should have at least one line of comments in it. A comment is any line that starts with a `#`. Here is how I like to structure my comments: @@ -31,7 +31,7 @@ command 4 ## Performance Functions in data packs can easily lead to bad performance. Here is a list of some things to be aware of: * **Multiple Entity Selectors** @@ -71,7 +71,9 @@ Functions in data packs easily lead to bad performance. Here is a list of what y **Predicates** Predicates are JSON files that can be used in combination with commands to check for all kinds of things. Often, NBT checks can be replaced with predicates to improve performance. This is the case for the command shown above. Here is what a predicate replacing the NBT check above would look like: @@ -95,8 +97,8 @@ Functions in data packs easily lead to bad performance. Here is a list of what y execute if predicate namespace:path/to/predicate ``` However, predicates will not help if you only use them to check using the `nbt` key. This is an example of something that does *not* help performance: ``` { "condition": "minecraft:entity_properties", @@ -107,7 +109,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y } ``` Notice how the predicate above only checks for the property `OnGround:1b`, and does not use any keys other than `nbt`. In this case, it is better to simply check the NBT in the command directly: ```mcfunction # Check if the executing entity is on the ground @@ -118,7 +120,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y Storage is global NBT that can contain anything you want and that can be accessed from anywhere. It is the most performance-friendly option for storing NBT, but is not specific to any entity or block. If you need to either modify NBT several times, or check it multiple times while predicates are not applicable, using storage can be a lot more efficient. Here is an example: ```mcfunction @@ -137,7 +139,7 @@ When you need to detect something a player does, like placing a block, first see ## Fakeplayers "Fakeplayers" are an extremely useful trick used in order to avoid creating big amounts of scoreboard objectives. Simply give a score to a nonexistant player, and you are able to make way more variables using only one objective and no entities. Here is an example of what you can do using fakeplayers: -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 6 additions and 4 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -116,16 +116,18 @@ Functions in data packs easily lead to bad performance. Here is a list of what y **Storage** Storage is global NBT that can contain anything you want and that can be accessed from anywhere. It is the most performance-friendly option for storing NBT, but is not specific to any entity or block. If you either need to modify NBT several times, or check it multiple times and predicates are not applicable, using storage can be a lot more efficient. Here is an example: ```mcfunction # Set the X, Y, and Z coordinates of the executing entity's position data modify storage namespace:name Key set from entity @s Pos data modify storage namespace:name Key[0] set value 3.0d data modify storage namespace:name Key[1] set value 7.0d data modify storage namespace:name Key[2] set value 85.0d data modify entity @s Pos set from storage namespace:name Key ``` -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 16 additions and 16 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,13 +7,13 @@ Place files that have something in common in the same folder, and name them base Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). If you are unsure of how a good structure could look, you could take a look at some vanilla assets, such as the lang file or the built-in data pack, as well as get ideas from looking at data packs that other people have made. ## Commenting Comments are very important and a huge help when working with functions, and any code in general. Ideally, every function should have at least one line of comments in it. A comment is any line that starts with a "#". Here is how I like to structure my comments: ```mcfunction # Called by namespace:path/to/function @@ -42,26 +42,26 @@ Functions in data packs easily lead to bad performance. Here is a list of what y function1: ```mcfunction # Executes as all pigs that have the "namespace.mytag" tag execute as @e[type=minecraft:pig,tag=namespace.mytag] run function namespace:function2 ``` function2: ```mcfunction # Called by namespace:function1 # Runs commands as all pigs that have the "namespace.mytag" tag say My name is @s kill @s say ouch ``` **@a** is another selector that selects multiple entities. It only selects players, and there are usually not nearly as many players as general entities in a world, so it does not contribute to lag as much as `@e`. However, if you have a lot of `@a` selectors you should still be splitting them into `@s`, the same way you do with `@e`. * **NBT Checks** Checking for NBT data hurts performance quite a lot, and is something that you should avoid as much as possible. Example of a bad NBT check: ```mcfunction @@ -73,7 +73,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y Often, NBT checks can be replaced with predicates to improve performance. This is the case for the command above. Here is what a predicate replacing the NBT check above would look like: ```json { @@ -96,7 +96,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ``` *However,* predicates will not help if you only use them to check using the `nbt` key. This is an example of something that does __not__ help performance: ``` { "condition": "minecraft:entity_properties", @@ -107,7 +107,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y } ``` Notice how the predicate above only checks for the `nbt` property `OnGround:1b`, and does not use any keys other than `nbt`. In this case, it is better to simply check the NBT in the command directly: ```mcfunction # Check if the executing entity is on the ground @@ -116,9 +116,9 @@ Functions in data packs easily lead to bad performance. Here is a list of what y **Storage** If you either need to write NBT several times, or check it multiple times and predicates are not applicable, using storage can be a lot more efficient. Here is an example: ```mcfunction # Set the X, Y, and Z coordinates of the executing entity's position @@ -131,14 +131,14 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ## Advancements When you need to detect something a player does, like placing a block, first see if that is something an advancement can detect, instead of creating a scoreboard objective for it or perhaps running a check for it every tick. Advancements are very useful and powerful, as they do not cause any lag (with the exception of the `tick` advancement trigger) and can be used to run a function when something happens. ## Fakeplayers "Fakeplayers" are an extremely useful trick to avoid creating big amounts of scoreboard objectives. Simply give a score to a nonexistant player, and you are able to make way more variables using only one objective and no entities. Here is an example of what you can do using fakeplayers: ```mcfunction # Do some math @@ -148,5 +148,5 @@ scoreboard players operation #variable1 objective *= #five objective scoreboard players operation #variable2 objective += #variable1 objective ``` Notice how the fakeplayer names are prefixed with `#`. This is not needed, but it makes sure that the fakeplayer's name can't happen to be the same as a real player's name, since real players can't have `#` in their name. Fakeplayers are global and not applicable if you need to tie a score to an entity. -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -35,8 +35,8 @@ Functions in data packs easily lead to bad performance. Here is a list of what y * **Multiple Entity Selectors** **@e** is an essential selector as it is able to select all entities, but it is also a huge reason for command lag. Therefore, it should be avoided in large quantities as much as possible. If you execute a function as an entity, you can then use the `@s` selector to refer to that entity. `@s` is the selector you should be using the most. Example of splitting an `@e` selector into multiple `@s`: -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 5 additions and 3 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ Place files that have something in common in the same folder, and name them base Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). If you're unsure of how a good structure could look, you could take a look at some vanilla assets, such as the lang file or the built-in data pack, as well as get ideas from looking at data packs that other people have made. ## Commenting @@ -36,7 +36,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y * **Multiple Entity Selectors** **@e** is an essential selector as it is able to select all entities, but it also a huge reason for command lag. Therefore, it should be avoided in large quantities as much as possible. If you execute a function as an entity, you can use the `@s` selector for that entity, which is the selector you should be using the most. Example of splitting an `@e` selector into multiple `@s`: @@ -70,6 +70,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ``` **Predicates** Often, NBT checks can be replaced with predicates to improve performance. This is the case for the command above. Here's what a predicate replacing the NBT check above would look like: @@ -114,6 +115,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ``` **Storage** If you either need to write NBT several times, or check it multiple times and predicates aren't applicable, using storage can be a lot more efficient. Here's an example: @@ -134,7 +136,7 @@ When you need to detect something a player does, like placing a block, first see ## Fakeplayers "Fakeplayers" are an extremely useful trick to avoid creating big amounts of scoreboard objectives. Simply give a score to a nonexistant player and you're able to make way more variables using only one objective and no entities. Here's an example of what you can do using fakeplayers: ```mcfunction -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ Place files that have something in common in the same folder, and name them base Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). If you're unsure of how a good structure could look, you could take a look at some vanilla assets, such as the lang file or the built-in data pack. ## Commenting @@ -36,7 +36,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y * **Multiple Entity Selectors** **@e** is an essential selector as it is able to select all entities, but it also a huge reason for command lag. Therefore, it should be avoided as much as possible. If you execute a function as an entity, you can use the `@s` selector for that entity, which is the selector you should be using the most. Example of splitting an `@e` selector into multiple `@s`: -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -36,7 +36,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y * **Multiple Entity Selectors** **@e** is an essential selector as it is able to select all entities, but it also a huge reason for command lag. Therefore, it should be avoided in large quantities as much as possible. If you execute a function as an entity, you can use the `@s` selector for that entity, which is the selector you should be using the most. Example of splitting an `@e` selector into multiple `@s`: -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ Place files that have something in common in the same folder, and name them base Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). If you're unsure of how a good structure could look, you could take a look at some vanilla assets, such as the lang file or the built-in data pack, as well as get ideas from looking at data packs that other people have made. ## Commenting @@ -36,7 +36,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y * **Multiple Entity Selectors** **@e** is an essential selector as it is able to select all entities, but it also a huge reason for command lag. Therefore, it should be avoided as much as possible. If you execute a function as an entity, you can use the `@s` selector for that entity, which is the selector you should be using the most. Example of splitting an `@e` selector into multiple `@s`: -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ Place files that have something in common in the same folder, and name them base Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). If you're unsure of how a good structure could look, you could take a look at some vanilla assets, such as the lang file or the built-in data pack. ## Commenting @@ -36,7 +36,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y * **Multiple Entity Selectors** **@e** is an essential selector as it is able to select all entities, but it also a huge reason for command lag. Therefore, it should be avoided in large quantities as much as possible. If you execute a function as an entity, you can use the `@s` selector for that entity, which is the selector you should be using the most. Example of splitting an `@e` selector into multiple `@s`: -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 2 additions and 4 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ Place files that have something in common in the same folder, and name them base Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). If you're unsure of how a good structure could look, you could take a look at some vanilla assets, such as the lang file or the built-in data pack, as well as get ideas from looking at data packs that other people have made. ## Commenting @@ -70,7 +70,6 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ``` **Predicates** Often, NBT checks can be replaced with predicates to improve performance. This is the case for the command above. Here's what a predicate replacing the NBT check above would look like: @@ -115,7 +114,6 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ``` **Storage** If you either need to write NBT several times, or check it multiple times and predicates aren't applicable, using storage can be a lot more efficient. Here's an example: @@ -136,7 +134,7 @@ When you need to detect something a player does, like placing a block, first see ## Fakeplayers "Fakeplayers" are an extremely useful trick to avoid creating big amounts of scoreboard objectives. Simply give a score to a nonexistant player and you're able to create way more variables using only one objective and no entities. Here's an example of what you can do using fakeplayers: ```mcfunction -
Ellivers revised this gist
May 15, 2021 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -70,6 +70,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ``` **Predicates** Often, NBT checks can be replaced with predicates to improve performance. This is the case for the command above. Here's what a predicate replacing the NBT check above would look like: @@ -114,6 +115,7 @@ Functions in data packs easily lead to bad performance. Here is a list of what y ``` **Storage** If you either need to write NBT several times, or check it multiple times and predicates aren't applicable, using storage can be a lot more efficient. Here's an example: @@ -134,7 +136,7 @@ When you need to detect something a player does, like placing a block, first see ## Fakeplayers "Fakeplayers" are an extremely useful trick to avoid creating big amounts of scoreboard objectives. Simply give a score to a nonexistant player and you're able to make way more variables using only one objective and no entities. Here's an example of what you can do using fakeplayers: ```mcfunction -
Ellivers created this gist
May 15, 2021 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,150 @@ # Good Data Pack Practices and Common Tricks ## Structuring and Consistency An organized structure to your data pack's folders and file names always helps you and other people understand your code better and leads to less bugs. Place files that have something in common in the same folder, and name them based on what their purpose is. Consistency in naming stuff like tags, files, and scores can help keep you sane. Always have a clear structure in place, such as prefixing tag and objective names with your namespace (`namespace.name`) and giving tags different categories (`namespace.entity.name`, `namespace.block.name`). If you're unsure of how a good structure could look, you could take a look at some vanilla assets, such as the lang file or the built-in data pack. ## Commenting Comments are very important and a huge help when working with functions, and any code in general. Ideally, every function should have at least one line of comments in it. A comment is any line that starts with a "#". Here's how I like to structure my comments: ```mcfunction # Called by namespace:path/to/function # Short description of what this function does # More describing if needed # Description of what these commands do command 1 command 2 # Description of what these commands do command 3 command 4 ``` ## Performance Functions in data packs easily lead to bad performance. Here is a list of what you can try to avoid: * **Multiple Entity Selectors** **@e** is an essential selector as it is able to select all entities, but it also a huge reason for command lag. Therefore, it should be avoided as much as possible. If you execute a function as an entity, you can use the `@s` selector for that entity, which is the selector you should be using the most. Example of splitting an `@e` selector into multiple `@s`: function1: ```mcfunction # Executes as all pigs that have the "mytag" tag execute as @e[type=minecraft:pig,tag=mytag] run function namespace:function2 ``` function2: ```mcfunction # Called by namespace:function1 # Does things as all pigs that have the "mytag" tag say My name is @s kill @s say ouch ``` **@a** is another selector that selects multiple entities. However, it only selects players, and there are usually not nearly as many players as general entities in a world, so it doesn't contribute to lag as much. However, if you have a lot of `@a` selectors you should still be splitting them into `@s`, the same way you do with `@e`. * **NBT Checks** Checking for NBT data hurts peformance quite a lot, and is something that you should use as little as possible. Example of a bad NBT check: ```mcfunction # Check if the executing player is holding a feather execute if entity @s[nbt={SelectedItem:{id:"minecraft:feather"}}] ``` **Predicates** Often, NBT checks can be replaced with predicates to improve performance. This is the case for the command above. Here's what a predicate replacing the NBT check above would look like: ```json { "condition": "minecraft:entity_properties", "entity": "this", "predicate": { "equipment": { "mainhand": { "item": "minecraft:feather" } } } } ``` It could replace the check in the command like this: ```mcfunction # Check if the executing player is holding a feather execute if predicate namespace:path/to/predicate ``` *However,* predicates will not help if you only use them to check using the `nbt` key. This is an example of something that does __not__ help: ``` { "condition": "minecraft:entity_properties", "entity": "this", "predicate": { "nbt": "{OnGround:1b}" } } ``` Notice how the predicate above only checks for the `nbt` property `OnGround:1b`, and doesn't use any other keys than `nbt`. In this case, it is better to simply check the NBT in the command directly: ```mcfunction # Check if the executing entity is on the ground execute if entity @s[nbt={OnGround:1b}] ``` **Storage** If you either need to write NBT several times, or check it multiple times and predicates aren't applicable, using storage can be a lot more efficient. Here's an example: ```mcfunction # Set the X, Y, and Z coordinates of the executing entity's position data modify storage namespace:name Key set from entity @s Pos data modify storage namespace:name Key[0] set value 3 data modify storage namespace:name Key[1] set value 7 data modify storage namespace:name Key[2] set value 85 data modify entity @s Pos set from storage namespace:name Key ``` ## Advancements When you need to detect something a player does, like placing a block, first see if that is something an advancement can detect, instead of creating a scoreboard objective for it or perhaps running a check every tick for it. Advancements are extremely useful and powerful, as they don't cause any lag (with the exception of the `tick` advancement trigger) and can be used to run a function when something happens. ## Fakeplayers "Fakeplayers" are an extremely useful trick to avoid creating big amounts of scoreboard objectives. Simply give a score to a nonexistant player and you're able to create way more variables using only one objective and no entities. Here's an example of what you can do using fakeplayers: ```mcfunction # Do some math scoreboard players set #five objective 5 scoreboard players operation #variable1 objective *= #five objective scoreboard players operation #variable2 objective += #variable1 objective ``` Notice how the fakeplayer names are prefixed with `#`. This isn't needed, but it makes sure that the fakeplayer's name can't happen to be the same as a real player's name, since real players can't have `#` in their name. Fakeplayers are global and not applicable if you need to tie a score to an entity.