Jump to content

I want to build a really random map script


Recommended Posts

Hi guys.

I don't know if this comes here of in the modification forum, you may move this topic.

I've noticed that there are lots of new RMS lately, witch is great. But most, if not all of the scripts are actually a random variation on a predefined map structure.

My idea is to build a random map generator that will produce a random map, in a seance of a random terrain and randomly (even of not equally) distributed resources, trees, animals and even factions.

I was looking briefly at the random maps folder, and seen there a very useful little class called Noise2D witch is used widely in the scripts for distribution of heights, terrain, etc...

My idea was to use something called Plasma Fractal, or more particularly, an algorithm called "The Diamond-Square Algorithm", as described here: http://www.gameprogrammer.com/fractal.html#diamond.

This will produce a data that looks close to this:

heightmap.jpg

This plasma cloud can be very different in density, change and quantization (it can have "steps" of greys, instead of full range grey scale). This data can be translated to map data in these manners:

* For height - just use it as it is: black is low and white is high. can have a random water level, witch can make big or small lakes.

it can be quantized so instead of lots of hills and valleys, there would be ledges in witch buildings can be built.

It can be capped from top or bottom, making a flat land with mountains or flat land with valleys.

* For trees and terrain distribution a generated plasma can be "threshold" so only areas that have value above some level will get trees.

If there is an option for this, the interface can support inputting values for several options, like mountain heights density and so on

I want to know what you think about it. Is this idea even relevant? I would like to try and build this, but I need some guidance to start.

Thank you.

Link to post
Share on other sites

Just an FYI, the tool that was used prior to Atlas to make maps (SCNed) had the ability to import a black and white height map. It would be nice to have this functionality restored, enabling users not just to plug in RMS generated height maps, but also real world height maps (both at a continent level and at a battlefield level).

Bryce was a neat old tool used to generate some great height maps, having some cool features like erosion. May be worth a look.

http://en.wikipedia.org/wiki/Bryce_%28software%29 (looks like there might be a free limited version out there?)

Link to post
Share on other sites

I want to know what you think about it. Is this idea even relevant? I would like to try and build this, but I need some guidance to start.

Fractals are a pretty common way of generating random terrain in theory, I'm not sure it works so great for games though, at least games where terrain is critical to strategy. You don't just want a map that looks pretty, it has to be playable and challenging. So that introduces a lot of constraints on the notion of randomness, like paths have to be clear and reasonable, players should be on approximately equal areas of land in most cases, resources should be approximately balanced, every generated map should be valid and playable, etc. I agree our random maps aren't very "random", one of the reasons is that the current API is too low level, it's difficult to establish concepts like islands, rivers, lakes, forests, deserts, which IMO is what you want when creating a strategic map. Also there haven't been any good specs for random maps, but now we have this guide, which should help redesigning our existing ones.

That said, you can use any algorithm you want to generate terrain and place entities, as long as you know or learn JavaScript. As Erik pointed out the Trac wiki has almost everything you need to know about how the random map generator works including the data formats.

Link to post
Share on other sites

Thanks for the replies.

I understand your concern about maps would not be strategic, or even playable. That is kind of a risk, because they can be both, it's very random. Actually my first drive to make this kind of RMS was just because it was interesting, I wasn't thinking about strategic advantages. I understand that these kind of maps could be for only specific kind of play, or even players.

By the way, I wasn't aiming for "bryce style" landscapes. Although it could make some beautiful maps, this is not the goal. With post processing of the data like low flatten, high flatten and quantize (making steps) there would be alot of places that are just flat "playground".

This method could be implemented even for trees and animal distributions, or just using the Noise for this.

About Atlas: I think it would be an awesome tool if atlas could run an RMS script and generate the map. First, this would be a great way to debug and tweak maps, second, this could give map builders the opportunity to not build a map from scratch (something that made me just give up on map making lots of times).

Also if there was a way to make interface to change some parameters of the script in the map selection screen, this will benefit all maps and make them very costumizable (according to the script writer's wish, of course)

About the javascript...

Well it's been more then 5 years since the last time I wrote prototype style classes (Flash ActionScript 1) without automatic completion and compiler errors, but I tried to do something, without meaningful results.

Here is the code, it's the basic class but it doesn't generate anything useful right now, just a blank array:


function average(vaules:Array) {
var result = 0;
for (var i = 1; i < values.length; i++) {
result = result + values[i];
}
return result / values.length
}

/////////////////////////////////////////////////////////////////////
// The Diamond-Square Algorithm
// by iap
// according to the dscription in this site: http://www.gameprogrammer.com/fractal.html#diamond
// Class representing 2D plasma generated from a plasma fractal generator, using diamond mid point
//
/////////////////////////////////////////////////////////////////////

//params:
// iterations: how many iterations to the plasma. This eventually sets the size of the grid (int 1..maximum memry)
// smooth: how smooth will the plasma be. the higher the number, the less smoth it will be (float 0..1)
// quantize: post proccessing the plasma to make "steps" (int 0 - no quantize, 1..100)
// lowCut: post proccessing the plasma to flatten anything below this value (float 0..highCut)
// highCut: post proccessing the plasma to flatten anything above this value (float lowCut..1)
function Plasma(iterations, smooth, quantize, lowCut, highCut)
{
iterations = int(iterations);
this.iterations = iterations;
this.grads = new Array(iterations);
this.smooth=smooth
this.quantize=quantize
this.lowCut=lowCut
this.highCut=highCut

// creates the array
for (var i=0; i<this.grads.length; i++) {
this.grads[i] = new Array(iterations);
}

this.populateGrads(1, 0,0,this.grads.length-1,this.grads.length-1);

// ok I got stuck when trying to post proccess
//this.postProccess();
}

// return the average values of the four corners of the square + smooth
Plasma.prototype.getFullAverage = function(x, y, w, h) {
return avrage([this.grads[x][y],this.grads[x][y+h],this.grads[x+w][y],this.grads[x+w][y+h]]) + (randFloat()-0.5)*this.smooth;
}

// return the average values of the two cells of the square + smooth
Plasma.prototype.getAverage = function(x1, y1, x2, y2) {
trace("av: "+[x1, y1, x2, y2,this.grads[x1][y1],this.grads[x2][y2]]);
return avrage([this.grads[x1][y1],this.grads[x2][y2]]) ;//+ (randFloat()-0.5)*this.smooth;
}

//a recursive function that creates the plasma in the array in "diamond square" thechnic
// four corner values are selected randomly, the recursively avarages are claculated with a "variation"
//params:
// type (1 - for squares, 0 - for diamonds)
// x, y, w, h the coordinates and dimentions of the square
Plasma.prototype.populateGrads = function(type, x, y, w, h) {
trace("populate grads "+[type,x,y,w,h]);
var fw = int(w/2);
var fh = int(h/2);
if (type == 1) {
// square
this.grads[x][y] = randFloat();
this.grads[x][y+h] = randFloat();
this.grads[x+w][y] = randFloat();
this.grads[x+w][y+h] = randFloat();
this.grads[x+fw][y+fh] = randFloat();
} else {
// diamond
this.grads[x+fw][y] = this.getAverage(x,y,x+w,y);
this.grads[x+w][y+fh] = this.getAverage(x+w,y,x+w,y+h);
this.grads[x+fw][y+h] = this.getAverage(x,y+h,x+w,y+h);
this.grads[x][y+fh] = this.getAverage(x,y,x,y+h);
this.grads[x+fw][y+fh] = this.getFullAverage(x,y,w,h);
}
if (w == 1 && h == 1) {
return;
}

// because all the "squares" where defined by the centers avarege calculations,
// the olly place to use the "square" method is at first run
this.populateGrads(0,x,y,fw,fh);
this.populateGrads(0,x+fw,y,fw,fh);
this.populateGrads(0,x,y+fh,fw,fh);
this.populateGrads(0,x+fw,y+h,fw,fh);
trace("---");
}
// Utility function used in both noises as an ease curve

When trying to use it (draw the grid in flash) well.... it seems that all the average function just return NaN.

Unfortunately I don't have much time to work on it, but when I do - I give it a shot.

(And I apologize for my English...)

Link to post
Share on other sites

I understand your concern about maps would not be strategic, or even playable. That is kind of a risk, because they can be both, it's very random. Actually my first drive to make this kind of RMS was just because it was interesting, I wasn't thinking about strategic advantages. I understand that these kind of maps could be for only specific kind of play, or even players.

I think it could be quite good for casual play. Competitive players will never use something like this but vs an AI or some friends it could be fun.

About Atlas: I think it would be an awesome tool if atlas could run an RMS script and generate the map.

It can already. It is in the left hand pane when you start atlas.

For your code, you need to try running it and watch the debug messages. At a brief glance there seem to be a few typos e.g. avrage() which will be causing errors. If you insert it into a random map script then 0ad will run it for your and print nice error messages.

Link to post
Share on other sites

About Atlas: I think it would be an awesome tool if atlas could run an RMS script and generate the map. First, this would be a great way to debug and tweak maps, second, this could give map builders the opportunity to not build a map from scratch (something that made me just give up on map making lots of times).

As quantumstate pointed out, you can run RMS scripts in Atlas, I think you need to restart Atlas if you add a new map script, so it will be displayed in the list. We don't have a script debugger though, so you'll have to debug by hand, using warn() and uneval().

Also if there was a way to make interface to change some parameters of the script in the map selection screen, this will benefit all maps and make them very costumizable (according to the script writer's wish, of course)

There's actually a ticket for that: #812

Link to post
Share on other sites

I think you need to restart Atlas if you add a new map script, so it will be displayed in the list.

Weren't you the one working on this? :P

R button: Refreshes the list of random maps so new random maps shows up.
from: http://trac.wildfiregames.com/wiki/Atlas_Manual_Map_Tab :) Or did someone provide me with incorrect information? =)
Link to post
Share on other sites

Weren't you the one working on this? :P from: http://trac.wildfiregames.com/wiki/Atlas_Manual_Map_Tab :) Or did someone provide me with incorrect information? =)

Oh, that information is indeed a bit outdated. The R button just generates a random seed now, rather than refreshing the map list. I don't remember when it refreshed the list, but I do remember it used to do that.

Link to post
Share on other sites

Oh, that information is indeed a bit outdated. The R button just generates a random seed now, rather than refreshing the map list. I don't remember when it refreshed the list, but I do remember it used to do that.

Aha :P Good that you've updated the manual now :)

Link to post
Share on other sites

Does '0' pick a seed at random and doesn't tell you or what?

I would assume that's a seed of its own. Especially since '0' often seems to equal "one" in programming :P (Maybe that's more in lists and the like, but anyways =) ) But Ben would know for sure :)

Link to post
Share on other sites

Fixed the crash, but hotloading still fails for unknown reasons.

Iirc there's something on Windows that hinders hotloading the way it is implemented now, as far as I've been told it works on e.g. Linux though :-/

Link to post
Share on other sites

Iirc there's something on Windows that hinders hotloading the way it is implemented now, as far as I've been told it works on e.g. Linux though :-/

It doesn't seem to work on Linux. I tested by running pyrogenesis, opening atlas via the main menu, generating a random map, modifying the random map script and saving it, then generating the random map again. This produced a random map without my changes. Closing atlas and reopening using the same process results in the modified script being run.

Link to post
Share on other sites

It doesn't seem to work on Linux. I tested by running pyrogenesis, opening atlas via the main menu, generating a random map, modifying the random map script and saving it, then generating the random map again. This produced a random map without my changes. Closing atlas and reopening using the same process results in the modified script being run.

Ok, it might not work anymore/not work with random maps/perhaps I just don't remember correctly :P

Link to post
Share on other sites

A small question from quantumstate, how did you manage to change public.zip while atlas was still open? Because when I do this, the file gets corrupted and I have to recompress it.

And something off topic but important, did you know that the windows install doesn't compress the public.zip properly? I checked and saw that compression ratio was 100%!!! During my rms makings, sometimes I try to save my changes to public.zip while atlas is still open and it corrupts the file. When I compress the file again, compression ratio is about 60% and the whole zip file's size is about 350mb (compare it to current 600mb one!)

Link to post
Share on other sites

A small question from quantumstate, how did you manage to change public.zip while atlas was still open? Because when I do this, the file gets corrupted and I have to recompress it.

And something off topic but important, did you know that the windows install doesn't compress the public.zip properly? I checked and saw that compression ratio was 100%!!! During my rms makings, sometimes I try to save my changes to public.zip while atlas is still open and it corrupts the file. When I compress the file again, compression ratio is about 60% and the whole zip file's size is about 350mb (compare it to current 600mb one!)

I use svn so it isn't a zip file, it is just in a normal folder.

Link to post
Share on other sites

And something off topic but important, did you know that the windows install doesn't compress the public.zip properly? I checked and saw that compression ratio was 100%!!! During my rms makings, sometimes I try to save my changes to public.zip while atlas is still open and it corrupts the file. When I compress the file again, compression ratio is about 60% and the whole zip file's size is about 350mb (compare it to current 600mb one!)

This is intended, it will give a better compression ratio on the installer which uses a better compression scheme (lzma). Compressing an uncompressed file give better result than compressing an already compressed file with a weaker (zip) compressor.

Link to post
Share on other sites

A small question from quantumstate, how did you manage to change public.zip while atlas was still open? Because when I do this, the file gets corrupted and I have to recompress it.

I use svn so it isn't a zip file, it is just in a normal folder.

Spahbod, you can just unpack your public.zip file too (so you will have a 'public' folder inside the 'mods' directory) and change files inside it, and game will use files from the directory.

Link to post
Share on other sites

Spahbod, you can just unpack your public.zip file too (so you will have a 'public' folder inside the 'mods' directory) and change files inside it, and game will use files from the directory.

I've done this before. It doesn't work. Even when I deleted public.zip (and thus there was only the public folder in mods directory).

This is intended, it will give a better compression ratio on the installer which uses a better compression scheme (lzma). Compressing an uncompressed file give better result than compressing an already compressed file with a weaker (zip) compressor.

Hmm I see. Thanks.

Edited by Spahbod
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...