- 1,928 views, 3 today
73
Randomizing
Contents
0. Prerequisites 1. Introduction 2. Pseudorandomness 3. Random Number 4. Random Function 4.1. Function Chance 4.2. Select Function 5. Random Entity 5.1. Random Player 5.2. Random Mob/Entity 6. Random Location 6.1. Location in Area 6.2. Location from List 7. Conclusion and Further Reading |
0. Prerequisites
Knowledge of the following topics is required for this explanation. If you don't have that knowledge, I suggest you visit the linked resource and learn about that topic first.
Topic | Suggested Resource |
Creating a basic function datapack | Function Datapacks for Dummies by Bertiecrafter, at least quickstart |
Scoreboards (creating, setting/adding values) | Function Datapacks for Dummies by Bertiecrafter, at least section 7.1 |
1. Introduction
So you have been working with datapacks a little and started to ask yourself: How can I do random stuff? How can I decide randomly what function to run, spawn something at a random location or just get a random number? Well, you've found just what you were looking for! Wh.. What? You haven't? Then why have you clicked on this article? No worries, you just didn't know how much you'll need this, you can still leave a diamond before you leave! 😉
Anyways, let's get right into the interesting stuff:
First of all, using the #minecraft:load tag, this function will run whenever our datapack is loaded and therefore we'll always have a scoreboard to store random numbers whenever we'll need it:
# File Location: ./data/did/functions/randomizing/load.mcfunction
# as/at server
scoreboard objectives add rng dummy
2. Pseudorandomness
ℹ️ This section contains background information. If you're only interested in the minecraft-specific part of this article, you can skip this section.
Most randomness you come across while writing code these days is actually pseudorandomness: It's random enough to seem unpredictable for most humans and it's random enough for most use cases, but behind the scenes it's just some really complicated calculation.
Now you might ask: Why don't we use true randomness? The answer is simple: Computers themselves are not capable of doing random things. We built them to do exactly what we want them to do and that's what they to: They follow specific instructions. That's not how randomness works and therefore they can't do truly random things without help.
Of course, there are ways to generate true random numbers, but they are complicated and therefore not practical in most situations. To generate true random numbers we need help from something random: Reality! We take something that we can't predict, for example something like thermal noise, atmospheric noise or nuclear decay, measure it and then incorporate it into our random number calculatian. Voilà - there we have our perfectly random number! You wouldn't want to do something that complicated for every random number you want to generate, right?
3. Random Number
We'll start with the most basic randomizing. The basis of all coincidence! The knowledge upon which everything unpredictable is built! The glue that holds all randomness and the entire universe together!! THE ESSENCE OF COINCIDENCE!!! Oh... Pardon, possibly I have drifted away from the topic very slightly. What I actually wanted to say: We'll start with generating a random number!
Probably the easiest way to generate a random number in minecraft is to use a loot table to generate a random number of items:
# File Location: ./data/did/loot_tables/randomizing/random.json
{
"pools":
[
{
"rolls":
{
"min": 1,
"max": 3
},
"entries":
[
{
"type": "minecraft:item",
"name": "minecraft:stone",
"functions":
[
{
"function": "minecraft:set_count",
"count": 0
}
]
}
]
}
]
}
If you don't understand all of that, don't worry. You don't need to, right now. The only important things are: That loot table can be used to generate a random number of items. The minimum and maximum values of your random number can be set by modifying the "min" and "max" values of "rolls". (in the above example that would mean a random number between 1 and 3) It won't actually spawn any items, since the count is set to 0 using a minecraft:set_count item modifier. Still, the number of items that tried to spawn can be counted and stored to a scoreboard. For storing data, you can use /execute store. Since you want to store the result of a command to a score, more specifically you'd need to use the /execute store result score command. Since you want to get the result of the loot table, you'll need to store the result of spawning that loot using /loot:
# File Location: ./data/did/functions/randomizing/number.mcfunction
# as/at player executing the function
execute store result score #number rng run loot spawn ~ ~ ~ loot did:random
After that, you can do whatever you want with your fresh, randomly generated number. For my example, I'll just write the generated number into the chat using /tellraw:
# File Location: ./data/did/functions/randomizing/number.mcfunction
# as/at player executing the function
tellraw @a {"score":{"name":"#number","objective":"rng"}}
And just like that, you've generated your first random number! Yayyy! Here are some fireworks as a reward :D
4. Random Function
4.1. Function Chance
This method is useful if you want something to happen with a specific chance, for example a chance of 75% for your custom mob doing a special attack, whenever something happens. In minecraft, you can check for specific conditions using predicates. There already is a built-in predicate condition for a random chance, you just need to create a predicate and set the chance to whatever you want, I used 75% in this example:
# File Location: ./data/did/predicates/chance.json
{
"condition": "minecraft:random_chance",
"chance": 0.75
}
Now you can use /execute if predicate combined with whatever function you want to run that function with the chance defined in your predicate:
# File Location: ./data/did/functions/randomizing/number.mcfunction
# as/at player executing the function
execute if predicate did:chance run function did:randomizing/function/f1
This would mean there's a 75% chance of triggering the function, else nothing will happen.
My f1.mcfunction simply says 1, but of course you could run any command you want:
# File Location: ./data/did/functions/randomizing/function/f1.mcfunction
# as/at player executing the function
say 1
4.2. Select Function
But what if you want to randomly select a function from a list of functions? Actually, you only need to combine the method to get a random number with some /execute if score commands:
# File Location: ./data/did/functions/randomizing/function/select.mcfunction
# as/at player executing the function
execute store result score #number rng run loot spawn ~ ~ ~ loot did:random
execute if score #number rng matches 1 run function did:randomizing/function/f1
execute if score #number rng matches 2 run function did:randomizing/function/f2
execute if score #number rng matches 3 run function did:randomizing/function/f3
Based on the number you got from the random number generator, you select a function to run. You just need to change the min/max of your random number loot table, so that it matches the amount of functions you want to choose from. (in this case: 3 possible functions -> min = 1; max =3)
If you have a very large number of possible functions, it might be useful to use a function tree, in order to prevent your datapack from getting laggy. (see DID 4)
5. Random Entity
5.1. Random Player
Minecraft already has a built-in selector to target a random player: @r. This can be used in all commands that use a selector, for example when giving an effect to a random player:
effect give @r minecraft:glowing
This can also be used in combination with /execute as|at, if you want to run a whole function as a random player.
# File Location: ./data/did/functions/randomizing/player.mcfunction
# as/at player executing the commad
execute as @r at @s run function did:randomizing/function/effect
In my example, the function I run is used to apply glowing and a particle effect to a random player, but again you can use this for any purpose you want.
5.2. Random Mob/Entity
If you want to target a random entity, not only players (Who would want to exclude our dear friend the creeper?), you'll have to use @e as selector again. To get a random one, that selector needs to be combined with a limit and sort. Limit controls how many random entities you want to get (only 1 in my example) and sort needs to be random, since you want to get random entities:
effect give @e[limit=1,sort=random] minecraft:glowing
Again, just like for players this can be used in combination with /execute as|at, if you want to run a whole function as a random entity. Furthermore, you can also check for the type, if you want to get a random entity of a specific type. In my example, I apply the same effects as before to 1 random pig:
# File Location: ./data/did/functions/randomizing/entity.mcfunction
# as/at player executing the commad
execute as @e[limit=1,sort=random] at @s run function did:randomizing/function/effect
6. Random Location
6.1. Location im Area
Conviniently, there also is a built-in command to get random locations: /spreadplayers. Conviniently? Well, actually it's kinda sad. Where is the challenge? There's a danger of this getting boring... Whatever. To understand how this works, you need to know the syntax of the spreadplayers command:
spreadplayers <center> <spreadDistance> <maxRange> <respectTeams> <targets>
<center> is the center around which your random location should be chosen. In my example, it should be centered around the player, therefore <center> is the players location (~ ~). <spreadDistance> is only relevant, if you want to move multiple entities (generate multiple locations). It would be the minimum distance between those random locations, for now I'll just set it to 0. <maxRange> is the maximum distance from <center> your random locations should have. <respectTeams> is not important right now, just set it to false. <targets> are the entities to spread. If you want to teleport a player to a random location, target should be that player, for example:
spreadplayers ~ ~ 0 5 false @p
If you want to do something different at the location you generate, usually you'd use an invisible entity like an invisible armorstand or marker.
For my example, I want summon an item at a random location near the original location:
# File Location: ./data/did/functions/randomizing/location.mcfunction
# as/at player executing the commad
summon minecraft:marker ~ ~ ~ {Tags:["rng_location"]}
spreadplayers ~ ~ 0 5 false @e[tag=rng_location]
execute as @e[tag=rng_location] at @s run summon minecraft:item ~ ~ ~ {Item:{id:"minecraft:diamond",Count:1b}}
execute as @e[tag=rng_location] at @s run kill @s
To accomplish that the above function does the following
- It summons a marker to mark the random location
- It teleports it to a random location within a 5 block radius using /spreadplayers.
- It summons an item (diamond) at the new location of the marker and...
- ... kills the marker, in order to leave no unnecessary entites behind and prevent lag.
There is one slight problem with this method though: Spreadplayers will only ever use surface locations, so it wont work underground. There are other methods for that, but in most cases it is enough to add a maximum height to the spreadplayers command:
spreadplayers <center> <spreadDistance> <maxRange> under <maxHeight> <respectTeams> <targets>
As you can see, the only thing that changed is the additional "under <maxHeight>" option. This can be used to get underground locations, since anything above <maxHeight> will be ignored and spreadplayers only targets locations with air.
6.2 Location from List
To generate a random location from a list of locations, you firstly should mark all possible locations by summoning a marker there:
/summon minecraft:marker ~ ~ ~ {Tags:["did_location"]}
This can be done by just manually running that command in chat.
After that, you can use the explanation from the "Random Entity" section to select a random one of those markers and execute your commands at the location of that random marker:
execute as @e[type=minecraft:marker,tag=did_location,limit=1,sort=random] at @s run tp @a ~ ~ ~
This example would teleport all players to the location of a random marker with the "did_location" tag (the one you used to mark your locations).
7. Conclusion and Further Reading
Congratulations! You now (hopefully) know a lot more about randomizing in minecraft and will use your knowledge to create awesome datapacks in the future. You know how to get random numbers, functions, entities and locations. Your worlds are going to be so much more random after this, enjoy :P
If you want to, you can practice using your newly gained knowledge by completing this challenge:
assignment Challenge |
Try to build a dungeon room where, if a player enters it, a random amount of a mobs will be spawned. The type of mob should also be randomly selected from a list (for example: creeper, zombie, husk). |
If you have any further questions, feel free to ask in the comments.
If you want to check out the functions I created for this tutorial, change some things around and test it for yourself, you can download the tutorial datapack here:
🔗 DID Tutorial Datapack: Randomizing
If you want to read about some more methods for randomizing, check those out:
🔗 Generate a random number (r/MinecraftCommads)
🔗 Randomizer in One Command (Shane Stone)
🔗 Random Items using loot tables (Timber Forge)
👍👎 | How did you like it? Please leave your feedback in the comments. |
If you want to learn even more about datapacks, you can find other episodes of DID and more in the Datapack Knowledge Book.
Tags |
3 Update Logs
Update #3 : by Kefaku 04/12/2023 4:12:32 pmApr 12th, 2023
- added reference to relevant information in DID 4 to 4.2.
- now mentions the Datapack Knowledge Book at the end, instead of the DID collection
- fixed another spelling mistake
LOAD MORE LOGS
tools/tracking
5755217
6
did-3-this-is-so-random-randomizing
Create an account or sign in to comment.
execute store result score #number rng run random roll 1..3
It might be worth noting some other mechanics, some very basic and others being combinations of already listed ones. Picking from a list of locations (as opposed to the entire area) can be achieved by spawning an entity at each of the locations and using the random entity section + /execute at. Another obvious, but noteworthy one is that random items can be generated with loot tables and the /loot command. And random NBT data can be selected by spawning markers with the NBT + random entity selection or using a random number + recursion + /data to drop from an NBT array until you find the item. They might not seem obvious to all =)
Either way, great write up!
I'll probably update this blog to include "Picking from a list of locations" and "random items", but I think random nbt might be a bit to complicated for beginners, which is what this is focused on.