Hi all! I was playing some weeks in JE 14.4 Minecraft and suddenly got my world broken (level.dat and level.dat_old are corrupted)
I didnt any backups so I dont have world seed. Is it possible to reverse engineer it or find in logs? I know coordinates of spawn, ocean monument and village, also some biomes. Is these enough for restoring seed or it is impossible and what tools are using now for this?
I'm not sure...usually you could load in the game & use '/seed' to get the seed of the map, but if you can't load in the world then the only other way that MIGHT work is using something like nbtexplorer
Using this program & loading in the world data you can search through & find an entry like 'RandomSeed: xxxxxxxxxx' which is the seed used for the world generation (I'm guessing it's 'randomseed' as I didn't put in a seed value)
When I tested it out on a WORKING world I found the entry "saves > Test World > level.dat > data > RandomSeed"
You may be lucky that you can load in the corrupted world into 'nbtexplorer' & get to see what the seed is that way..
...I don't have a corrupted world to try out to see if this progam will at least read the files evn if Minecraft can't
I'm not sure...usually you could load in the game & use '/seed' to get the seed of the map, but if you can't load in the world then the only other way that MIGHT work is using something like nbtexplorer
Using this program & loading in the world data you can search through & find an entry like 'RandomSeed: xxxxxxxxxx' which is the seed used for the world generation (I'm guessing it's 'randomseed' as I didn't put in a seed value)
When I tested it out on a WORKING world I found the entry "saves > Test World > level.dat > data > RandomSeed"
You may be lucky that you can load in the corrupted world into 'nbtexplorer' & get to see what the seed is that way..
...I don't have a corrupted world to try out to see if this progam will at least read the files evn if Minecraft can't
My level.dat is broken so I cant open it in nbt expoler. Maybe there is a way to find the seed in log files or brute force it by structures ids? For example I have village, lost mine, sunk ship and ocean monument in it (and some biomes) so maybe I can use any tool to get set of working seeds?
There maybe someone there that can help recover your world
If it's just your level.dat corrupt a google seems to show some old videos etc on how to 'fix' these - have you tried these ?? (copy your original world & try on a backup first just in case things go totally wrong)
There maybe someone there that can help recover your world
If it's just your level.dat corrupt a google seems to show some old videos etc on how to 'fix' these - have you tried these ?? (copy your original world & try on a backup first just in case things go totally wrong)
I posted to this thread but it seems the only way is to generate new seed and move my regions to it. So I don't know my seed and don't have any backup to copy this like in youtube video - single level.dat that I had got corrupted(((
It is possible to reverse-engineer a seed by brute-force within a reasonable amount of time if you know the locations of structures and biomes but this requires advanced programming knowledge (I'm not sure how hard GPU programming is but this will never run in any reasonable amount of time with an ordinary CPU-based program, which I could write in less than an hour, since up to 281 trillion seeds need to be checked (then you need to check up to 65536 seeds for the biome layout, possibly more if there aren't enough structures; this is only possible at all due to the RNG used by most world generation only using 48 bits, making the search 65536 times faster), plus I don't have any source code for the algorithms since 1.13, which changed the way many structures are placed):
Using this program & loading in the world data you can search through & find an entry like 'RandomSeed: xxxxxxxxxx' which is the seed used for the world generation (I'm guessing it's 'randomseed' as I didn't put in a seed value)
If you don't enter a seed the game will choose a random seed, which will also always be a number and virtually always different (just storing "randomseed" would mean that every "random" world would have the same seed, otherwise it would still need to save an actual seed value or it would have no way to save the seed across sessions, which would completely mess up world generation. If you enter an alphanumeric seed it is hashed to a 32 bit integer; "0" is treated the same as entering nothing (it is perfectly valid to use 0 as a seed, and possible to enter a string that hashes to it, the game just needs to reserve one numerical value to tell it when to use a random seed).
... If you enter an alphanumeric seed it is hashed to a 32 bit integer; "0" is treated the same as entering nothing (it is perfectly valid to use 0 as a seed, and possible to enter a string that hashes to it, the game just needs to reserve one numerical value to tell it when to use a random seed).
Now, in the case of text seeds, all of these text strings will produce the same world:
"pollinating sandboxes"
"amusement & hemophilias"
"schoolworks = perversive"
"electrolysissweeteners.net"
"constitutionalunstableness.net"
"grinnerslaphappier.org"
"BLEACHINGFEMININELY.NET"
"WWW.BUMRACEGOERS.ORG"
"WWW.RACCOONPRUDENTIALS.NET"
You have to enter them (without the quotes) exactly as shown into Minecraft or Amidst.
Non-Minecraft websites about "pollinating sandboxes"
There are many technical pages that reference the "seed zero" texts as a programming problem that has to be accounted for.
This does not directly address the OP's problem, though the prior posts give about the best that can be had on recovery. The value is in level.dat, or the OP is screwed. As far as getting the text value that results in that seed value, it would require about the same effort to get the *text* seed as guessing a password from a hash value. Likely a ton of effort for not very much value, in this case. And there are a ton of possible text values for any given seed numeric value, as can be seen above.
Only seeds that can fit within the bounds of a 32 bit integer can have a text seed; conversely, if you generated a world with a random seed it will never have any of many 32 bit values due to Java's Random only having 48 bits of state (for example, the seed "TMCWv4" or "-1816924181" will never be obtained from a random seed; to get all possible 2^64 seeds you need to manually enter most of them. This also explains the "one of 65536 similar seeds", where only biome generation differs between seeds with the same lower 48 bits, since the biome generator uses a custom 64 bit RNG; as mentioned previously, this complicates using structure locations to reverse engineer a seed as you also need to verify the biome map, but at least you don't have as much searching to do).
So its unreal to brute force after 1.13? I can try to take google comput engine server for this
No, but one needs to know the algorithms used to generate structures, many of which changed in 1.13, and the knowledge to write a GPU-based program. Otherwise, it can be much faster today, given that the thread I linked to mentioned an "average gaming GPU" as of 2014, which took about 8 hours to brute-force a seed. I have no idea if the person (who hasn't been active since 2017) who made that thread is willing to share their code, even privately, since this is by definition a security exploit (they mention a bug report on the bug tracker but I can't find one, meaning it is likely hidden from the public).
However, I found some code that somebody posted, but you'd need to be able to compile it into a working C program, and it appears to only search for ocean monuments (due to the "spacing" and "separation" values; ocean monuments did not change in 1.13):
It is possible to reverse-engineer a seed by brute-force within a reasonable amount of time if you know the locations of structures and biomes but this requires advanced programming knowledge (I'm not sure how hard GPU programming is but this will never run in any reasonable amount of time with an ordinary CPU-based program, which I could write in less than an hour, since up to 281 trillion seeds need to be checked (then you need to check up to 65536 seeds for the biome layout, possibly more if there aren't enough structures; this is only possible at all due to the RNG used by most world generation only using 48 bits, making the search 65536 times faster), plus I don't have any source code for the algorithms since 1.13, which changed the way many structures are placed):
If you don't enter a seed the game will choose a random seed, which will also always be a number and virtually always different (just storing "randomseed" would mean that every "random" world would have the same seed, otherwise it would still need to save an actual seed value or it would have no way to save the seed across sessions, which would completely mess up world generation. If you enter an alphanumeric seed it is hashed to a 32 bit integer; "0" is treated the same as entering nothing (it is perfectly valid to use 0 as a seed, and possible to enter a string that hashes to it, the game just needs to reserve one numerical value to tell it when to use a random seed).
It is extremely reasonable to brute force a seed on CPU actually. The trick lies in using the end pillars:
Random rand = new Random(worldSeed);
long pillarSeed = rand.nextLong() & 65535L;
List pillars = IntStream.range(0, 10).boxed().collect(Collectors.toList());
Collections.shuffle(pillars, new Random(pillarSeed));
As you can see, this gives us 16 raw bits of the structure seed, tuning the search down from 2^48 to 2^32. I recently made a mod for it, check it out .
It is extremely reasonable to brute force a seed on CPU actually. The trick lies in using the end pillars:
long pillarSeed = rand.nextLong() & 65535L;
Is Mojang's coding really THAT bad these days:? Surely they know that this completely destroys any randomness since the low-order bits from an LCG are less random (nextLong takes the upper 32 bits from two successive cycles and combines them; this means that the lowest 16 bits of the result are using bits 17-32 of a single cycle, which will only have the period of a 32 bit LCG; in the worst-case nextLong & 1 will only have a period of 2^17); if you want a value between 0-65535 you want to use nextInt(65536) instead, which will use bits 33-48 for a period as long as the RNG itself (nextInt(n) has a special case for when n is a power of 2 to maximize its period), and why even truncate the seed to 16 bits anyway?
IMO, they should be replacing Random with a true 64 bit RNG, as I've done in my own mod/version; the way I set the per-chunk seed also (as far as I can tell) avoids the issues that Mojang's implementation has (did you know that in about a third of all seeds about a third of all chunks at sign-reversed coordinates have the same chunk seed, thus the same caves and other structures? Certainly, they need to change this if they make a "cave update" as this would become much more noticeable if they add in giant caves and stuff; I fixed this myself in TMCWv3, released in 2015, by altering the chunk seed when the z-coordinate was negative):
Not only this, this is FAR faster than Java's Random, as is a replica which avoids the use of "AtomicLong", which more than doubles the speed of vanilla cave generation with no other changes, and could likewise greatly benefit a seed search program written in Java (Mojang always talks so much about "optimizations", I've gone further to use a simpler 32 bit RNG for individual features like trees and ore veins which only have a limited number of variations, which is even faster, at least on a 32 bit OS, requiring only a single field in a base class. The overall randomness is preserved since a 64 bit RNG is used to seed the internal RNG as well as determine the chunk-relative offsets each time an attempt is made at placing them).
Either way, a (properly used) 64 bit RNG is 65536 times harder to crack - the thread I mentioned before said it took 8 hours for an average gaming GPU to find a match - which could instead be 60 years (Mojang already uses a 64 bit RNG for the biome generator, the only place in the code that uses it; even a randomly generated world seed will use Java's Random for only 2^48 possible seeds, plus every 32 bit value which isn't available from Random.nextLong, so most worlds will only take advantage of 1/65536 of the available seed space, making it much easier to find a biome match after you've found the 48 bit base seed since you only need to find the full 64 bit value that can be generated with nextLong).
This piece of code has been added in 1.9 and helped boost seed cracking into levels of insanity. I am also well aware of the weaknesses of LCGs. When it comes to world generation, the bias is immense but for the average player, it is random enough. I find beauty in the fact that some seeds have extremely exotic features.
Either way, a (properly used) 64 bit RNG is 65536 times harder to crack - the thread I mentioned before said it took 8 hours for an average gaming GPU to find a match - which could instead be 60 years (Mojang already uses a 64 bit RNG for the biome generator, the only place in the code that uses it; even a randomly generated world seed will use Java's Random for only 2^48 possible seeds, plus every 32 bit value which isn't available from Random.nextLong, so most worlds will only take advantage of 1/65536 of the available seed space, making it much easier to find a biome match after you've found the 48 bit base seed since you only need to find the full 64 bit value that can be generated with nextLong).
When it comes to your random implementation, it does indeed help with the entropy but it stills has its flaws. An LCG at its core is still only slightly safer than a number line; you have just obfuscated the problem. If Mojang ever makes the LCG 64-bits, building lattices for decorator features would be the way to go.
When it comes to your random implementation, it does indeed help with the entropy but it stills has its flaws. An LCG at its core is still only slightly safer than a number line; you have just obfuscated the problem. If Mojang ever makes the LCG 64-bits, building lattices for population features would be the way to go.
Aside from players being able to obtain the world seed by looking at certain features I don't see the need for anything better, especially not encryption-grade, which also usually means slower and I place very heavy emphasis on performance, which is why I use a 32 bit LCG for the internal RNG for most small feature generators (I have no idea why they ever decided to use the Mersenne Twister for Bedrock, which is not only slow but according to Wikipedia, "Can take a long time to start generating output that passes randomness tests, if the initial state is highly non-random—particularly if the initial state has many zeros. A consequence of this is that two instances of the generator, started with initial states that are almost the same, will usually output nearly the same sequence for many iterations", which doesn't sound good at all since e.g. the biome generator usually only gets the first few random values after setting the "layer" seed, often even just one).
At least in my case there is also the benefit of randomizing the offset of the grid used to space out structures on a per-seed basis, which also have a very wide range, from 536870912 to 1610612735, a range of 2^30 (in vanilla there is no offset, meaning that every world will always only ever have e.g. villages at chunk coordinates 0-23 plus a multiple of 32, even if you change the "magic number" that Spigot lets you alter to help deter reverse-engineering):
public MapGenVillageTMCW(World par1World, int distance, int size)
{
this.spawnRNG.setSeedModifiers(par1World.getSeed() + 10387312L);
this.offsetX = this.spawnRNG.getOffset();
this.offsetZ = this.spawnRNG.getOffset();
this.maxDistance = distance;
this.regionOffset = this.maxDistance - this.minDistance;
this.villageSize = size;
}
protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ)
{
// Large positive offset simplifies calculations (vanilla has to modify negative values so they are
// properly floored)
int x = chunkX + this.offsetX;
int z = chunkZ + this.offsetZ;
this.spawnRNG.setChunkSeed(x / this.maxDistance, z / this.maxDistance);
if ((x % this.maxDistance) == this.spawnRNG.nextInt(this.regionOffset) && (z % this.maxDistance) == this.spawnRNG.nextInt(this.regionOffset))
{
BiomeGenBase biome = this.worldObj.getBiomeGenForCoords(chunkX << 4 | 8, chunkZ << 4 | 8);
if (validBiomes.contains(biome))
{
// RNG used to determine structure layout (still based on Random)
this.rand.setSeed(this.spawnRNG.nextLong());
if (((x / this.maxDistance) & 1) == ((z / this.maxDistance) & 1))
{
return true;
}
else
{
// Ice Plains has 50% as many villages while Desert and Savanna have 75%
return biome != BiomeGenBase.icePlains && ((biome != BiomeGenBase.desert && biome != BiomeGenBase.savanna) || this.spawnRNG.nextBoolean());
}
}
}
return false;
}
public MapGenStrongholdTMCW(World par1World)
{
this.worldObj = par1World;
this.spawnRNG.setSeedModifiers(par1World.getSeed());
this.strongholdOffsetX = this.spawnRNG.getOffset();
this.strongholdOffsetZ = this.spawnRNG.getOffset();
}
protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ)
{
// Checks distance to avoid overflow at extreme distances
int distance = (Math.abs(chunkX) < 64 && Math.abs(chunkZ) < 64 ? chunkX * chunkX + chunkZ * chunkZ : 4096);
if (this.validStrongholdLocation(chunkX, chunkZ, distance))
{
this.rand.setSeed(this.spawnRNG.nextLong());
return true;
}
else
{
return false;
}
}
public boolean validStrongholdLocation(int chunkX, int chunkZ, int distance)
{
// Generates an infinite number of strongholds starting 40 chunks (640 blocks) from the origin,
// the same minimum distance used by vanilla; strongholds generate to a 128 chunk grid in
// alternating 64x64 chunk regions with a relative offset of 0-31 chunks, for one stronghold
// every 8192 chunks. The same algorithm is used for colossal and regional caves with different
// grid-relative offsets so they can never collide.
chunkX += this.strongholdOffsetX;
chunkZ += this.strongholdOffsetZ;
if ((chunkX & 64) != (chunkZ & 64)) return false;
this.spawnRNG.setChunkSeed(chunkX >> 6, chunkZ >> 6);
return (chunkX & 63) == this.spawnRNG.nextInt(32) && (chunkZ & 63) == this.spawnRNG.nextInt(32) && distance >= 1600;
}
Also, you have to admit that this is quite bad - many of the issues with vanilla have more to do with poorly-chosen methods to set the per-chunk seed; in this case, a third of all ravines (and caves) at sign-reversed coordinate pairs are identical:
All ravines:
Only ravines where the chunk seed is the same as the chunk at sign-reversed coordinates (e.g. -1,1 and 1,-1; this also includes 0,0, which has a ravine in this seed):
For comparison, the same seed in TMCW shows no matches (including at 0,0, which has a 1/50 chance of a ravine):
Also, 1.13 completely broke mineshaft generation in the seed for my first world (-123775873255737467) - every single mineshaft within 600 blocks of 0,0 has an identical counterpart at the opposite coordinates, while the same seed in 1.6 only has a few matches (only the latter have been verified in-game but it is improbable that so many mineshafts would exist at the exact opposite coordinates):
These are two identical mineshafts at around -480, 300 and 480, -300 in the 1.6 version (near the upper-left and lower-right on the second map above; there is a second mineshaft near the first one):
Point is, your implementation only offers a slight performance boost and fixes entropy issues that an average player is completely blind to. I honestly do not see a point in that since a multithreading friendly datatype is quite handy. Using smaller LCGs for feature generators also sounds a bit weird to me, how are those executed?
Point is, your implementation only offers a slight performance boost and fixes entropy issues that an average player is completely blind to. I honestly do not see a point in that since a multithreading friendly datatype is quite handy. Using smaller LCGs for feature generators also sounds a bit weird to me, how are those executed?
Multithreading? No need for that, and as mentioned before I place VERY heavy emphasis on performance and resource usage; can you even launch 1.15 with only 256 MB of RAM, or even 512 MB? Or even a 32 bit OS at all? Check this out:
Why do I place such emphasis on performance? Well, that is one reason why I never updated past 1.6.4, since 1.7 and especially 1.8 were just terrible (why did they ever think that allocating 200 MB of "blockpos" per second was a good idea? I don't even see how it makes things more "convenient", except if you want a method to return a set of coordinates). Of course, using a faster RNG mainly affects world generation, which is insanely fast compared to newer versions (yes, this was from creating a new world - existing worlds load so fast that "preparing spawn area", which updates once per second, never appears - the last time I ran a newer version, 1.13 shortly after it came out, it took longer to reload a world, nevermind how long the game itself took to launch compared to 1.6.4, vanilla or modded):
2019-12-24 16:07:27 [SERVER] [INFO] Starting integrated minecraft server version 1.6.4
2019-12-28 16:07:27 [SERVER] [INFO] Generating keypair
2019-12-28 16:07:27 [SERVER] [INFO] Converting map!
2019-12-28 16:07:27 [SERVER] [INFO] Scanning folders...
2019-12-28 16:07:27 [SERVER] [INFO] Total conversion count is 0
2019-12-28 16:07:27 [SERVER] [INFO] Preparing start region for level 0
2019-12-28 16:07:28 [SERVER] [INFO] Preparing spawn area: 37%
2019-12-28 16:07:29 [SERVER] [INFO] Preparing spawn area: 71%
2019-12-28 16:07:30 [SERVER] [INFO] TheMasterCaver[/127.0.0.1:0] logged in with entity id 6248 at (-98.5, 66.0, 234.5)
2019-12-28 16:07:30 [SERVER] [INFO] TheMasterCaver joined the game
Also, the simplicity of an LCG allows you to implement one with nothing more than a simple integer field and a single line of code (plus the conversion to an output), with all the logic included in a common base class (the first line in the generate() method uses a passed-in RNG to set the seed each time it is called):
I also use it elsewhere, such as the random block particle logic, which calls Random.nextInt() 6000 times per tick in vanilla, while I only need to calculate 3000 random integers, with each one providing two values and only requiring a single method call:
// Replaces doVoidFogParticles in WorldClient
public void doRandomDisplayTicks(int posX, int posY, int posZ)
{
for (int i = 0; i < 1000; ++i)
{
int x = this.nextInt16_16();
int y = this.nextInt16_16();
int z = this.nextInt16_16();
// Particles are only visible within 16 blocks, range for random display ticks is +/- 15
if (x * x + y * y + z * z < 256)
{
int block = this.getBlockId(posX + x, posY + y, posZ + z);
if (block > 0) Block.blocksList[block].randomDisplayTick(this, posX + x, posY + y, posZ + z, this.rand);
}
}
}
// Equivalent to nextInt(16) - nextInt(16)
private int nextInt16_16()
{
this.updateLCG = this.updateLCG * 1664525 + 1013904223;
return (this.updateLCG >>> 28) - ((this.updateLCG >>> 24) & 15);
}
In fact, even vanilla uses a simple home-brew LCG for random block updates, even though it probably makes no difference unless you set random tick speed to a very high value (at least they don't use the main Random instance, which is improperly used by structure generation, which sets its seed and results in weird bugs):
I've also compared the performance and Random is extremely slow when compared to the alternatives; as mentioned before, I doubled cave generation speed, a major component of chunk generation time, and certainly not a "slight" boost (a 50% reduction in time to be exact), by simply replacing Random with a functional equivalent (no other code changes; each iteration of the tunnel carving code calls nextFloat() 6 times and nextInt(4) once and includes mathematical operations including sine and cosine, if done using a lookup table (another example of an optimization in vanilla itself, as Java's own trig functions are quite slow due to complying to strict standards).
The main reason I do this is to offset the performance impacts of new features I add - many people claim that newer vanilla versions are more demanding due to more content but that is simply not true (TMCW is faster than vanilla 1.6.4; the next update will be much faster despite over 300 new features and includes numerous optimizations to rendering as well (currently not changed), including bugfixes and improvements, like smooth lighting on water and a larger biome blend radius, often blamed for lag in vanilla 1.13+).
Anyway, this is all insanely off-topic by now as it has little to do with reverse-engineering a seed (besides how they could have improved the security; even if not perfect a 64 bit LCG has to be much harder to crack than 48 bits since you have 65536 times more seeds - as long as they use it properly, not stuff like nextLong() & 65535, though that would still give a period that is 65536 times longer if the upper 32 bits are used, better yet if the upper 16 bits are used, as a nextInt(n) implementation would use for powers of 2; I specifically use a separate method for this to avoid having to check if it is a power of 2).
Hi all! I was playing some weeks in JE 14.4 Minecraft and suddenly got my world broken (level.dat and level.dat_old are corrupted)
I didnt any backups so I dont have world seed. Is it possible to reverse engineer it or find in logs? I know coordinates of spawn, ocean monument and village, also some biomes. Is these enough for restoring seed or it is impossible and what tools are using now for this?
I'm not sure...usually you could load in the game & use '/seed' to get the seed of the map, but if you can't load in the world then the only other way that MIGHT work is using something like nbtexplorer
Using this program & loading in the world data you can search through & find an entry like 'RandomSeed: xxxxxxxxxx' which is the seed used for the world generation (I'm guessing it's 'randomseed' as I didn't put in a seed value)
When I tested it out on a WORKING world I found the entry "saves > Test World > level.dat > data > RandomSeed"
You may be lucky that you can load in the corrupted world into 'nbtexplorer' & get to see what the seed is that way..
...I don't have a corrupted world to try out to see if this progam will at least read the files evn if Minecraft can't
My level.dat is broken so I cant open it in nbt expoler. Maybe there is a way to find the seed in log files or brute force it by structures ids? For example I have village, lost mine, sunk ship and ocean monument in it (and some biomes) so maybe I can use any tool to get set of working seeds?
Well that my idea out the window.. not sure of any other way (brute force or otherwise).
Maybe you could post your problem on https://www.minecraftforum.net/forums/minecraft-java-edition/discussion/297844-official-corrupted-save-recovery-thread
There maybe someone there that can help recover your world
If it's just your level.dat corrupt a google seems to show some old videos etc on how to 'fix' these - have you tried these ?? (copy your original world & try on a backup first just in case things go totally wrong)
I posted to this thread but it seems the only way is to generate new seed and move my regions to it. So I don't know my seed and don't have any backup to copy this like in youtube video - single level.dat that I had got corrupted(((
It is possible to reverse-engineer a seed by brute-force within a reasonable amount of time if you know the locations of structures and biomes but this requires advanced programming knowledge (I'm not sure how hard GPU programming is but this will never run in any reasonable amount of time with an ordinary CPU-based program, which I could write in less than an hour, since up to 281 trillion seeds need to be checked (then you need to check up to 65536 seeds for the biome layout, possibly more if there aren't enough structures; this is only possible at all due to the RNG used by most world generation only using 48 bits, making the search 65536 times faster), plus I don't have any source code for the algorithms since 1.13, which changed the way many structures are placed):
https://www.minecraftforum.net/forums/support/server-support-and/2106483-world-seeds-can-be-reverse-engineered
If you don't enter a seed the game will choose a random seed, which will also always be a number and virtually always different (just storing "randomseed" would mean that every "random" world would have the same seed, otherwise it would still need to save an actual seed value or it would have no way to save the seed across sessions, which would completely mess up world generation. If you enter an alphanumeric seed it is hashed to a 32 bit integer; "0" is treated the same as entering nothing (it is perfectly valid to use 0 as a seed, and possible to enter a string that hashes to it, the game just needs to reserve one numerical value to tell it when to use a random seed).
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
Non-Minecraft websites about "pollinating sandboxes"
https://www.cs.princeton.edu/courses/archive/fall18/cos226/lectures/34HashTables 35SearchingApplications.pdf
https://stackoverflow.com/questions/16400711/two-unequal-objects-with-same-hashcode
This does not directly address the OP's problem, though the prior posts give about the best that can be had on recovery. The value is in level.dat, or the OP is screwed. As far as getting the text value that results in that seed value, it would require about the same effort to get the *text* seed as guessing a password from a hash value. Likely a ton of effort for not very much value, in this case. And there are a ton of possible text values for any given seed numeric value, as can be seen above.
Only seeds that can fit within the bounds of a 32 bit integer can have a text seed; conversely, if you generated a world with a random seed it will never have any of many 32 bit values due to Java's Random only having 48 bits of state (for example, the seed "TMCWv4" or "-1816924181" will never be obtained from a random seed; to get all possible 2^64 seeds you need to manually enter most of them. This also explains the "one of 65536 similar seeds", where only biome generation differs between seeds with the same lower 48 bits, since the biome generator uses a custom 64 bit RNG; as mentioned previously, this complicates using structure locations to reverse engineer a seed as you also need to verify the biome map, but at least you don't have as much searching to do).
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
So its unreal to brute force after 1.13? I can try to take google comput engine server for this
No, but one needs to know the algorithms used to generate structures, many of which changed in 1.13, and the knowledge to write a GPU-based program. Otherwise, it can be much faster today, given that the thread I linked to mentioned an "average gaming GPU" as of 2014, which took about 8 hours to brute-force a seed. I have no idea if the person (who hasn't been active since 2017) who made that thread is willing to share their code, even privately, since this is by definition a security exploit (they mention a bug report on the bug tracker but I can't find one, meaning it is likely hidden from the public).
However, I found some code that somebody posted, but you'd need to be able to compile it into a working C program, and it appears to only search for ocean monuments (due to the "spacing" and "separation" values; ocean monuments did not change in 1.13):
https://gist.github.com/syule/4acbc2e1aba251db6caa7d50a0afe546
I found it in this Reddit thread which discusses ways to reverse engineer seeds: https://www.reddit.com/r/technicalminecraft/comments/7idgzx/seed_reverse_engineering_survey_of_approaches_and/
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
It is extremely reasonable to brute force a seed on CPU actually. The trick lies in using the end pillars:
As you can see, this gives us 16 raw bits of the structure seed, tuning the search down from 2^48 to 2^32. I recently made a mod for it, check it out .
Is Mojang's coding really THAT bad these days:? Surely they know that this completely destroys any randomness since the low-order bits from an LCG are less random (nextLong takes the upper 32 bits from two successive cycles and combines them; this means that the lowest 16 bits of the result are using bits 17-32 of a single cycle, which will only have the period of a 32 bit LCG; in the worst-case nextLong & 1 will only have a period of 2^17); if you want a value between 0-65535 you want to use nextInt(65536) instead, which will use bits 33-48 for a period as long as the RNG itself (nextInt(n) has a special case for when n is a power of 2 to maximize its period), and why even truncate the seed to 16 bits anyway?
IMO, they should be replacing Random with a true 64 bit RNG, as I've done in my own mod/version; the way I set the per-chunk seed also (as far as I can tell) avoids the issues that Mojang's implementation has (did you know that in about a third of all seeds about a third of all chunks at sign-reversed coordinates have the same chunk seed, thus the same caves and other structures? Certainly, they need to change this if they make a "cave update" as this would become much more noticeable if they add in giant caves and stuff; I fixed this myself in TMCWv3, released in 2015, by altering the chunk seed when the z-coordinate was negative):
https://www.dropbox.com/s/9d1kqn8b4gx2ep2/Random64.java?dl=0
Not only this, this is FAR faster than Java's Random, as is a replica which avoids the use of "AtomicLong", which more than doubles the speed of vanilla cave generation with no other changes, and could likewise greatly benefit a seed search program written in Java (Mojang always talks so much about "optimizations", I've gone further to use a simpler 32 bit RNG for individual features like trees and ore veins which only have a limited number of variations, which is even faster, at least on a 32 bit OS, requiring only a single field in a base class. The overall randomness is preserved since a 64 bit RNG is used to seed the internal RNG as well as determine the chunk-relative offsets each time an attempt is made at placing them).
Either way, a (properly used) 64 bit RNG is 65536 times harder to crack - the thread I mentioned before said it took 8 hours for an average gaming GPU to find a match - which could instead be 60 years (Mojang already uses a 64 bit RNG for the biome generator, the only place in the code that uses it; even a randomly generated world seed will use Java's Random for only 2^48 possible seeds, plus every 32 bit value which isn't available from Random.nextLong, so most worlds will only take advantage of 1/65536 of the available seed space, making it much easier to find a biome match after you've found the 48 bit base seed since you only need to find the full 64 bit value that can be generated with nextLong).
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
This piece of code has been added in 1.9 and helped boost seed cracking into levels of insanity. I am also well aware of the weaknesses of LCGs. When it comes to world generation, the bias is immense but for the average player, it is random enough. I find beauty in the fact that some seeds have extremely exotic features.
When it comes to your random implementation, it does indeed help with the entropy but it stills has its flaws. An LCG at its core is still only slightly safer than a number line; you have just obfuscated the problem. If Mojang ever makes the LCG 64-bits, building lattices for decorator features would be the way to go.
Aside from players being able to obtain the world seed by looking at certain features I don't see the need for anything better, especially not encryption-grade, which also usually means slower and I place very heavy emphasis on performance, which is why I use a 32 bit LCG for the internal RNG for most small feature generators (I have no idea why they ever decided to use the Mersenne Twister for Bedrock, which is not only slow but according to Wikipedia, "Can take a long time to start generating output that passes randomness tests, if the initial state is highly non-random—particularly if the initial state has many zeros. A consequence of this is that two instances of the generator, started with initial states that are almost the same, will usually output nearly the same sequence for many iterations", which doesn't sound good at all since e.g. the biome generator usually only gets the first few random values after setting the "layer" seed, often even just one).
At least in my case there is also the benefit of randomizing the offset of the grid used to space out structures on a per-seed basis, which also have a very wide range, from 536870912 to 1610612735, a range of 2^30 (in vanilla there is no offset, meaning that every world will always only ever have e.g. villages at chunk coordinates 0-23 plus a multiple of 32, even if you change the "magic number" that Spigot lets you alter to help deter reverse-engineering):
Also, you have to admit that this is quite bad - many of the issues with vanilla have more to do with poorly-chosen methods to set the per-chunk seed; in this case, a third of all ravines (and caves) at sign-reversed coordinate pairs are identical:
Only ravines where the chunk seed is the same as the chunk at sign-reversed coordinates (e.g. -1,1 and 1,-1; this also includes 0,0, which has a ravine in this seed):
For comparison, the same seed in TMCW shows no matches (including at 0,0, which has a 1/50 chance of a ravine):
Also, 1.13 completely broke mineshaft generation in the seed for my first world (-123775873255737467) - every single mineshaft within 600 blocks of 0,0 has an identical counterpart at the opposite coordinates, while the same seed in 1.6 only has a few matches (only the latter have been verified in-game but it is improbable that so many mineshafts would exist at the exact opposite coordinates):
These are two identical mineshafts at around -480, 300 and 480, -300 in the 1.6 version (near the upper-left and lower-right on the second map above; there is a second mineshaft near the first one):
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
Point is, your implementation only offers a slight performance boost and fixes entropy issues that an average player is completely blind to. I honestly do not see a point in that since a multithreading friendly datatype is quite handy. Using smaller LCGs for feature generators also sounds a bit weird to me, how are those executed?
Multithreading? No need for that, and as mentioned before I place VERY heavy emphasis on performance and resource usage; can you even launch 1.15 with only 256 MB of RAM, or even 512 MB? Or even a 32 bit OS at all? Check this out:
Why do I place such emphasis on performance? Well, that is one reason why I never updated past 1.6.4, since 1.7 and especially 1.8 were just terrible (why did they ever think that allocating 200 MB of "blockpos" per second was a good idea? I don't even see how it makes things more "convenient", except if you want a method to return a set of coordinates). Of course, using a faster RNG mainly affects world generation, which is insanely fast compared to newer versions (yes, this was from creating a new world - existing worlds load so fast that "preparing spawn area", which updates once per second, never appears - the last time I ran a newer version, 1.13 shortly after it came out, it took longer to reload a world, nevermind how long the game itself took to launch compared to 1.6.4, vanilla or modded):
Also, the simplicity of an LCG allows you to implement one with nothing more than a simple integer field and a single line of code (plus the conversion to an output), with all the logic included in a common base class (the first line in the generate() method uses a passed-in RNG to set the seed each time it is called):
(this is the first LCG listed by Wikipedia)
I also use it elsewhere, such as the random block particle logic, which calls Random.nextInt() 6000 times per tick in vanilla, while I only need to calculate 3000 random integers, with each one providing two values and only requiring a single method call:
In fact, even vanilla uses a simple home-brew LCG for random block updates, even though it probably makes no difference unless you set random tick speed to a very high value (at least they don't use the main Random instance, which is improperly used by structure generation, which sets its seed and results in weird bugs):
I've also compared the performance and Random is extremely slow when compared to the alternatives; as mentioned before, I doubled cave generation speed, a major component of chunk generation time, and certainly not a "slight" boost (a 50% reduction in time to be exact), by simply replacing Random with a functional equivalent (no other code changes; each iteration of the tunnel carving code calls nextFloat() 6 times and nextInt(4) once and includes mathematical operations including sine and cosine, if done using a lookup table (another example of an optimization in vanilla itself, as Java's own trig functions are quite slow due to complying to strict standards).
The main reason I do this is to offset the performance impacts of new features I add - many people claim that newer vanilla versions are more demanding due to more content but that is simply not true (TMCW is faster than vanilla 1.6.4; the next update will be much faster despite over 300 new features and includes numerous optimizations to rendering as well (currently not changed), including bugfixes and improvements, like smooth lighting on water and a larger biome blend radius, often blamed for lag in vanilla 1.13+).
Anyway, this is all insanely off-topic by now as it has little to do with reverse-engineering a seed (besides how they could have improved the security; even if not perfect a 64 bit LCG has to be much harder to crack than 48 bits since you have 65536 times more seeds - as long as they use it properly, not stuff like nextLong() & 65535, though that would still give a period that is 65536 times longer if the upper 32 bits are used, better yet if the upper 16 bits are used, as a nextInt(n) implementation would use for powers of 2; I specifically use a separate method for this to avoid having to check if it is a power of 2).
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?