Jump to content


Photo

Procedural World Generation


  • This topic is locked This topic is locked
33 replies to this topic

#1 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 22 December 2009 - 03:23 AM

I'm currently making a Roguelike game, a large part of which is to do with random level generation. I started to look into some ways of generating random worlds, and I found some examples of procedural generation (created in Game Maker):
Posted Image
http://properundead....-generator.html
I looked at his results of map generation and wondered how to do that myself. Reading through the site's article, I decided to try his method. I began by (as the site's suggestion) randomly filling a 128x128 grid with single pixels at increments of 16, and looping through the grid, drawing the pixels as 16x16 blocks. It was nice, but not what I wanted. I made the blocks get progressively smaller until I reached 1 pixel blocks. Unfortunately, what I got was mostly random pixels everywhere. What I did next was find the blocks around it, and increase the chance of a block being the same as an adjacent one. The site also advises this, but gave no indication as to how to go about it. The code looks like this:
block_size = 1;
land_amount = 50;
g = ds_grid_create(room_width, room_height);
ds_grid_set_region(g, 0, 0, room_width, room_height, 0);

var i, ii, d;
d = 0;
for(i = 0; i < room_width; i += block_size) {
	for(ii = 0; ii < room_height; ii += block_size) {
		d = ds_grid_get(g, i - block_size, ii);
		d += ds_grid_get(g, i - block_size, ii - block_size);
		d += ds_grid_get(g, i, ii - block_size);
		d += ds_grid_get(g, i + block_size, ii - block_size);
		d += ds_grid_get(g, i + block_size, ii);
		d += ds_grid_get(g, i + block_size, ii + block_size);
		d += ds_grid_get(g, i, ii + block_size);
		d += ds_grid_get(g, i - block_size, ii + block_size);
		d *= 40;
		if(d == 0) d = -50;
		ds_grid_set(g, i, ii, (round(random(200 - d)) <= land_amount));
	}
}
land_amount is a variable I use for playing with the amount of land; I set it to 30 to begin with.
After a bit of playing with the values (including the amount to multiply "d" by), I ended up with a result like this:
Posted Image
I experimented a bit more, and found that by increasing the block_size variable, I could make the map have more islands.

You can download the GMK here: http://host-a.net/Pl..._generation.gmk

So what I thought would be interesting would be to discuss other ways of achieving a similar result, and expanding this idea into other styles of maps.
  • 1

#2 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 22 December 2009 - 03:16 PM

I think that it would be better to "form" the land, rather than try to arrange pixels into something that looks like land.

The first version of my growing concept:
fundamental bodies of land + peninsulas = dynamic bodies of land

islands = 5;
map_width = 100;
map_height = 100;

var this_island, this_peninsula;
for(this_island = 0; this_island < islands; this_island += 1)
{
island_X[this_island] = random(map_width);
island_Y[this_island] = random(map_height);
island_aspect[this_island] = 0.5+random(1);
peninsulas[this_island] = choose(1,2,3,4);
for(this_peninsula = 0; this_peninsula < peninsulas[this_island]; this_peninsula += 1)
{
peninsula_magnitude[this_island,this_peninsula] = 0.5 + random(0.5);
// The "position" is actually an angle between 0 and 360 degrees:
peninsula_position[this_island,this_peninsula] = random(360);
}
}
// Then after the general shape of the islands is decided, use a pixel generator to build an image of the islands.

I will try to add onto this code, test it, and completely finish it, but I don't want to right now. I could significantly improve it, but I will try it later.

~ SnowCream

Edited by SnowCream, 22 December 2009 - 03:19 PM.


#3 Tarik

Tarik

    GMC Member

  • GMC Member
  • 2731 posts
  • Version:GM:Studio

Posted 23 December 2009 - 08:52 PM

I gave it a shot. Generating a few maps worked out pretty nicely though it can still use lots of work.
Also I generated a map, and used a planet example xot kindly made me to texture a planet with a map (which I just generated, the 1024x512 map took about 60 seconds!)

Here's a link showing the large map, the planet, and 3 smaller maps that take about 5 seconds to render.
SCREENSHOT

One small problem that keeps occurring is that sometimes (rarely) the maps' distribution ratio of land to water is very lopsided, caused by what you could describe as an avalanche effect, though not in the usual programming sense. The method discussed in this topic bases its choice of land or water on the adjacent cells. Thus if there's land nearby, the cell has a likely chance of also becoming land, which will increase the chance of other cells also being land. Of course when the first distribution is even, there's a small chance that this happens. But when the first distribution is say 65/30, the 65 can quickly become even worse. It's possible to counter this by comparing the observed distribution to the expected distribution, and then use that result to influence the new distribution. (So if we set distribution to 50/50, and we find after the first loop that it's 40/60, then we will artificially increase the chances of the first being chosen in the second loop to get closer to 50/50 again.) Anyway it's not a big problem, just something to look out for.

It's not very interesting to generate land versus water alone though, as terrain and worlds are much more complex than that. The maps I generated are green/blue (with random color variations), so you can consider them as containing information on a completely flat world with either blue or green land, which is inadequately exciting for just about any game!

A next step I'll be looking into are heightmaps, so that it's not just water or land, but a hill or a mountain, and different colors at different heights (ice on very high land). That'd provide more interesting information to render a planet, or 3d terrain. Clouds follow a pretty similar concept, and it's quite possible to have these circular distortions applied to the cloud-surface to mimic storms, pretty cool!

Thanks for the interesting post, procedural content is a very interesting programming & game concept and GM provides a great basis for quickly prototyping basic algorithms.
It'd be interesting to expand terrain generation to something more complex, such as generating infrastructure (bridges, roads) and concentrations of life based on very simplified concepts.

Oh and don't forget you can save GM's random seed, allowing you to generate the exact same map multiple times, and compare algorithms applied to the same random distribution.

Edited by Tarik, 23 December 2009 - 08:53 PM.

  • 0

#4 Atarian

Atarian

    GMC Member

  • New Member
  • 28 posts

Posted 24 December 2009 - 01:49 PM

one thing you should think about is that id you can create (fairly) realistic land/water scenarios you could then use these in a height map generator, it would allow for more realism, on land for example you could create rolling hills where as underwater you could have a much sharper drop off and then some other sort of height map generator, it would also break the process down into a couple of simpler steps which would allow for easier adjustment.
  • 0

#5 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 24 December 2009 - 07:59 PM

It's obvious that you could use this for heightmaps. I would also mix it with a little bit of perlin noise if I were to use it for a heightmap. I guess that my original idea was stupid; perpixel procedural generation is the way to go!

~ SnowCream

Edited by SnowCream, 24 December 2009 - 08:07 PM.


#6 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 24 December 2009 - 11:30 PM

It might be a bit slower, but I feel letting it randomly generate would give the player a better feeling of immersion; it automatically generates quite a few islands, and the small islands just off the coast are very realistic.

I've never worked with heightmaps before; can you explain a little bit, please?
  • 0

#7 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 25 December 2009 - 01:37 AM

Height maps are used to generate height fields: 3-Dimensional terrain geometry. Like in Age of Mythology or Age of Empires III, they use procedural generation to build 3D maps with islands and an ocean. We're talking about implementing these specific pixel algorithms into 3D video games, to build random maps.

Checkout Jesper's example: Link to Topic

Edited by SnowCream, 25 December 2009 - 01:45 AM.


#8 Schreib

Schreib

    Valen Shadowbreath

  • GMC Member
  • 1457 posts
  • Version:Unknown

Posted 25 December 2009 - 11:37 AM

If not mentioned already, look up Midpoint displacement, which is a very effective technique.

The very best world generator (I'm afraid to say much more advanced than any of us Game Makers can ever dream to implement) I've seen so far is in the terrific game of Dwarf Fortress.

Interview on the shallowest world generation concepts of Dwarf Fortress: Gamasutra

A world generated in Dwarf Fortress:
Posted Image

Edited by Schreib, 25 December 2009 - 11:39 AM.

  • 0

#9 xot

xot

    GMC Dismember

  • GMC Elder
  • 4775 posts
  • Version:GM:Studio

Posted 25 December 2009 - 03:14 PM

Midpoint displacement is a powerful and easy to understand technique. It's a shame that Wikipedia doesn't show a very good example of it for the purposes of this topic. In fact Wikipedia seems to go out of its way to make it hard to understand. The main problem with it is that it creates crease-like artifacts along the 2n grid lines. I did find this which at least illustrates the process (although incorrectly; 2nd frame looks flipped horizontally):
http://en.wikipedia....actal_landscape
The older version of the image looks more correct:
Posted Image

This looks like a pretty good explanation of the algorithm:
http://www.gameprogr...om/fractal.html

This might provide some food for thought as well:
http://algorithmicbo...ntains.gi93.pdf

Personally, I'd go with a solid texturing technique, especially if you are attempting to work with a topology other than a flat plane. If you look at Tarik's image, you'll see that the map appears pinched near the poles. This needs to be compensated for which can be very difficult if your generator is based on a Cartesian/grid-like structure. It's a classic mapping problem and is why all flat maps of the globe have some amount of distortion. The mapping Tarik is using is similar to a Mercator projection, the most common projection seen for world maps. In those maps the areas near the poles are extremely distorted. An equirectangular projection is what Tarik is actually using. It is the most common spherical image projection used in CGI, probably because of its simplicity.
Posted Image
http://en.wikipedia....ular_projection

A solid texture can eliminate these distortion problems and Perlin noise is an ideal foundation for a spherical fractal terrain (or any other shape, including a plane). Instead of attempting to map an image to a shape using UV coordinates, a solid texture function is continuous in all dimensions and takes any point in space as an input. That's why they work for any kind of shape. Because the texture exists everywhere in space, if you created a solid texture to look like marble and textured a 3D model with it, the result would be 100% analogous to carving a real statue out of real marble. This link shows how such a texture can be constructed:
http://en.wikipedia....cedural_texture

Typical noise-based fractals have their own problems, namely they tend to be very homogeneous; everything looks the same at all scales and locations. That's the self-similar nature of fractals in general. It leads to unnatural looking valleys and shorelines. F. Kenton Musgrave attempts to address the problem by creating a variant called a multifractal that creates a more heterogeneous result. This is all covered in the book Texturing & Modeling: A Procedural Approach. Here's a preview of the book:
http://books.google....I...;q=&f=false

Thanks to the WayBack Machine, the source code is still available. I highly recommend checking it out, although it may be a little difficult to follow without the text.
http://web.archive.o...ndmodeling.com/

The same techniques are discussed briefly here:
http://www.gamasutra...procedural_.php
  • 0

#10 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 26 December 2009 - 12:50 AM

Very interesting; but suppose you want a specific amount of islands, with a ratio of land and water. Create a bank of the particles you will use. Start the islands by placing the designated amount of them as particles ( onto a coordinate plane ). Loop through each "particle" left in the bank and place it by another randomly selected particle which has already been place onto the plane. You'll have a some-what complex algorithm, but it shouldn't be too hard to program. Eventually the bank of particles will collect into the designated islands!

// Initialize
islands = 3;
land_percent = 0.8;
width = 100;
height = 100;
area = width * height;
land_particles = round(area * land_percent);
particle_num = 0;
bank_num = land_paritcles;

// Place nodes
for(i = 0; i < islands; i += 1)
{
particle_x[i] = round(random(width-2))+1;
particle_y[i] = round(random(height-2))+1;
// The 8 valid positions (4 sides + 4 corners)
particle_valid[i,0] = true;
particle_valid[i,1] = true;
particle_valid[i,2] = true;
particle_valid[i,3] = true;
particle_valid[i,4] = true;
particle_valid[i,5] = true;
particle_valid[i,6] = true;
particle_valid[i,7] = true;
particle_surrounded[i] = false; /* This is a piece for optimization which tells whether or not it is completely surrounded by other particles */
particle_num += 1;
bank_num -= 1;
}

// Build map
for(i = 0; i < bank_num; i += 1)
{
// TODO: place pixels into collections using two special repeat loops. I explain this more, after the code.
}

// TODO: draw map

Let me explain the primarily unfinished segment of code:

The REPEAT Loop
I will elaborate the idea of the repeat loops: choose a random place to start at, then circle through until a valid selection has been made. Because the random function is only used once, there's no chance of wasted processing; again, because you're not using it everytime the loop executes the statement (like if you used a while loop).

Why not use a FOR loop?
Because FOR loops cannot have dynamic progression! This unique loop design can begin at any place, and should be capable of circling past the threshold and wrap to 0. I call this design the "circle" loop.

Why do you need to use 2 circle loops?
You have to circle through the placed particles, and also 8 possibly valid positions around the selected particle (4 sides and 4 corners).

~ SnowCream

Edited by SnowCream, 26 December 2009 - 12:57 AM.


#11 xDanielx

xDanielx

    GMC Member

  • GMC Member
  • 1002 posts
  • Version:Unknown

Posted 27 December 2009 - 12:49 AM

This is always a fun topic. I wrote a terrain generator in Java (sorry, I can't stand GML these days), borrowing from some of these ideas. Here are some screenshots:

Posted Image Posted Image

The algorithm is similar to the one originally described:
  • We start with a map comprised of large blocks. The default block size is 64 by 64. The state of each block (land or water) is entirely pseudorandom.
  • Repeat until all blocks are 1 by 1 in size:
    • Divide each block into four smaller blocks.
    • For each derived block, decide on a probability for that block becoming a land block. This probability is based on the state of the block it was derived from, and the land mass of surrounding blocks. The probability computation can be configured in different ways with different weights.
    • If a pseudorandom number between 0 and 1 is less than that probability, the derived block becomes a land block. Otherwise, it becomes a water block.
  • Darken land blocks which are contiguous with water blocks.
Here is a runnable JAR to play around with. You can also view the source code, although it may be difficult to understand the algorithm from the code alone.

Edited by xDanielx, 27 December 2009 - 05:47 AM.

  • 0

#12 Juju

Juju

    GMC Member

  • GMC Member
  • 862 posts

Posted 27 December 2009 - 11:18 AM

I wrote this in 2006, written in GM6: http://64digits.com/...i...ame&id=1246
I do have other versions that have height mapping, wrap-around worlds and weather systems et cetera if anyone is interested.
  • 0

#13 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 31 December 2009 - 08:02 PM

I can't believe my eyes, the source code! This code generates an islands map for Age of Mythology. Apparently the way that they declare islands is as "blobs". Pretty simple concept . . .

Age of Mythology, Islands Map:
View Text File


I hope that this is helpful for those who are making an RTS game.

~ SnowCream

************
Moderator Note:


I removed several posts after this one, which commented how nice Juju's contribution was... but whose authors apparently hadn't downloaded his example:

"I might be interested in this." .... "I would like to take a look at this...."

Look, this is a discussion forum about technical issues. Not a chat room. If you don't have anything substantial to contribute -- or a meaningful question to ask -- then don't post.

Edited by KC LC, 01 January 2010 - 11:22 AM.


#14 wiiowner

wiiowner

    Absolute Zero Team

  • New Member
  • 685 posts

Posted 01 January 2010 - 10:02 PM

This site has some good theoretical ideas for generating maps that aren't for any language in particular but are more general processes that can be implemented into GM quite easily. In another section they also explain ways to place tiles on the grid.
Here's the link: http://www.squidi.ne...r/map/map03.php
The method is basically selecting a starting point and then selecting one of the neighboring cells and setting all of the ones around them to the "available" state. You can then either select one of the "available" cells randomly or pick the ones that have to most filled cells around them (or the other way around if you prefer a more scattered approach). It also has some good explanations for having themed zones (ie. forest, desert) and different ways of connecting the zones together.

Edited by wiiowner, 01 January 2010 - 10:07 PM.

  • 0

#15 Sinaz

Sinaz

    MCP Killer

  • GMC Elder
  • 2751 posts
  • Version:GM8

Posted 11 January 2010 - 07:59 PM

One thing I notice in those sorta noise generated terrains is that there are no smooth coastlines.

I'd like to know a bit about how LunarCell by Flaming Pear generates their terrain. I've been trying to find some relevant articles, but just cannot.
  • 0

#16 Yourself

Yourself

    The Ultimate Pronoun

  • GMC Elder
  • 7352 posts
  • Version:Unknown

Posted 11 January 2010 - 08:25 PM

One thing I notice in those sorta noise generated terrains is that there are no smooth coastlines.

I'd like to know a bit about how LunarCell by Flaming Pear generates their terrain. I've been trying to find some relevant articles, but just cannot.


One thing to look into are erosion algorithms. For the most part, pure noise doesn't make a very good heightmap. You have to do some kind of post-processing which is usually some kind of simulated erosion. Have a look at this paper for more on that:

http://oddlabs.com/d..._generation.pdf

They go over not only erosion algorithms, but also the methods for generating the noise.

I should mention that I couldn't really reproduce their results exactly. My implementation of their final algorithm (which is the same as the pseudocode given) produces a lot of artifacts. These artifacts are single pixels which have a height value considerably higher than their neighbors.

Edited by Yourself, 11 January 2010 - 08:30 PM.

  • 0

#17 xot

xot

    GMC Dismember

  • GMC Elder
  • 4775 posts
  • Version:GM:Studio

Posted 11 January 2010 - 09:41 PM

The nicest erosion modelling I've ever seen is in the program World Machine.

http://www.world-machine.com/

The output from that program is beautiful and it's node-based terrain design system is extremely powerful.

In the past, with height maps, I've used a simple median-style filter biased to selected the lowest sample. It works OK and is simple to understand. It might work better if applied at multiple scales and intensities as part of a midpoint displacement system.

The multifractal noise technique I mentioned earlier specifically tries to flatten out valleys which gets you smoother coastlines and what can pass for alluvial plains. A variant called a ridged multifractal attempts to accentuate mountain ridgelines as well. Just having those simple kinds of variation between low altitudes and high altitudes goes a long way towards improving realism.
  • 0

#18 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 12 January 2010 - 05:04 AM

Download TerrainGen.gmk

I used xot linked site for terrain generation (his other post, not this ^^ one)... Actually, terrain deformation as the terrain need initial data to start with... it's not 100%

Edited by icuurd12b42, 12 January 2010 - 05:08 AM.

  • 0

#19 Aethelwulffe

Aethelwulffe

    GMC Member

  • GMC Member
  • 118 posts

Posted 13 January 2010 - 02:24 PM

I just came up with my first generation isometric random terrain generator myself.
Mind you, I don't really quite know your objectives here. Rogue was a 1983 dungeon game, so for that purpose, I don't get the world gen thing. That being said, I am VERY interested in generating planetary maps, especially if they are of high enough quality to use as planetary textures later on....
For my game, I would also like a planetary map generator. I use isometric terrain in some parts of the game, and 2d in others. Planetary landing scenes, and atmospheric flight would be nice in small scale 2d, as would "maps".
I learned some important things in my 8 hours first gen room generator coding session:
1. Leave room in the code. Breaking it up into scripts will enable you to easily modify multiple levels of arguments.
2. If the maps or sub-maps are supposed to be repeatable, use a map grid system (cartesian whatever) to generate the random seed. That way, if the character is at grid x-4, y10, and you use the product of these two numbers to generate the random seed, then the randomly created map at that location will be the same every time the player visits it.

Edited by Aethelwulffe, 25 February 2010 - 09:19 PM.

  • 0

#20 xot

xot

    GMC Dismember

  • GMC Elder
  • 4775 posts
  • Version:GM:Studio

Posted 14 January 2010 - 09:30 PM

I learned some important things in my 8 hours first gen room generator coding session:

3. Find the Enter key because lines of code that are 464 characters long are extremely hard to follow and make your posts difficult to read.
  • 0

#21 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 15 January 2010 - 02:09 AM

That code hurts my eyes.
  • 0

#22 Schyler

Schyler

    Noskcirderf Derf

  • GMC Member
  • 2679 posts
  • Version:GM:Studio

Posted 16 January 2010 - 02:54 AM

That code hurts my eyes.

Agreed. I find irony in the first thing he said :P

Out of interest, how long does that Jar take to render? I can't test it myself, it dosn't seem to be working for me.

-Schyler-
  • 0

#23 xDanielx

xDanielx

    GMC Member

  • GMC Member
  • 1002 posts
  • Version:Unknown

Posted 16 January 2010 - 10:05 AM

Sorry to hear the JAR isn't working for you, can't think of why that might be. For a 512*512 terrain, the generation takes a few hundred milliseconds.

The one thing I don't like about it, and other generators that take a similar approach, is that I can't see a nice generalization into the third dimension.
  • 0

#24 xot

xot

    GMC Dismember

  • GMC Elder
  • 4775 posts
  • Version:GM:Studio

Posted 21 January 2010 - 06:00 AM

It can easily be extended to other dimensions, but the result wouldn't make a very good landscape. It'd be more like a hypertexture or isosurface.

Posted ImagePosted Image
http://mrl.nyu.edu/~...c/hypertexture/
  • 0

#25 nick1965

nick1965

    GMC Member

  • New Member
  • 88 posts

Posted 24 February 2010 - 01:36 AM

Ok well I got an idea, too busy to actually figure it out, but here's how it works.

First, you randomly place maybe 5 massive blocks, like 48 * 48 blocks.

Then use some kind of grid to randomly add single pixels ONLY around the edges of the 48*48 blocks.

This way you would get several equally sized, randomly placed, random coastline islands.

Hope I helped =)

~Nick
  • 0

#26 freko

freko

    The Professional

  • GMC Member
  • 504 posts
  • Version:GM8

Posted 08 March 2010 - 08:30 AM

Out of interest, how long does that Jar take to render? I can't test it myself, it dosn't seem to be working for me.


Pretty fast. Yes a few milliseconds and has good setup as well
  • 0

#27 vdweller

vdweller

    GMC Member

  • GMC Member
  • 184 posts

Posted 19 March 2010 - 09:11 PM

I managed to put together a planet surface creation script for a project involving random planet creation. Here are some screenies with the results (click on the thumbs for larger size):

Posted Image Posted Image Posted Image
Earth-like

http://s114.photobuc...ent=ss58937.jpg
Jungle

http://s114.photobuc...ent=ss58970.jpg
Barren

http://s114.photobuc...ent=ss58757.jpg
Oceanic

http://s114.photobuc...ent=ss58054.jpg
Icy

http://s114.photobuc...ent=ss58542.jpg
Volcanic

If you're interested in the script, let me know.

PS It is quite slow. It takes 4,5 seconds on my Dual Core 2.13MHz to create a 400x300 map. These screens are from a 180x180 map, 2x scaled (takes about 0.88 seconds).

Edited by vdweller, 19 March 2010 - 09:12 PM.

  • 0

#28 varuks

varuks

    GMC Member

  • New Member
  • 982 posts
  • Version:Unknown

Posted 20 March 2010 - 01:43 PM

Whell i am gona make an example that shows what is my idea of making random levels! It is probably not as mathematical as optimistic.

The thing is this: First the entire screen is fillen with cubes about (random(32)) pixels wide and long. Then you make some kind of amount of objects that have a random x and y.

then every point or object makes an instance that flies to some other point whilst destroying any block it touches(it can also have a curl)

While they fly they can make small semi objects that also fly in some direction and have a life time(this makes small tunels and dead ends)

when the instances touch some other point they get destroyed!

It neads some improvement but it wourks good for a spelunky type game!
  • 0

#29 Boreal

Boreal

    C++ Wackjob

  • GMC Member
  • 417 posts
  • Version:None

Posted 22 May 2010 - 12:13 PM

I'm making a roguelike for comp06, and I have been trying to find a good way to generate dungeons.
Just now I found this article, which gives a very interesting way to generate a realistic dungeon.

It basically works using a tree to store sub-dungeons, splitting sub-dungeons into further sub-dungeons, and then linking them up to their sisters and parents.
  • 0

#30 YellowAfterlife

YellowAfterlife

    GMC Member

  • Global Moderators
  • 4011 posts
  • Version:GM:Studio

Posted 22 May 2010 - 12:53 PM

I'm making a roguelike for comp06, and I have been trying to find a good way to generate dungeons.

Don't bother. Judges don't pay a sh*t to roguelike games and turn-based genre overall.
I've tried & failed.
You may download dungeon generator source from a link in my signature.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users