• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

A new map script (MountainCoast)

I'll just do a check that there arent any mountains or other non-hills too close (1/2 tiles?), and randomly lower some of the hills resulting, that should be fast enough (you can quit the loop the moment you hit a mountain instead of having to loop through everything etc....)

2 files because that way I can keep the terrain data generation separated from civ functions, and thus invoke the map script on console (having normal python installed) without having to start civ(which stubbornly refuses to reload the script without a restart)
(I used to throw code around two separate files, on of which was stripped of the civ stuff, but its too prone to leaving out some part/overwriting a good change. It also produces extra work)
 

Attachments

  • console_map_gen.png
    console_map_gen.png
    58.5 KB · Views: 178
How do you get that debugger view?

EDIT: I should clarify, is there any special modules or anything required?
or just executing on the command line via python ho its done?
 
A new version is out again, with a significantly better starting positions system. Distances between starting positions may occasionally be too close, but on average things are well :)
The usual little fixes are included as well, forest still hangs around (something is not working (for a change), and I'm just throwing this out again before catching sleep again)

@giddion:
You get it by executing selected bits of the script in a windows command line via the standard python interpreter (wont work with unix). I have a file with the following contents that I use.(living in the same directory as OALTerrain.py, but has a non ".py" file type so Civ wont load it)
Code:
import OALTerrain as TG

HM=TG.HeightMap()
mc=TG.globals()
HM.GenerateHeightMap(60,45 ,mc.NRANGES,mc.NPEAKS,mc.NLAKES)

print HM.GetBestStartingPositions(20)
HM.Print()
#HM.MoisturePrint()
#HM.AreaPrint()
HM.SPQPrint()


Feels funny to watch the file size increasing with each version :crazyeye: Should give some idea of why it was way of balance etc. when I first let it out into the wild
 
0.9.6. screenshot attached, this shouldn't happen I guess? :D

I've always been using default map options, small map, and 0.9.6 gives weird results. way too much water and huge lakes :\

0.9.5 worked fine though :D
 
That tends to happen if you have a LOT of civs and a small map. Since large share of the map is more less wasteland, the small grasland patches are the first to get overpopulated. (I thought I got this working better than that....)

The lakes should remain normal, but apparently that isn't the case...looking into it(Probably a side effect of the file split or one of the merges I talked about in my last post, but doing the split now should avoid similar regressions in the future)
The reason I don't really notice things like this is because I generate the map so often that any gradual change will be completely unnoticed
 
@lonkero
I still don't fully get it... Sorry

Can you give an example of what you run on the command line?
Are there any paths that need o be supported.

Thanks
 
Thanks for making a great map script! This is how the FFH2 maps should look like. Two notes:

1. When forest on mountains is enabled, it often generates Deer on mountains, which is ususable for obvious reasons.

2. Are you planning to make the starting locations according to terrain (Malakim on Desert, Lanun on the coast etc.)?
 
@PawelS
Are you using the truly random resources? (if so, this will be fixed asap)

@giddion:
default paths should do the trick, use the stuff I posted (put them in the file you call in a moment)
(use "cmd", not "command")

Code:
cd ../../Python26
C:\Python26>python "E:\Pelit\CivIV\Beyond the Sword\Mods\Fall from Heaven 2\PublicMaps\test_hm_gen.py_dont_run"

I once again realised how I hate some things about python...If you attempt to set a value to a global variable's value from within a function, the interpreter thinks you want a new local variable with that name (rather than assuming you mean the existing variable....) and thus gives you "somename referenced before assignment" crap...

Fixed version (lake scaling & deer should) is up.
Note The Rivers :cool::king::cool:

If no one hits any major issues with this, I'll consider it ready for the 1.0 designation. (Improvements still coming of course)
 
Yes, I use the "truly random resources", I think your placement method is better than the standard one :)
 
Thanks for fixing the deers, I noticed another thing:

Sometimes there is a straight borderline between coast and ocean, which looks artificial. See the attached minimap (large, wannabe archipelago, everything else standard).

minimap1.PNG
 
0.9.7 has kinda the same issues as 0.9.6. 2 screenshots attached, both with a small map, default number of civs ( 5 ) , all options set to default.


first start dumped all 5 civs in the same area :D ( amurites got the great bard random event on turn 1 and chose to create a great work, that's why their culture is so huge )


second start dumped 3 civs right next to each other and a really weird 99% straight coastline.

there is way too much sea ( this is medium sea level ) btw. since you can't use it to navigate anywhere right now, it just eats up space. I guess the starting spot selection code is being way too picky and that's why it's placing many civs in the same area? :D
 
@giddion:
You get it by executing selected bits of the script in a windows command line via the standard python interpreter (wont work with unix). I have a file with the following contents that I use.(living in the same directory as OALTerrain.py, but has a non ".py" file type so Civ wont load it)
Code:
import OALTerrain as TG

HM=TG.HeightMap()
mc=TG.globals()
HM.GenerateHeightMap(60,45 ,mc.NRANGES,mc.NPEAKS,mc.NLAKES)

print HM.GetBestStartingPositions(20)
HM.Print()
#HM.MoisturePrint()
#HM.AreaPrint()
HM.SPQPrint()

Instead of having this in a separate file with a mangled extension, you could use the python idiom "if __name__ == '__main__':".

__name__ is a special variable that is automatically assigned the name of the module when it is imported, or '__main__' if it is run directly.

Just put the following at the end of the OALTerrain.py file, and then run it with python.

Code:
if __name__ == '__main__':
    # Code that is run if the module is run directly.
    HM=HeightMap()
    mc=globals()
    HM.GenerateHeightMap(60,45 ,mc.NRANGES,mc.NPEAKS,mc.NLAKES)

    print HM.GetBestStartingPositions(20)
    HM.Print()
    #HM.MoisturePrint()
    #HM.AreaPrint()
    HM.SPQPrint()

A minor note: globals is actually a bad name since it shadows a builtin. Just thought you should be aware.

@PawelS
I once again realised how I hate some things about python...If you attempt to set a value to a global variable's value from within a function, the interpreter thinks you want a new local variable with that name (rather than assuming you mean the existing variable....) and thus gives you "somename referenced before assignment" crap...

In order to alter a global variable from within a local namespace you need to use the global keyword to tell the interpreter that you are talking about a global variable. I don't know of any languages that don't require you to be explicit about something like this.
 
@odalrick:
Good point, I'll do that. However that doesn't allow me to get rid of the two file split (need the Civ specific functions outside that file in order to execute it normally)
I actually noticed the "globals" thing about a day or two ago when playing with "dir()", but I didn't do anything about it since things seemed to work ok. (Guess I'm getting rid of it now, bad practice :blush:)
(I'm self taught in python and I've only known it for a couple of months so stuff like this is appreciated as well)

I don't know of any languages that don't require you to be explicit about something like this.
C(++) ? Most that require explicit variable declarations? (I really like the way c(++) handles scopes, even thought there are a couple of weird situations...(constructor that has parameter names equal to member variable names))(And as you might guess I prefer explicit variable declarations, less room for weird mistakes)

@Gekko:
You are really baffling me now... I've tested it quite a few times on small sizes and I haven't gotten anything that bad since the early 0.9.5 tests... It can actually handle 25+ civs on a normal sized map without any issues (that I have seen....) Guess I'll look into it again tomorrow...
I think I'll implement two different types of distance checking (fixed minimum and negative modifier to nearby positions "quality")
 
Actually if you want to have only one file, there is nothing that prevents you from placing the contents of the current MountainCoast.py in a similar if-statement that only executes if __name__ != '__main__' .

Whether it's a good idea or not is up to you.

C(++) ? Most that require explicit variable declarations?

Then you're explicit about what variables are local. Same difference.
 
i just downloaded the latest vesion and the first map I've just generated was perfect! I used a Huge map with all 19 civs, low sea level, some peaks, lots of lakes and moderate resources. Even with all the extra civs, every one was spread out and everyone had a decent starting position. I actually like that some people maybe surrounded by forest, forcing them a different starting strategy than usual. In this one I didn't have a single workable land tile, but had 3 clams just off the coast of my start, so I beelined Fishing, something I've never done before.

Anyway attached is the map after playing for a while.

My only one issue would be that while ther is always a lot of tundra (almost the top quarter of the map) in the maps I generate, I never really seem to get more than a few squares of desert. I'd like if these two terrain types were a bit more balances. I.e. less tundra but more desert.

But other than that, I am certainly usingthis mapscript from now on :)

Edit: on a second I attempt I did get alot more desert this time, so maybe I was just unlucky first time around :)
 

Attachments

  • map.jpg
    map.jpg
    9.5 KB · Views: 183
@odalrick:
Good point again... forgot that the interpreter only checks for sanity when running(too used to all checks being at compile time). But the files are allready big enough to warrant staying apart...(if you look at the .zip sizes, Its running at almost 2x the original size) Also since you seem to know a lot more about python: If I declare the functions Civ calls from within a conditional, will Civ still see them normally? Do I have to creaty dummys for those functions first?
And the variables: I meant that when referencing allready declared ones you are being implicit. ("this.foo" is explicit, "foo" is implicit at least when in a class scope/member function) Declarations are of course explicit. Since python likes to use the same syntax for both it has caused me some trouble.

@CladInShadows
Glad it's working properly for at least someone. The amount of deserts varies a lot. If you happen to get a mountain range right on the coast in the south and no rivers/lakes to the east of said range, you will get almost pure desert there. (You seemed to get a lot of big lakes, thats why its so moist)

@Gekko
Confirmed... I'll do something about it
 
I think I got the problem fixed now.. the reason was my lack of understanding of the function "getMAX_CIV_PLAYERS()". I thought it returned the number of players in the game. Turns out its the maximum civ can support (or something in that direction, rather a lot anyway). Thus the reason players spawned so close was that those were the best positions available when a LOT of civs were present (like I said ;) ). Now the system seems to work as it should.
I also tweaked the system a bit, I think it now produces by far the best distribution of starting positions, with starts somewhat closer together in the fertile areas, and most poor areas uninhabited. The "very sad" style starts should not occur too easily.
And last a little note: If the script fails to get starting positions far enough, it will revert to the civ default starting position system, which will at least maintain player separation...

Fixed version is up in first post again
 
If I declare the functions Civ calls from within a conditional, will Civ still see them normally? Do I have to creaty dummys for those functions first?

No there is no need to create dummy functions. Functions are only looked up when someone calls them, and since they are only called after civ has imported them there is no problem.


Ranting about global variables:
Spoiler :
And the variables: I meant that when referencing allready declared ones you are being implicit. ("this.foo" is explicit, "foo" is implicit at least when in a class scope/member function) Declarations are of course explicit. Since python likes to use the same syntax for both it has caused me some trouble.

The global keyword works pretty much the same. Somewhere before you use the variable, you state "global some_global_variable" and then whenever you use that name later in the function python knows that it's a global name.

In C you instead do something like "local some_local_variable" and then whenever you use a variable that is not explicitly declared local the compiler knows it's a global variable. ("local" is replaced by the type of the variable, int, char, float, whatever, since C needs to know that too.)

Actually, if all you're doing is reading the value, not assigning to it, you don't need to explicitly state that it's a global name.

"this.foo" and "foo" has to do with member variables and local variables. Python does not have any way to implicitly chose between member and local variables. "foo" is always a local variable, unless you explicitly said it's a global. "self.foo" is the only way to access member variables.
 
Back
Top Bottom