I'm glad you all voiced your opinions about resource distribution. Feedback is very important for a better mod.
Clarifications
- The minimum and maximum distances specified in a resource distribution create an area where no resource of the same type can spawn in. Valid types are strategic, luxury (minus marble), bonus, fish, city state, natural wonder, marble. There seems to be a sheep layer defined in the code comments, but it's not used at all. See also the Impact Table entry in the Terminologies below.
- Real life horses do exist in tundra and desert, just in low amounts.
- I have very little experience on "standard" maps like Continents and Pangaea. I don't recall the existence of seeing marsh near tundra, for example, or having so many flat grassland and plains plots (and few hills, mountains and lakes) on the map.
How resource distributions exactly work
Since there are confusions about how it works and what was changed in this version, I'll use my time to dig through the code and explain the whole thing (in detail) here. Luckily the script is well-documented (though a bit outdated on the details) so I don't have to dig VERY deep into it.
I'll go through everything I understand from reading AssignStartingPlots (and MapGenerator). I won't include luxury distribution which functions perfectly well and wasn't changed at all.
Terminologies:
- Plot types: Mountain, Hills, Land, Ocean. They define the shape of a plot.
- Terrain types: Grassland, Plains, Tundra, Desert, Snow, Coast, Ocean. MOUNTAIN and HILL are also defined, but they're not referred to in this. HILL is likely unused as it's not really a terrain in the game. Imagine them as textures on the plot graphics.
- Feature types: Forest, Jungle, Marsh, Flood Plains, Oasis, Ice, Atoll, and No Feature. All Natural Wonders and Fallout are features too, but you can disregard them for this. They're extra sprites added on plots and provide a modifier to the plot yields.
- Resource types: Each of the resources defined in the game, and a value for no resource. They're more extra sprites, but some combinations like Furs on hills don't look good and were forbidden.
- Every plot consists of one of each above type. No exceptions.
- Fertility: a value that measures the yields of plots. There are currently two different ways to calculate this.
- Area/Landmass: a body of connected non-ocean plots surrounded by ocean. "Continent" is an ambiguous term so it's not used here.
- Region: a rectangle of plots that maps to one major civ's starting location. Each area is divided into regions equal to the number of major civs spawning there. The division method is different depending on mapscript, but you can assume each region has roughly the same fertility.
- Strategic deposit: a plot with a strategic resource
- Major deposit: a strategic deposit with a higher amount, hardcoded in the script as uran_amt, horse_amt, oil_amt, iron_amt, coal_amt, alum_amt = 2, 4, 6, 4, 7, 7 for standard setting. I've added a 20% chance of spawning 20% more and 20% chance of spawning 20% less, for each deposit.
- Minor deposit: a strategic deposit with a lower amount, hardcoded in the script as uran_amt, horse_amt, oil_amt, iron_amt, coal_amt, alum_amt = 1, 2, 2, 2, 2, 2.
- Impact table: a multi-layered table of all map plots that serves as a banlist for resource placement. An impact placed on a plot on the strategic layer with radius 3 means no strategic resource can be placed anywhere within 3 tiles of the plot, if the impact table is checked before placement.
Resource placement in chronological order:
0. PlaceImpactAndRipples
This happens after all regions have been determined and during the determination of start locations.
For each start location determined, the following impacts are done:
- Strategic layer with radius 0 (no strategic spawn on start location)
- Luxury layer with radius 3 (all luxury spawns near start location are placed specifically later)
- Bonus layer with radius 3 (all bonus resources near start location are placed by NormalizeStartLocation)
- Fish layer with radius 3 (same as above)
- Natural Wonders layer with radius 4 (no NW may spawn near start location, though this is further restricted later)
At the same time, the function also tries to prevent 2 major civs from starting too close to each other by decreasing the viability score of plots in a 8-tile radius from the determined start location, with a higher penalty towards closer plots.
1. NormalizeStartLocation
Note that no resource has been placed yet as of now. This function ignores the impact table.
Comment from dev:
This function measures the value of land in two rings around a given start location, primarily for the purpose of determining how much support the site requires in the form of Bonus Resources. Numerous assumptions are built into this operation that would need to be adjusted for any modifications to terrain or resources types and yields, or to game rules about rivers and other map elements. Nothing is hardcoded in a way that puts it out of the reach of modders, but any mods including changes to map elements may have a significant workload involved with rebalancing the start finder and the resource distribution to fit them properly to a mod's custom needs. I have labored to document every function and method in detail to make it as easy as possible to modify this system. -- Bob Thomas - April 15, 2010
First, it measures each type of land plots in two rings around each start location, then calculate production scores and food scores for turn 0 plots (first ring only) and early turn worked plots (it's assumed you don't work featureless hills).
Then, it adds strategic balance resources near the starting position, if the setting is on. The original way was adding 1 minor deposit of iron, horses and oil within 3 plots of each starting position. Now it adds 1 minor deposit of iron and horses
4-6 plots from each starting position (prioritize closer, strictly following terrain/feature rules (no forested horses!)), so you have to settle for them.
If early hammers will be too short, attempt to add a minor Horses or Iron deposit to second ring. This is a bad practice IMO (balance-wise and you won't reveal Iron on time) and I think it should be changed to Stone instead.
Next, according to the food scores, a different number of food bonus resources (Bison, Deer, Wheat, Sheep, Fish, Cattle, Banana) and/or Oasis (at most one) will spawn in the first three rings. Legendary Start gives two more bonus resources. Resource spawned depends on plot/terrain/feature type.
Lastly, add up to 2 Stone to random flat featureless grassland plots in the first two rings (prioritize first) if grassland count is high and plains count is low. It adds stone even if the start location is 90% grassland hills, so this could use some change.
2. AttemptToPlaceNaturalWonder
This is the function to attempt to place a specific Natural Wonder on the map. If successfully placed, the Natural Wonder would generate the following impacts:
- Strategic layer with radius 1
- Luxury layer with radius 1
- Bonus layer with radius 1
- City State layer with radius 1 (with fertility checks, City States won't spawn near Natural Wonders anyway in this version)
- Marble layer with radius 1
- Natural Wonders layer with radius (map height/5)
This is why there's never any resource around a Natural Wonder (fish excluded) and they never spawn near each other.
3. PlaceCityStates
This is the function to place City States on the map. For each successful City State placement, the following impacts are generated for the plot:
- Strategic layer with radius 0 (no strategics on city tile to prevent blocking Mercantile luxury spawns)
- Luxury layer with radius 3 (CS has a specific set of luxuries exclusive to them)
- Bonus layer with radius 3 (placed by NormalizeCityState)
- Fish layer with radius 3 (same as above)
- Marble layer with radius 3 (they can't build wonders; don't waste Marble on them)
- City State layer with radius 4 (minimum distance between CS)
4. PlaceStrategicAndBonusResources
The main thing! This places the majority of strategic and bonus resources on the map outside the three rings of major and minor civ starts. Luxuries have already been placed before this.
Resource settings:
Scarce: only 2/3 of resource deposits are placed on the map via this function
Abundant: 3/2 of resource deposits are placed on the map via this function
Random: the multiplier is logarithmically randomized between 2/3 and 3/2
Strategic and bonus resources have different random values.
ProcessResourceList:
This places major deposits of a specific resource on a specific plot/terrain/feature type with a specific frequency, and then places a randomized radius of impact (between a defined min and max radius) for the resource category on the plot.
For example:
Resource to be placed = horses
Plot list = featureless flat plains (with 300 plots on the map)
Frequency = 34 -> Number of plots = ceil(300/34) = 9
Impact = 1-2
It'll place 9 major deposits of horses (20%: 3, 60%: 4, 20%: 5 in standard resource setting) randomly on the map's featureless flat plains plots, while banning any more strategics to be placed in the 1-2 plot radius from the selected plots.
(Note that I've simplified the definition of the impact table. In reality impact values are not absolute, and lower impact plots
can have resources placed if all plots in the plot list are impacted and there are still resources to be placed. That could happen if the impact radii are set too high, or the frequencies are set too low.)
4.1 AddModernMinorStrategicsToCityStates
For each city state, there's a 20% chance to place coal, 20% chance to place oil, and 20% chance to place aluminum. All are minor deposits and no impact is checked nor placed when placing these resources. These have also been changed to follow terrain rules.
4.2 PlaceSmallQuantitiesOfStrategics
Minor strategic deposits are scattered on the map, using the land plot list. The frequency is set to 160 times the number of major civs, that means for each player, every 160 land plots have a minor strategic deposit. (Wait, now that I think of it, this really shouldn't scale with number of players. Oops. Gotta change it to maybe 20 instead.)
If a land plot is selected to have a minor deposit, its plot/terrain/feature type is checked and a specific resource type is picked randomly for it.
Each resource placement also makes an impact with a radius of (0: 25%, 1: 50%, 2: 25%).
4.3 PlaceOilInTheSea
The final strategic placement is oil in the ocean. The planned amount of oil in the ocean is 50% of the oil on land, of which half is placed as 3-nodes and the other half is placed as 2-nodes, and the number of deposits for each are capped at 20% of all coast plots. The 3-nodes place an impact of 4-7 radius while the 2-nodes place an impact of 2-4 radius.
4.4 Fallback plan if there's not enough strategics
There's a final final addition of strategic resources if the map has too few per player. The script adds minor deposits until it reaches the minimum amount required. The amounts per player are 4 Iron/Horses/Coal/Oil, 5 Aluminum and 2 Uranium.
4.5 PlaceFish
This places fish on 10% of coast tiles, with an impact of radius (0: 1/7, 1: 1/7, 2: 1/7, 3: 3/7, 4: 1/7). Unlike the Communitu_79a version, this doesn't check surrounding fertility and distance to land. Which is fine I guess, since the standard maps don't really plan to make habitable tiny islands.
4.6 PlaceSexyBonusAtCivStarts
Comment from dev:
This function will place a Bonus resource in the third ring around a Civ's start. The added Bonus is meant to make the start look more sexy, so to speak. Third-ring resources will take a long time to bring online, but will assist the site in the late game. Alternatively, it may assist a different city if another city is settled close enough to the capital and takes control of this tile.
This adds one Deer/Banana/Wheat/Sheep/Cattle to the third ring of every start location, according to region type. It ignores the impact table. Hills region gets a second sheep. If none of the third ring tiles satisfy terrain restrictions, it attempts to add a fish instead.
4.7 AddExtraBonusesToHillsRegions
Comment from dev:
Hills regions are very low on food, yet not deemed by the fertility measurements to be so. Spreading some food bonus around in these regions will help bring them up closer to par.
This calculates an "infertility quotient" from comparing the amount of hill/mountain tiles to flat grassland/plains tiles, which scales from 1 (flat grassland/plains more than or equal to hills/mountains) to 2 (all hills/mountains). Then, it adds bonus resources to the region as below (All frequencies are further divided by the infertility quotient):
That's... a lot of sheep.
4.8 The remaining of bonus resources
5. NormalizeCityState
Similar to NormalizeStartLocation, but with different scoring and no addition of strategic resources or stone. I won't go into the details.
Extra: AdjustTiles
This fixes all the terrain issues with resources, mostly for luxuries.
- Marsh and oasis are removed from mining/quarry luxuries. Originally this removed floodplains too, but it's just weird that the plot suddenly isn't flooding just because some gold is there.
- Furs and ivory plots are flattened because they look bad with hills.
- Add trees for tree luxuries and deer, except sugar, cinnamon and dyes that are also fine on marsh. Forests are always added for deer and furs, and also for other resources that are above the latitude of jungle spawns.
- Remove trees and marsh on open land luxuries like perfume.
- Change grassland incense to plains.
Extra 2:
Ancient ruins are placed after all of these, and then "continent type" is determined for every tile (only affects graphics).