Quick answer: Godot randi() returning the same values each session? The global RNG’s seed is fixed unless you call randomize(). Most games want a seeded run plus a randomize at boot.

A loot system always drops the same items in the same order across sessions. The dev never called randomize() so the seed is always 0.

Call randomize() Once

func _ready():
    randomize()

Seeds the global RNG from system time. Call in an autoload’s _ready so every session has a fresh seed.

Per-Instance RNG

var rng = RandomNumberGenerator.new()
rng.randomize()
var n = rng.randi()

For deterministic systems (replays, procedural generation), create an RNG with a known seed. Reproducible across runs.

Seed Storage

Save the seed alongside save data. Loading restores the seed and replay regenerates the same content.

Multi-Threaded Random

Multiple threads sharing the global RNG produce inconsistent results. Give each thread its own RandomNumberGenerator.

Verifying

Loot orders differ across sessions. Replays with the same seed produce identical loot sequences.

“Global RNG defaults to seed 0. randomize() once or use per-instance RNGs with explicit seeds.”

Adopt per-instance RandomNumberGenerator for every system that might need replay or deterministic testing — the global one is a footgun at scale.