PRNG/LCG Method
Post based on this reddit post
Range varies depending on the implementation. The one in this post has the following range
Min |
Max |
−2 147 483 648 |
2 147 483 647 |
Creating your own pseudo random number generator is in (almost) all cases the least lag intensive and most flexible way of getting a random number. Using functions and this method you can get hundreds of different random numbers per tick without causing any significant lag, as it's just a handful of scoreboard commands.
What is a PRNG/LCG?
A PRNG is a pseudo random number generator, pseudo because it's not really random and actually predictable, but to a human it looks random enough. Most computer based random generators are actually PRNGs, because computers aren't very good at actual randomness. They were designed not to. Wikipedia on PRNGs
LCG stands for linear congruential generator and it's one of the most common ways to implement a PRNG, probably because of it's ease of use, reliability and the fact that it has been known for a long time. It's just a bunch of arithmetic operations chained together. Wikipedia on LCG
LCG in Minecraft
Setup
Our only option for mathematical operations is scoreboards, so we'll be using those. For the LCG to work, we'll need a few hard-coded values and for ease of understanding we'll use 2 different dummy scoreboards.
/scoreboard objectives add RNG_Constant dummy
/scoreboard objectives add RNG_Variable dummy
Then we set the constants that we'll work with, as well as initializing the seed.
/scoreboard players set C_1000 RNG_Constant 1000
/scoreboard players set C_314159 RNG_Constant 314159
/scoreboard players set C_2718281 RNG_Constant 2718281
/scoreboard players set RNGseed RNG_Variable 0
Getting a random number
Finally, the list of commands to run in order to get the random number. To make it slightly less predictable, we change the starting value of the variable to something like the in-game time or the amount of entities or any other variable amount using execute store
(line 2).
/scoreboard players add RNGseed RNG_Variable 1
/execute store result score RNG RNG_Variable run time query gametime
/scoreboard players operation RNG RNG_Variable *= RNGseed RNG_Variable
/scoreboard players operation RNG RNG_Variable *= C_314159 RNG_Constant
/scoreboard players operation RNG RNG_Variable *= C_2718281 RNG_Constant
/scoreboard players operation RNG RNG_Variable *= RNG RNG_Variable
/scoreboard players operation RNG RNG_Variable /= C_1000 RNG_Constant
/scoreboard players operation RNG RNG_Variable *= C_314159 RNG_Constant
/scoreboard players operation RNG RNG_Variable *= C_2718281 RNG_Constant
After running these commands, the RNG RNG_Variable
score will be a random number that you can use in whatever way you see fit. /scoreboard players get RNG RNG_Variable
.
You can scale the result down to a desired range using scoreboard players operation
with the modulo (%=
) operator. Note that minecrafts modulo algorithm will only result in positive numbers, so keep that in mind if you need negative values, too.