Useful information about world seeds -- how to get closer to the world you want!

The other day, I was generating seeds to try and get a very specific set of conditions. I got bored with re-rolling, and tried entering some “meaningful” numbers that the random generator was staying well away from; things like my birthday and so on.

Eventually, I got around to entering the numbers 1 through to 0… and the seeds were very very similar! Well, at least until I got to 0 – that seed looked a lot closer to the seed “1” than it did to the seed “9”.

So, I experminted. “10” yielded something very close to “9”, but more… IDK, developed? Hilly? There was more variation to it compared to the single-digit seeds.

Then, I rolled a random seed, and got the large number from it. I changed the end digits up and down by a few places, and kept similar results. When I changed the middle digits or the initial digits, the results varied wildly.

This implies that seeds have a value order – the first few numbers set one variable, the next group of numbers affect a different variable, and so on. It may alternatively mean that, among the number of seeds the game can generate, different outcomes are stored in numerical order… however, that would imply that the game has pre-generated every seed and stored them in some kind of list, which I think must be very unlikely for that list would have to be massive. That’s why I believe it’s the former option, rather than the latter.

And so, that’s how I found one useful bit of info for generating new seeds: similar seeds yield similar results; with larger numbers giving more varied terrain. It’s not as simple as “larger = rougher”, actually the larger numbers seem smoother, but they have more terrain features. By contrast, lower numbers tend to give flatter terrain with sharper cliffs and corners, and more water.

So, if you roll a seed that you kind-of like but aren’t quite happy with, select the seed text and change the last couple digits to slightly change the way that lakes, elevations, clay pits and forests are distributed. I presume this affects all map features including trees, statues and rocks; however there’s no way to see those from the map generator screen and loading up each map to check would take more patience than I have, lol.

Also, all of my tests are conducted with the Darkmoor Forest biome, I don’t know what happens with other biomes. I don’t expect dramatic changes, but it may be that different biomes use the seeds differently?

I’d be very keen to see how this info fits into a larger picture of world generation… given the popularity of seeds and trying to reverse-engineer them in Minecraft and other such games, I’m hoping that someone with previous experience can contribute their knowledge here. If we can figure out (or get a Dev explanation of) how the seed inputs are turned into a map, that might lead to a lot of cool new options; particularly for builders who want specific terrain features to work with…

2 Likes

Yeah, noticed that, too. Made a GIF to show what it’s about:

Reverse engineering for Minecraft won’t work, though. Despite both games using a similar approach, the implementation is vastly different. In any case, it seems to be based on Perlin-Noise, if you’re interested to further dive into that topic.

Edit: I think I’m kinda wrong. Theoretically it should be possible to develop a mod for Minecraft to achieve a world generation like Stonehearth. Not sure, how feasible it is, though.

4 Likes

Woah, that GIF is phenomenally helpful!

I had a suspicion that the seed “evolution” from one number to the next might actually be related to moving around the world location, but I wrote that off as just a trick of the eye/imagination. Clearly I should have searched a little bit harder, or used more exact search terms…

I’m aware that Minecraft seeds have basically no resemblance, code-wise, to Stonehearth seeds; I merely raised the comparison to bring up how much effort Minecrafters are prepared to spend to find out more about seeds… there’s something about world seed generation that appeals to some players on a deep level. I think it would be quite reasonable to expect a significant cross-over between the two communities; so I posted this thread to spark some further discussion and hopefully catch the attention of interested parties. What I’m interested in is understanding how Stonehearth’s seed generator works, so that we can hopefully come up with a formula for “if you want ___ and _____ in your world, type in _____”.

One very intersting point that your GIF raises: the water doesn’t seem to move, the terrain rolls over it but the water stays roughly in the same place and shape each time; only changing when the elevation around it changes. If we assume that the game has certain rules about where water can’t generate (e.g. we know it can’t generate on the edge of a cliff, and there has to be a set amount of level space between the different elevations of a mountain), then it looks like the size and shape of any bodies of water is related to the terrain around it; but on a perfectly flat belt of terrain the lakes would probably be the same size and shape each time.

Notice also that islands only form in the lakes when there’s a “clay pit” surrounded by water… again, the game has to preserve an edge of terrain around the water to keep it in place.

I would guess that the location for those water bodies is determined by some bits further along again, so a little digging should be able to turn up which digits correspond to water placement locations. I may have to mod together a totally flat biome to play around with…

Imagine how cool it would be to have control over even just some of the terrain feature placement though! Being able to move most of the water to, say, the top-right corner of the map, or have an even sprinkling of ponds and then move the X and Y coords to a very mountainous/rough location… it’s becoming a more realistic possibility.

I mean, technically, the whole world generation is kinda “open source” if you take a look into the game files (world_generation_service.lua and all its thousand includees). I do not have the desire to fully understand it though, as it’s an awful lot of math, with filters and noises stacked on top of each other.

The basic premise, I believe, is that there’s noisemaps for things - one for elevation, one for vegetation, probably one for wildlife, that might be related in some way or another. Before the revamp some Alphas ago, the system had some idea of sub-tiles/areas (I suppose you could call them “biome”), that had slightly adjusted maps and rules. For example, under a certain attitude, all trees were oak, followed by an vertical area where both could appear, followed by junipers (and finally, I think, followed by nothing?). All those hard-coded rules have been replaced since then; and put into JSON. You can take a look at it in temperate.json (or desert.json if Rayya’s Children is more to your liking), which defines some constraints/rules that the world generator follows.

Technically, there’s nothing to it and you could write an own application which lets you generate as much map as you want, and as different as you want (and in all likelihood, much faster than SH too, because each tile could be threaded). It would require understanding the current generation code however, and then writing it in whatever tool you want to. I would say it’s an interesting task, but I’m not a fan of that kind of maths.

5 Likes

The reason that seeds are very similar when numbers are very close is because it is a simple mathematical formula. Imagine a formula that draws a line as a result, if you change a number in it, the line will be different, and the more difference in the numbers you use, more different the lines will be. This is the same thing, but in 2d.
Everything in the map is based on simplex-noise (as mentioned above, like perlin-noise, but better).
Here is a image to help understand:

The game generates something like this image. Now imagine that this is a black and white photo of your terrain, viewed from above. White areas are tall mountain, dark are low plains. There was a formula to create this image, using a seed number in the equation. Changing it just a bit will not result in much differences. That’s why seeds next to each other seems similar.

Now, to some points you made.

Well, it does follow the terrain, the reason it changes way less than the terrain, is because it uses another black and white image for itself, on top of the terrain image. White areas will have water, black areas will not have water, plus a few rules, like you said, there is no water at edges.

The clay pits (dirt holes) can create islands a lot because they ignore water bodies when generating. If you test the same seed, but this time changing the code to generate without the dirt holes, you will see that where there was an island is just a lake now. I made this test before, they force islands to be able to be generated in the water. (I had this problem in my archipelago biome, that’s why I removed them in it)

Water is generated using another height map (those black and white images).

Correct.
For example, imagine another image, just for the trees, white areas will have tress, black will not. Brighter are bigger trees, darker small.

4 Likes

Ok, that lines up with the picture I had in my head – I’ve seen that kind of noisemap before in similar applications, and it’s what I was referring to when I said “water placement locations”. I was assuming that the bits further along in the seed were what was generated that heightmap, or selected a location in it.

So, by knowing which bits correspond to which heightmaps, we gain some control over the generation without having exact control. Good for creating natural-looking terrain, but still having rough overall control of what’s there (e.g. making sure there’s a lake relatively where you want it, that there are cliffs roughly where you want them, and so on).

Obviously biome/map modding gives much finer control over those heightmaps if the modder wishes, I’ve taken a cursory glance over some of those threads already to see what kind of modding options are already in use and I can see that there’s a lot more control available than was exposed in other games I’ve modded…

As the title of this thread implies, my focus here was more from a player perspective rather than modding – I will, eventually, get around to modding myself (and then I’ll have plenty of annoying questions for all of you existing modders :P), but not every player wants to take advantage of that capability. What I wanted to do with this thread was give “vanilla” players, especially builders, some extra tools to speed up the process of finding their ideal building site, should they have one in mind. Many times it’s a journey of working with the site the map generator gives you, and that can certainly be a fun way to play; but sometimes there’s an idea you can’t get rid of and that requires a certain set of map features… I’m sure that urge has been the basis of many wonderful map mods in various building games, lol! In fact, the first mod I ever wrote for a game was a map mod to create just such a setting for a project I had in mind.

But yeah, thanks to everyone @SachielMF @RepeatPan @BrunoSupremo for those answers, tips and bits of perspective. Unfortunately I don’t have the ability to take the “science” any further from a code end; but I’ll try some experiments from a player/in-game end to see how practical it is to manipulate the terrain generation via the seed.

I don’t think it will be as simple as “type in this formula and get the terrain you’ve been dreaming of!”, but that’s my ultimate wish here – being able to know that, say, having a 4 in the first digit will give a particular effect. I’m guessing that each digit (or rather, a certain group of digits which correspond to particular bits in the sequence… a stab in the dark guess would be that it’s 8 bits each for “decorations” like trees, then water, then Y axis and X axis respectively) will yield a particular heightmap, and by combining known heightmaps we can roughly “plot out” the map features we want. That would require seeing and understanding the particular heightmaps, or else a LOT of experimentation to deduce the effect that each one creates…

meh, it’s an interesting enquiry to occupy the evening with. As I’ve said, I’ve got no ability to follow it up beyond making use of the very basic knowledge that I can alter the generation slightly; but perhaps someone else will see this and be inspired to take it further :slight_smile: Or maybe it will help some builder who is sick of finding almost the right terrain every time, but wishes they could just make that lake a little bigger or move the mountains slightly…

Just to make it more clear (I don’t know if you got this idea) the seed is a single number used by all features. It is not divided into digits, like the half part to terrain, the next 2 digits to water and last digits to features, no. It is a whole number, else, seeds like “15” will not work for the lack of digits. This whole and same number is used by all features at that map.

The reason for when you change just the last digit resulting in very small changes, and changing the first digit resulting in a total different map is because it is a bigger number.
If you jump from 1001 to 1002 you just increased the seed by 1, so a small change.
If you jump from 1001 to 2001, you increase it by 1000, so a bigger change is noticed.

1 Like

Looking at this post, and its mention of the upper and lower digits of that 32-bit integer, I interpreted that as having two possibilities:

  1. The number is used to create the heightmaps, and then a certain part of the number is used to pick coordinates for a section of that heightmap to pull from when determining the output within an area.
  2. The heightmaps are created from the seed, and then overlayed with the game map directly.

I was assuming it was the latter, since that’s the simplest and most logical implementation. However, I have seen more complex versions where, instead of simply using the current map coordinate as the heightmap coordinate, the game does weird and wonderful extra steps to further “roughen” the output. In the case I’m thinking of, the game looked at what quadrant of the map (on a cartesian plane) that coord was in, and then used that to pick 1/4 of the seed as the input for a second pass of noise generation.

But, even assuming the simplest option, there are clear links between parts of the seed and their effects on the generation. I don’t claim to know how exactly it works, but it seems that the different heightmaps “favour” one end of the integer. I would guess (and again, my guesses aren’t worth much) that there’s a “multiply by negative” in one or some of the simplex algorithms/equations (IDK which is the proper term here) but not the others, possibly just to further separate the results. So, even though the whole number is important for the end result, if my guess is close to accurate then particular combinations can be traced back to specific inputs.

Adding 1000 to the seed would result in a very different map, yes, but ticking over only the largest bit to cause a wrap-around would create an identical (or perhaps not quite identical?) seed. But that’s just the conversion of the entered number to bits; my goal here is wrapping around the simplex generator itself so that the heightmap produced conforms to a set expectation. If adding 1000 repeatedly gives a consistent result, then after X number of repetitions a pattern should emerge.

What I’m talking about is tracing the effects back, and loading the seed with numerals based upon the knowledge of what the simplex mapping will convert that to. Even though the game reads the seed as a whole, the order of the numerals is still important – there is a finite number of possibilities, even though it’s really really large it’s not random. Figuring out the output of each seed obviously isn’t practical; and it would be much faster to automate the process and have a computer spit out every possible result. But what I’m interested in isn’t exact results, it’s the patterns. The algorithms don’t change, so if there’s a pattern that creates, say, large plains with no trees, that’s useful for players to know about. Then it’s down to trial and error to get the best possible result.

If the player only cares about particular features, e.g. they want to target large plains with no trees but don’t care about water or where the mountains are, then there will be certain seed inputs which create that a set of large plains with no trees on them; if there’s a visible pattern running through those inputs then that becomes a general rule they can apply. The rules may not combine well, since that’s not how the simplex algorithm works; but it should still be possible to control at least one variable at a time if the pattern can be established. Now, it’s entirely possible that any such pattern won’t show up readily, or that there is no such pattern; but there’s no logical reason for Radiant to go out of their way with excessive randomisation… so I’m hopeful that those patterns will exist. Depending on what the simplex noise generator does with the input, the process may be straightforward or downright impossible.

But, if it’s possible, then the goal is to create a guideline based upon the inputs, not the method. I mean, I’m banking on the possibility that figuring this out creates a straightforward list of generation rules; one which is simpler to learn than going through the process of learning about noise generation and how to apply the heightmaps. If I knew that, I would have applied it to a mod by now LOL!

Again though, thanks for indulging my curiosity, ignorance and imagination. Together they can be a dangerous combination… but, that’s how I come up with the motivation to go spend the time and effort learning new stuff to put those crazier and less-informed thoughts into practice.

Very interesting, but I think it is just a math coincidence. The function wraps to the same point. Like for example a function about angles, 1 would be similar to 2, and to 3. But if you add 360, instead of getting a very different result you get the same because it wraps.
Looking at the code I found nothing that looks like splitting the bits into different areas like the first bits for terrain and last bits for details or water. They always grabs it as a whole number.

I tested the seed 1 and the seed 65536, they looked equal. And were similar to their next neighbors (1 to 2 and 65536 to 65537).
But the seed 65535 (1 before 65536) was completely different.

1 Like