Up to date
This page is up to date for Godot 4.0
.
If you still find outdated information, please open an issue.
Random number generation¶
Many games rely on randomness to implement core game mechanics. This page guides you through common types of randomness and how to implement them in Godot.
After giving you a brief overview of useful functions that generate random numbers, you will learn how to get random elements from arrays, dictionaries, and how to use a noise generator in GDScript.
Note
Computers cannot generate "true" random numbers. Instead, they rely on pseudorandom number generators (PRNGs).
Global scope versus RandomNumberGenerator class¶
Godot exposes two ways to generate random numbers: via global scope methods or using the RandomNumberGenerator class.
Global scope methods are easier to set up, but they don't offer as much control.
RandomNumberGenerator requires more code to use, but allows creating multiple instances, each with their own seed and state.
This tutorial uses global scope methods, except when the method only exists in the RandomNumberGenerator class.
The randomize() method¶
In global scope, you can find a randomize() method. This method should be called only once when your project starts to initialize the random seed. Calling it multiple times is unnecessary and may impact performance negatively.
Putting it in your main scene script's _ready()
method is a good choice:
func _ready():
randomize()
public override void _Ready()
{
GD.Randomize();
}
You can also set a fixed random seed instead using seed(). Doing so will give you deterministic results across runs:
func _ready():
seed(12345)
# To use a string as a seed, you can hash it to a number.
seed("Hello world".hash())
public override void _Ready()
{
GD.Seed(12345);
GD.Seed("Hello world".Hash());
}
When using the RandomNumberGenerator class, you should call randomize()
on
the instance since it has its own seed:
var random = RandomNumberGenerator.new()
random.randomize()
var random = new RandomNumberGenerator();
random.Randomize();
Getting a random number¶
Let's look at some of the most commonly used functions and methods to generate random numbers in Godot.
The function randi() returns a random
number between 0 and 2^32-1. Since the maximum value is huge, you most likely
want to use the modulo operator (%
) to bound the result between 0 and the
denominator:
# Prints a random integer between 0 and 49.
print(randi() % 50)
# Prints a random integer between 10 and 60.
print(randi() % 51 + 10)
// Prints a random integer between 0 and 49.
GD.Print(GD.Randi() % 50);
// Prints a random integer between 10 and 60.
GD.Print(GD.Randi() % 51 + 10);
randf() returns a random floating-point number between 0 and 1. This is useful to implement a Weighted random probability system, among other things.
randfn() returns a random floating-point number following a normal distribution. This means the returned value is more likely to be around the mean (0.0 by default), varying by the deviation (1.0 by default):
# Prints a random floating-point number from a normal distribution with a mean 0.0 and deviation 1.0.
var random = RandomNumberGenerator.new()
random.randomize()
print(random.randfn())
// Prints a normally distributed floating-point number between 0.0 and 1.0.
var random = new RandomNumberGenerator();
random.Randomize();
GD.Print(random.Randfn());
randf_range() takes two arguments
from
and to
, and returns a random floating-point number between from
and to
:
# Prints a random floating-point number between -4 and 6.5.
print(randf_range(-4, 6.5))
RandomNumberGenerator.randi_range() takes two arguments from
and to
, and returns a random integer between from
and to
:
# Prints a random integer between -10 and 10.
var random = RandomNumberGenerator.new()
random.randomize()
print(random.randi_range(-10, 10))
// Prints a random integer number between -10 and 10.
random.Randomize();
GD.Print(random.RandiRange(-10, 10));
Get a random array element¶
We can use random integer generation to get a random element from an array:
var _fruits = ["apple", "orange", "pear", "banana"]
func _ready():
randomize()
for i in range(100):
# Pick 100 fruits randomly.
print(get_fruit())
func get_fruit():
var random_fruit = _fruits[randi() % _fruits.size()]
# Returns "apple", "orange", "pear", or "banana" every time the code runs.
# We may get the same fruit multiple times in a row.
return random_fruit
private string[] _fruits = { "apple", "orange", "pear", "banana" };
public override void _Ready()
{
GD.Randomize();
for (int i = 0; i < 100; i++)
{
// Pick 100 fruits randomly.
GD.Print(GetFruit());
}
}
public string GetFruit()
{
string randomFruit = _fruits[GD.Randi() % _fruits.Length];
// Returns "apple", "orange", "pear", or "banana" every time the code runs.
// We may get the same fruit multiple times in a row.
return randomFruit;
}
To prevent the same fruit from being picked more than once in a row, we can add more logic to this method:
var _fruits = ["apple", "orange", "pear", "banana"]
var _last_fruit = ""
func _ready():
randomize()
# Pick 100 fruits randomly.
for i in range(100):
print(get_fruit())
func get_fruit():
var random_fruit = _fruits[randi() % _fruits.size()]
while random_fruit == _last_fruit:
# The last fruit was picked, try again until we get a different fruit.
random_fruit = _fruits[randi() % _fruits.size()]
# Note: if the random element to pick is passed by reference,
# such as an array or dictionary,
# use `_last_fruit = random_fruit.duplicate()` instead.
_last_fruit = random_fruit
# Returns "apple", "orange", "pear", or "banana" every time the code runs.
# The function will never return the same fruit more than once in a row.
return random_fruit
private string[] _fruits = { "apple", "orange", "pear", "banana" };
private string _lastFruit = "";
public override void _Ready()
{
GD.Randomize();
for (int i = 0; i < 100; i++)
{
// Pick 100 fruits randomly.
GD.Print(GetFruit());
}
}
public string GetFruit()
{
string randomFruit = _fruits[GD.Randi() % _fruits.Length];
while (randomFruit == _lastFruit)
{
// The last fruit was picked, try again until we get a different fruit.
randomFruit = _fruits[GD.Randi() % _fruits.Length];
}
_lastFruit = randomFruit;
// Returns "apple", "orange", "pear", or "banana" every time the code runs.
// The function will never return the same fruit more than once in a row.
return randomFruit;
}
This approach can be useful to make random number generation feel less repetitive. Still, it doesn't prevent results from "ping-ponging" between a limited set of values. To prevent this, use the shuffle bag pattern instead.
Get a random dictionary value¶
We can apply similar logic from arrays to dictionaries as well:
var metals = {
"copper": {"quantity": 50, "price": 50},
"silver": {"quantity": 20, "price": 150},
"gold": {"quantity": 3, "price": 500},
}
func _ready():
randomize()
for i in range(20):
print(get_metal())
func get_metal():
var random_metal = metals.values()[randi() % metals.size()]
# Returns a random metal value dictionary every time the code runs.
# The same metal may be selected multiple times in succession.
return random_metal
Weighted random probability¶
The randf() method returns a floating-point number between 0.0 and 1.0. We can use this to create a "weighted" probability where different outcomes have different likelihoods:
func _ready():
randomize()