Followers 0

# Random Map generator needs improvement

## 7 posts in this topic

I have a random map generator, that essentially uses the X/Y location of the tile as the seed to identify its tile type.  (infinite terrain without needing to save it)

However, its too random.  the terrain is peppered with any terrain type.  I would like it to be more splotchy.

What I was planning, was to divide it into regions (like x >> 4, y >> 4) of 16x16 to increase the likely hood of a particular type, but then I end up with squares.  any thoughts?

Here is the code I use:

    public static int PickANumber0ThoughN(int seed, int x, int y, int range)
{
uint hash = (uint)seed;
hash ^= (uint)x;
hash *= 0x51d7348d;
hash ^= 0x85dbdda2;
hash = (hash << 16) ^ (hash >> 16);
hash *= 0x7588f287;
hash ^= (uint)y;
hash *= 0x487a5559;
hash ^= 0x64887219;
hash = (hash << 16) ^ (hash >> 16);
hash *= 0x63288691;
return (int)(hash % range);
}
int tileTypeId = PickANumber0ThoughN(playerid, tileX, tileY, TileTypes.Length) - returns a seemingly random tile, that is the same every time the method is called.  I'm considering ways. to improve that to make larger blocks of random code, without adding much cost here.  Any ideas? I'm not opposed to using polar coordinates,
Edited by Dan Violet Sagmiller
1

##### Share on other sites

an interesting challenge.

terrain that makes sense, randomly generated, on the fly, no saving to disk or ram.

can you lose the "no saving to ram" requirement, and generate sections at a time in ram at least? if so you can apply more sophisticated distributions to your tile patterns, but the algos may not be fast enough to do it from scratch every frame for every tile.

essentially, you'd have part of your world map stored in memory, probably the usual 9 regions paging method. but in your case, you don't page, you generate. but since the algos define multiple tiles at once, you have to store the results in ram, and can't just generate one tile at a time if it happens to need drawing. well, you could, but it probably would be too slow.

the algos themselves are your typical splotch based stuff. as long as you keep it deterministic, you should be able to generate anything anybody else does.

0

##### Share on other sites

You can copy the initial permutation idea from the Perlin noise: basically, you have a permanent 256-sized array which points to a numbers from 0 to 255, call it "permutations". Then your "random" hash number at a specific integer point would be:

int X = (int)Math.floor(x) & 255;
int Y = (int)Math.floor(y) & 255;
int Z = (int)Math.floor(z) & 255;

int hash = permutations[X];
hash = permutations[hash + Y];
hash = permutations[hash + Z];


Also the trick is to expand the 256-sized array and clone the copy of the same numbers to the second half, so you don't need to check for array overflow when adding the coordinates.

You get more variations by interpolating between these values and blending more noises at different scales.

Perlin noise is here: http://mrl.nyu.edu/~perlin/noise/. 3D Perlin noise additionally interpolates between 12 points, plus 4 point simplex shape.

Although you would want to use improved Perlin noise, which uses 4 point simplex for 3D and 3 point triangle for 2D, which is aptly called Simplex Noise.

Edited by Nercury
0

##### Share on other sites

@Norman

Here is the reason I'm trying to avoid saving chunks of data.  When the server needs to know something, like if a building can go in a particular spot, it needs to check all the tiles that it will be on to make sure they are buildable.  As in not water for instance.  If I did chunks, then for each check, it has to build that entire chunk, Suppose a building is 2x2 tiles, and that is right on a division between four chunks.  Then it has to build up all 4 chunks of data just to check 4 tile ids.

So it is for the server's sake that I am trying to avoid this.

also, @JTippetts

Some of what that produced was awesome.  exactly the types of layouts I would like to see.  But it also looks like its building in large chunks, not so much pixel by pixel.  (as in a function/pattern will adjust many pixels at a time, so if you didn't preprocess that, how much work would it take to implement something like that per pixel for checking.

*Possible Idea...

(PreviousRandom = where the current code leaves off and was about to return)

X>>3&7&previousRandom = obtaining bits 0 1 2 3 4 5 (giving blocks of 8*8 the same base randomizers), as 0 through 7.  It increases the odds for the value to be 0, then 1,2 or 4, then 3,5,6 then 7 from highest to lowest order.

I can repeat the same pattern on the Y side.

Each value can link to something that will alter the odds of particular tile types, for instance, I could make

: 0 grass, just all grass.  No more mods.

: 1,2,4 Grass mostly, but with water as an alternative.

: 3 = grass at edges, another tile type massed through the center

: 5 = additional rock focus.

: 6 = additional forrest focus.

: 7 = Forest.

That would be the X effect, and Y could have its own modifying alterations.  Perhaps the top corner pieces, can even look up its 2 neighbors to modify its likely hood of a particular type.

I think this gives me some more tweaking room without particularly expanding on the processing level too much.

Edited by Dan Violet Sagmiller
0

##### Share on other sites
I've done this sort of thing before, and I always used Perlin noise as JTippetts suggested.

Note that some things are pretty difficult to do with purely math methods, such as erosion. There are some tricks you can do with a Perlin function, such as using the derivative of the function at the given point, to sort of fake erosion but it's just never going to look as good as an explicit pass across a buffer of data using Navier-Stokes or some other approximation. Of course, if you're doing a tile game, then good looking erosion probably isn't a necessity.

If you have to do any after-the-fact modification to the terrain, or if you want to add things like roads, then again you will probably need to be able to work with chunks of data. Pure mathematical procedural roads are a BEAST to implement, and only rarely to they look good, but you can make them look okay if done as a post-processing pass after chunk generation.
1

##### Share on other sites
Yeah, erosion and roads can be tricky. I do use erosion on the maps in Goblinson Crusoe to help with river and lake placement, but it's a lot easier in my case since I'm not streaming a continuous world. There are a couple of noise variants described here that use the derivative of preceding noise layers to affect latter noise layers (some of the "tricks" that FLeBlanc may have been talking about). The Swiss variant described at that link, especially, gives the appearance of an eroded terrain. It still doesn't really help with rivers, though. I still haven't found what I would consider a good technique for procedural rivers on procedural terrain that doesn't involve simulating a process over an entire chunk.
2

## Create an account

Register a new account