Arrakis.py map script discussion

If you locate the Arrakis.py mapscript in PublicMaps and edit it in notepad or another text editor, you will see this section:

Spoiler :
##############################################################################
## GLOBAL TUNING VARIABLES: Change these to customize the map results

#Percent of land vs. water
self.landPercent = 0.22

#How many map squares will be above peak threshold and thus 'peaks'.
self.PeakPercent = 0.06

#How many map squares will be above hill threshold and thus 'hills' unless
#they are also above peak threshold in which case they will be 'peaks'.
self.HillPercent = 0.0

self.SnowPercent = 0.15
self.GrassPercent = 0.40
self.PlainsPercent = 0.93

#In addition to the relative peak and hill generation, there is also a
#process that changes flats to hills or peaks based on altitude. This tends
#to randomize the high altitude areas somewhat and improve their appearance.
#These variables control the frequency of hills and peaks at the highest altitude.
self.HillChanceAtOne = 0.0
self.PeakChanceAtOne = 0.30

#This variable adjusts the amount of bonuses on the map. Values above 1.0 will add bonus
#bonuses. People often want lots of bonuses, and for those people, this variable is definately
#a bonus.
self.BonusBonus = 1.0

#Height and Width of main climate and height maps. This does not
#reflect the resulting map size. Both dimensions( + 1 if wrapping in
#that dimension = False) must be evenly divisble by self.hmMaxGrain
self.hmWidth = 193
self.hmHeight = 193

#Controls wrapping (not sure if this makes sense yet)
self.WrapX = False
self.WrapY = False

#Size of largest map increment to begin midpoint displacement. Must
#be a power of 2.
self.hmMaxGrain = 16

#Size of largest map increment to begin midpoint displacement for terrain field.
#Must be a power of 2.
self.hmMaxTFGrain = 8

#These are not mountain peaks, but points on the height map initialized
#to 1.0 before the midpoint displacement process begins. This sets the
#percentage of 'peaks' for points that are not on the grain margin.
self.hmInitialPeakPercent = 0.30

#Scales the heuristic for random midpoint displacement. A higher number
#will create more noise(bumpy), a smaller number will make less
#noise(smooth).
self.hmNoiseLevel = 1.0

#Filter size for altitude smoothing and distance finding. Must be
#odd number
self.distanceFilterSize = 11

#Altitudes are attenuated at this distance from pole
self.innerAttenuationRadius = 45.0
self.outerAttenuationRadius = 55.0

#Min and max distances of shield wall from pole
self.maxShieldWallRadius = 65.0
self.minShieldWallRadius = 45.0

#Radius of polar ice as a percent of map width.
self.polarIceRadiusPercent = 0.10

#scale of the dune texture. Must be 1.0 or less.
self.duneScale = 0.5

#Altitudes for hills and land on the dune texture
self.duneHillAlt = 0.75
self.duneLandAlt = 0.50

#Dunes at max height at this distance from continent
self.duneMaxHeightDistance = 7.0

#Minimum deep desert 'lake' size. anything smaller will be filled in.
self.minInlandSeaSize = 30

#---These values are for evaluating starting locations

#The following values are used for assigning starting locations. For now,
#they have the same ratio that is found in CvPlot::getFoundValue
self.CommerceValue = 20
self.ProductionValue = 40
self.FoodValue = 10

You can edit the values and save the file for the changes to take effect. If we find that certain values give interesting/fun results then we can turn those values into menu options for the mapscript.
 
I had a go at making a scenario map using by tracing the book map and using BMP to WBS Converter. It has no Mesa, Rugged, Salt or Bonuses yet so is not really playable in its current form. It is 110 x 82 tiles which is quite Large, but I was trying to keep the detail in the outlying rock outcrops.
 
Looks nice, a few thoughts:

Which map did you take that from?
I generally prefer the map from the prequel books, it has more terrain features.
http://upload.wikimedia.org/wikipedia/en/3/3d/Map_Arrakis.jpg

Your Sihaya ridge looks very short.

I think we can justify a 2-tile wide rock strip on the inner edge of the minor erg for gameplay purposes (its not worth building on a 1-tile wide spit).

The polar sink looks slightly too small but that could be my imagination, and I also prefer including the "worm line" as polar desert waste rather than normal desert waste.
And I'd make the polar sink polar terrain rather than graben.

I'd crop the left side of the map severely; too much empty space.

I think the map is too large for gameplay purposes too; we only have 9 factions, so I think they will be too far apart here.
Having a map that is still fun to play on is more important IMO than having exact replication of the tile features.

I would make the minor erg desert waste, not deep desert, and most of the "inner circle" between the poles and the main continents should also probably be desert waste rather than deep desert.
 
Having a map that is still fun to play on is more important IMO than having exact replication of the tile features.

I've had a bit more of a play tracing maps. I've attached images of a base image for the Dune novel map, the prequel map and your scenario map for comparison. I was going make the prequel map into a WBS, but then I thought that because yours is handmade it is probably the best basis for a fun game. It's cool that you've named the various features.

I'd suggest a few amendments though.

1) It would be good if the Pasty Mesa and the Gara Kulon spit of land were a bit more pronounced. The Gara Kulon spit will give more possible city sites with desert access so that's good for gameplay.

2) It would also be good if Habbanya Ridge and the Cave of Birds in the bottom left hand corner was rock/rugged so that it can have a city.

3) Starting positions - perhaps the Fremen should start at Sietch Tabr and Ecaz can take the place of the smugglers at Tuek's Sietch.

We can change the Python code so that bonuses and goody huts are randomly placed even though the map is fixed. That will add replayability.
 
1) It would be good if the Pasty Mesa and the Gara Kulon spit of land were a bit more pronounced. The Gara Kulon spit will give more possible city sites with desert access so that's good for gameplay.

Agreed, my version is pretty distorted. I will work on those (when I get back, I am currently in Canada for a few days).
2) It would also be good if Habbanya Ridge and the Cave of Birds in the bottom left hand corner was rock/rugged so that it can have a city.

Sure, easily done.

3) Starting positions - perhaps the Fremen should start at Sietch Tabr and Ecaz can take the place of the smugglers at Tuek's Sietch.

I thought it was more important for Fremen to be relatively more isolated and desert oriented, rather than have them start where Sietch Tabr is.
The False wall W that they are on is a big area and supports a lot of good cities, and only Fremen are there on the map.
Crowding too many civs onto the main areas is a problem; it will mean that the civs on the northern edge of the mainland will be at a big disadvantage, since they will find it more difficult to colonize the poles and the South.

I forget who I put down by the smuggler caves - I think I put the Ordos there? The Ordos are described as mercenary, so I felt that fit with the smugglers somewhat. And there isn't space for two civs down there I think.

But I'm relatively indifferent about all the start places. I wanted Atreides and Harks to have natural conflict (and giving them Arrakeen/Carthag seemed likely to encourage that). And I wanted to leave the pole and the Cielgo depression empty (both are very specialist). But otherwise I am flexible.

We can change the Python code so that bonuses and goody huts are randomly placed even though the map is fixed. That will add replayability.

That would be good (I have no idea how to do that), though I did try a little to place some things strategically; there are high concentration of water resources around areas on the map that have cities or villages or sietches. And there are consequently slightly higher bonus placement around the areas that are more densely populated with civs.

But random resource placement would be fine too.
 
Agreed, my version is pretty distorted

I can upload a WBS made from the traced prequel map if you want to use that as a basis.
 
Here you go - the size is 85 x 73 tiles which feels like quite a nice size for 9 civs. It pretty much just gives you the outline - you'll need to redo starting positions, add rugged/ mesa, etc. Make whatever changes you think will make it more fun to play.
 
Find attached the version 0.53 of the Arrakis.py mapscript. The main purpose of this version is to add a number of options to the script, allowing players to customize the map.

The options are:

Land Percentage: 16, 18, 20, 22 (Default), 24, 26
Grain: 8, 16 (Default) (8 is better if you want more islands)
Noise: 1.0 (Default), 1.25, 1.5, 1.75 (this controls how 'broken up' the map will be - 1.5 and above good for more islands)
Donut Fatness: Default, Fatter, Fattest (this affects how fat the donut shaped area in which land is more likely to appear will be)
Min Inland Sea Size 10, 20, 30 (Default) (any deep desert lakes smaller than this will be filled in)

The default values will give the same result as Cephalo's 0.52 version of Arrakis.py. My hope is for this version to go in the next patch.

Example 1
Land Perc 22, Grain 8, Noise 1.5, Donut = Fatter, Min Inland Sea Size 10
Spoiler :


Example 2
Land Perc 24, Grain 8, Noise 1.75, Donut = Fatest, Min Inland Sea Size 10
Spoiler :


To install the mapscript just overwrite the file Arrakis.py in the Dune Wars/Public Maps folder with the attached one.
 
These look great! Setting grain=8 and noise=1.5+ and Fatter+ looks like it would solve at least half our not-enough-spice issues.

These also look much more like the actual Arrakis from the books.

If I finish up the scenario map and post it, can you then get it to run the resource placement over the top? How does that work?

Is there any way to place a handful of resources (like extra groundwaters around the main basins/cities) and then run the resource script on top of that?
 
These look great! Setting grain=8 and noise=1.5+ and Fatter+ looks like it would solve at least half our not-enough-spice issues. These also look much more like the actual Arrakis from the books.

That's why I opened the parameters up. :)

The available values can be simplified and refined based on feedback. Hopeful we can 'home in' on a combination of settings that both plays well and captures the Arrakis of the books.

If I finish up the scenario map and post it, can you then get it to run the resource placement over the top? How does that work?

The only way I know to have random bonuses on Scenario maps is by adding this code into the CvEventManager.py Python file.

Code:
	def onGameStart(self, argsList):
# Place random stuff on map START
		if (gc.getGame().getGameTurnYear() == gc.getDefineINT("START_YEAR")):
				CyMapGenerator().eraseBonuses()
				CyMapGenerator().eraseGoodies()
				CyMapGenerator().addBonuses()
				CyMapGenerator().addGoodies()
# Place random stuff on map END

At the beginning of any game, this wipes all goody huts and bonuses from the map and replaces them according to the rules set in Civ4BonusInfos.xml, irrespective of whether the map is mapscript generated or a scenario map. Mixing pre-placed bonuses and automatic placement would be more complicated and is far less likely to work well in all circumstances.
 
In the python for onGameStart you can tell if it loaded a scenario, or even a specific scenario.

From CvFinalFrontierEvents.py:
Code:
		# Is this a scenario file?
		if ('.CivBeyondSwordWBSave' in CyMap().getMapScriptName()):
If you specify just that, it is for any scenario (or loading a WB save in general). If you specify the full file name it is just detecting that specific scenario.

So if you have a scenario you want to apply random resources to, you can do it just for that one.

You could also do this for some specific name to get it to generate resources, then do a WB save with a name other than the special one when you get a set of resources you like (reloading until you get one you like). This may not be the best way to generate resources and such, but it ought to work. You can always tweak them by hand too.
 
Thanks for the tip God-Emperor.

Just a note about Arrakis 0.53. One issues with changing the settings so there are more islands and irregular shaped landmasses is that there is a routine in the script which turns all Sink/Graben tiles adjacent to the coast into Rock. This means the percentage of Graben and Salt gets smaller the more islands you have. We can think about addressing this. It may be possible to control the % of Sink/Graben placed initially in order to compensate.
 
New map options for arrakis.py are nice. :goodjob: Deliverator, do you think there is a way to give polar terrain a fixed minimum size, showing up even on smaller map sizes?
 
do you think there is a way to give polar terrain a fixed minimum size, showing up even on smaller map sizes?

Yes, I'm sure this can be done. I think it's just a question of scaling the amount of polar dependent of map size. The radius of the polar region is a parameter in the script so it shouldn't be to hard. I would like to get some feedback on the new settings on Standard size and then we can think about tuning for other sizes.
 
Here is my current game map, which I think was:
"Land Perc 22, Grain 8, Noise 1.5, Donut = Fatter, Min Inland Sea Size 10"

It works pretty well. A good amount of spice within my borders (currently I have 37 spice, using spice economy civic)
 

Attachments

  • Arrakisnew.jpg
    Arrakisnew.jpg
    201.9 KB · Views: 80
One recent playtest feedback is that there is too much mesa(peak). I have had a look into the code but I am confused by the order of operations.

Line 2528: class SmallMaps
Line 2531: def initialize
Line 2559: calls self.createPlotMap()
Line 2620: def createPlotMap
Line 2674: comment "break up large clusters of hills and peaks"
Line 2688: a loop which finds a 3x3 block of peak and changes the middle one to land.

Great, I will modify this loop here to break up 2x2. But I can't figure out if this comes before or after building the shield wall:

Line 4578: def generatePlotTypes (at global scope, not in any class)
Line 4590: calls hm.makeShieldWall()
Line 2208: class HeightMap
Line 2398: def makeShieldWall()

I cannot tell where SmallMaps gets used or subclassed, and I cannot find any call of generatePlotTypes.

I just want to make sure new code I put at line 2688, is called after the shield wall is built.
 
Since Cephalo doesn't have much time at the moment, is possible to just try your change and see if it has the desired effect.
 
Please find attached experimental version 0.54 of the script. My changes around line 2676. It seems to prevent mesa clumps, but I did not examine very extensively for side effects.
 
One recent playtest feedback is that there is too much mesa(peak). I have had a look into the code but I am confused by the order of operations.

Line 2528: class SmallMaps
Line 2531: def initialize
Line 2559: calls self.createPlotMap()
Line 2620: def createPlotMap
Line 2674: comment "break up large clusters of hills and peaks"
Line 2688: a loop which finds a 3x3 block of peak and changes the middle one to land.

Great, I will modify this loop here to break up 2x2. But I can't figure out if this comes before or after building the shield wall:

Line 4578: def generatePlotTypes (at global scope, not in any class)
Line 4590: calls hm.makeShieldWall()
Line 2208: class HeightMap
Line 2398: def makeShieldWall()

I cannot tell where SmallMaps gets used or subclassed, and I cannot find any call of generatePlotTypes.

I just want to make sure new code I put at line 2688, is called after the shield wall is built.

There are several ways to reduce the peaks, some are preferable to others. There's two variables in the map constants that control that. One is a percent of the land squares, the other is a further chance for a peak depending on altitude. The default is a 30% chance to be a peak when the altitude is 1.0, with a linear reduction down to altitude 0.0. I would play with these first.

Checking the 3x3 block is only to prevent an unsightly clump of peaks. Doing the same with a 2x2 seems like overkill to me.

The SmallMaps class is for the shrunken version of all the climate and elevation maps. I learned it is better to generate a large map and then shrink it than to try to generate directly on to a small map. The final function calls use the data in the SmallMaps class.

the generatePlotTypes function just looks at the plotMap in SmallMaps and converts it to something that civ can use. (actually that's where I initialize alot of stuff as well).
 
Top Bottom