J'ai initialement déclaré que Minecraft utilise la classe Random
par défaut de Java pour la génération de nombres pseudo-aléatoires. Random
utilise des valeurs de départ de 48 bits.
Cependant, cela impliquerait que les valeurs de départ 1 et 2 48 +1 résultent dans le même monde, ce que d'autres ont souligné n'est pas vrai. J'ai donc creusé un peu plus.
Minecraft semble utiliser Random
partout sauf pour le code de génération de biome. Là, il utilise son propre générateur aléatoire maison. De GenLayer.java :
protected int nextInt (int upperBound) {int randVal = (int) ((this.chunkSeed >> 24)% (long) upperBound); if (randVal < 0) {randVal + = upperBound; } this.chunkSeed * = this.chunkSeed * 6364136223846793005L + 1442695040888963407L; this.chunkSeed + = this.worldGenSeed; return randVal;}
Ceci est un générateur congruentiel linéaire avec les valeurs a = 6364136223846793005
et m = 1442695040888963407
. Cela produira en effet 2 64 flux de sortie distincts, et donc il y a 2 64 mondes distincts.
La revendication sur le wiki Minecraft selon lequel "Les graines multijoueurs ne peuvent avoir que 2 48 valeurs possibles [..] en raison de l'utilisation de Random.nextLong ()
" est incorrect . Les générateurs de monde solo et multijoueur ne sont pas différents.
L'utilisation de Random
partout ailleurs signifie que certaines choses seront idem entre les graines qui sont décalées de 2 48 , comme les graines 1 et 2 48 +1. Par exemple, l'emplacement des minerais devrait être presque le même entre les deux (sauf pour les minerais enlevés par les systèmes de grottes) .
De plus, l'utilisation de graines par bloc a des conséquences intéressantes. Par exemple, étant donné le petit nombre de biomes et le grand nombre de morceaux, dans un monde donné, il y a une très forte probabilité qu'il y ait deux morceaux qui soient exactement les mêmes. Trouver ces morceaux, cependant, implique des mathématiques qui me dépassent. Si quelqu'un est intéressé à le découvrir, le code pour initialiser le chunkSeed
est
public void initChunkSeed (long chunkX, long chunkY) {this.chunkSeed = this. worldGenSeed; pour (int i = 0; i < 2; i ++) {this.chunkSeed * = this.chunkSeed * 6364136223846793005L + 1442695040888963407L; this.chunkSeed + = chunkX; this.chunkSeed * = this.chunkSeed * 6364136223846793005L + 1442695040888963407L; this.chunkSeed + = chunkY; }}