Minecraft Blogs / Tutorial

⚙️ Datapacking In-Depth: This is so random... | Randomizing | DID 3

  • 1,919 views, 3 today
  • 17
  • 7
  • 9
Kefaku's Avatar Kefaku
Level 41 : Master Nerd
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
⚙️ Datapacking In-Depth: This is so random... | Randomizing | DID 3
⚙️ Datapacking In-Depth: This is so random... | Randomizing | DID 3
⚙️ Datapacking In-Depth: This is so random... | Randomizing | DID 3



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
  1. It summons a marker to mark the random location
  2. It teleports it to a random location within a 5 block radius using /spreadplayers.
  3. It summons an item (diamond) at the new location of the marker and...
  4. ... kills the marker, in order to leave no unnecessary entites behind and prevent lag.
Wooooooow! Free diamonds:



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

LOAD MORE LOGS

Create an account or sign in to comment.

2
03/24/2024 5:01 pm
Level 17 : Journeyman Blacksmith
Neceros
Neceros's Avatar
random is a thing now

execute store result score #number rng run random roll 1..3
1
03/26/2024 5:25 am
Level 41 : Master Nerd
Kefaku
Kefaku's Avatar
yeah, I'll have to update this blog, but I didn't have time to do that yet
2
03/30/2023 1:03 am
Level 27 : Expert Taco
Xboy1282
Xboy1282's Avatar
The loot table method doesn't work for me, it just sets the scoreboard to 0, even when I change the count of the items or change the scoreboard itself to be something else than 0, it just changes back to 0
1
03/30/2023 9:01 am
Level 41 : Master Nerd
Kefaku
Kefaku's Avatar
Do you mind sharing your datapack with me, so I can take a look?
2
01/08/2023 1:41 pmhistory
Level 70 : Legendary Engineer
Bertiecrafter
Bertiecrafter's Avatar
Wow, in all my searching I didn't come across the 0 item loot table trick, that's amazing. Real nice to see "random location" mentioned too.

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!
2
01/21/2023 5:05 pm
Level 41 : Master Nerd
Kefaku
Kefaku's Avatar
added a short section "6.2. Location from List" and a resource for loot tables, because of your feedback
3
01/08/2023 2:54 pm
Level 41 : Master Nerd
Kefaku
Kefaku's Avatar
Yeah, the 0 item loot table is cool, although I'm not sure whether the items aren't actually spawned or spawned and instantly deleted, which could cause lag spikes for large numbers.

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.
2
01/08/2023 9:53 am
Level 67 : High Grandmaster Bear
Silabear
Silabear's Avatar
dam this is good
2
01/08/2023 11:52 am
Level 41 : Master Nerd
Kefaku
Kefaku's Avatar
thanks :D
Planet Minecraft

Website

© 2010 - 2024
www.planetminecraft.com

Welcome