Random map scripts: how can I prevent bad resource spawns?

I am trying to convert a random map script from an alpha version of Age of Kings to work with DE. The original version of the script had very inconsistent resource distribution, and to update it for DE I have tried using the newer object generation code from GeneratingObjects.inc. However, I am still sometimes getting bad resource spawns – in particular, I have noticed that sometimes gold mines do not spawn for all players.

Does anyone know why this happens, or how I can avoid it? Given that there are so many variations of a random map, even if I do fix it, I don’t know how to be sure that I’ve fixed it for all map seeds, sizes and player numbers.

I have included the map script below so that any potential helpers can see the problem for themselves. (The forum won’t let me attach an .rms file so you’ll have to copy and paste the code into one.) An example of an affected map is seed 351553840, with two players, size set to small. Player 1 has two clumps of seven gold mines (as intended) but Player 2 only has one clump of gold. This also happens with tiny maps, e.g. seed -632246934.

/* ********* SWAMPLAND ********** */

#include random_map.def
ai_info_map_type SALT_MARSH

/* ****************************************************** */
<PLAYER_SETUP>
random_placement

/* ****************************************************** */
<LAND_GENERATION>
base_terrain SHALLOW

create_land
{
terrain_type WATER
land_percent 20
border_fuzziness 5
other_zone_avoidance_distance 3
zone 16
}

create_player_lands
{
terrain_type GRASS
land_percent 75
base_size 9
left_border 9
top_border 9
border_fuzziness 7

/* randomly choose if we have rivers and to what extent */
start_random
percent_chance 30
set_zone_by_team
percent_chance 40
set_zone_randomly
end_random
other_zone_avoidance_distance 4
}

/* ****************************************************** */
<TERRAIN_GENERATION>

create_terrain FOREST
{
base_terrain GRASS
spacing_to_other_terrain_types 3
land_percent 10
number_of_clumps 15
set_avoid_player_start_areas
set_scale_by_groups
}

create_terrain GRASS3
{
base_terrain GRASS
number_of_clumps 24
spacing_to_other_terrain_types 1
land_percent 2
set_scale_by_size
}

create_terrain WATER
{
base_terrain GRASS
if TINY_MAP
number_of_clumps 10
elseif SMALL_MAP
number_of_clumps 15
else
number_of_clumps 20
endif
spacing_to_other_terrain_types 1
land_percent 2
set_avoid_player_start_areas /* Not in original script! Avoid water spawning under TC */
set_scale_by_size
}

create_terrain SHALLOW
{
base_terrain GRASS
if TINY_MAP
number_of_clumps 10
elseif SMALL_MAP
number_of_clumps 15
else
number_of_clumps 20
endif
spacing_to_other_terrain_types 1
land_percent 3
set_avoid_player_start_areas /* Not in original script! Avoid shallows spawning under TC */
set_scale_by_size
}

/* ****************************************************** */
<OBJECTS_GENERATION>

#define GNR_NORMALTC
#define GNR_STARTVILLS
#define GNR_CLASSICSCOUT

#define GNR_GIVERELICS

#define GNR_RELICMODERN_MEDIUM

#define GNR_REGICIDECLASSIC

#const KERICEK 59
#define GNR_6KER
#define GNR_RESBYMAP_KER

#define GNR_STARTINGGOLD
#define GNR_STARTINGSTONE

#define GNR_STARTGOLD77M
#define GNR_STARTSTONE55M

#define GNR_ISLANDGS_DISTANCE

#const HERDABLE_A 594 /* Sheep are sheep */
#const HERDABLE_B 594

#const HUNTABLE 65
#const LURABLE_A 48
#const LURABLE_B 48

#define GNR_GIVEHERD_A
#define GNR_GIVEHERD_B

#define GNR_HERD4CLASSIC_A
#define GNR_HERD22CLASSIC_B

#define GNR_GIVEHUNT

#define GNR_HUNT3OR4CLASSIC

#define GNR_GIVELURES
#define GNR_CLASSICLURES

#define GNR_FARGORIG_GIVE
#define GNR_FARSORIG_GIVE

#define GNR_FARGORIG_TYPE7
#define GNR_FARSORIG_TYPE7

#const STRAGGLER 349 /* Straggler trees are oaks */
#define GNR_HOMESTRAGGLE

#const BIRDS_A 96 /* Hawk /
#const BIRDS_B 1056 /
Falcon */
#define GNR_NORMALBIRDS

#const FISH_A 456 /* Salmon /
#const FISH_B 458 /
Snapper /
#const MELKARYBA 69 /
Shore fish */

#define GNR_STANDARDFISH

#const PLACEHOLDER_TEMPORARY 55 /* Dead Fishing Ship, for illegal fish placement */

#include_drs GeneratingObjects.inc

create_object OAKTREE
{
number_of_objects 50
set_gaia_object_only
set_scaling_to_map_size
}
endif

/* create_object FISH
{
number_of_objects 10
set_scaling_to_map_size
terrain_to_place_on WATER
set_gaia_object_only
} Fish placement now uses the standardfish command */

/* Create fish on shallows. This was in the original script but was not actually possible in the alpha (without second_object or another workaround) – these fish did not spawn. */

create_object PLACEHOLDER_TEMPORARY
{
second_object FISH
number_of_objects 25 /* Up from 15 /
set_scaling_to_map_size
terrain_to_place_on SHALLOW
set_gaia_object_only
temp_min_distance_group_placement 6 /
Otherwise the fish can overlap */
actor_area 400
actor_area_radius 2
avoid_all_actor_areas
}

create_object PLACEHOLDER_TEMPORARY
{
second_object SHORE_FISH
number_of_objects 25 /* Up from 15 */
set_scaling_to_map_size
terrain_to_place_on SHALLOW
set_gaia_object_only
temp_min_distance_group_placement 6
actor_area 401
actor_area_radius 1
avoid_all_actor_areas
}

/* ****************************************************** */

<ELEVATION_GENERATION>

/* ****************************************************** /
<CONNECTION_GENERATION>
create_connect_all_players_land
{
/
replace_terrain GRASS DESERT /
replace_terrain WATER SHALLOW
replace_terrain DEEP_WATER SHALLOW
/
replace_terrain FOREST DESERT
replace_terrain PALM_DESERT DESERT */
terrain_cost WATER 7
terrain_cost FOREST 7
terrain_cost PALM_DESERT 7
terrain_cost SHALLOW 3
terrain_cost DESERT 1
terrain_cost GRASS 2
terrain_cost BEACH 7
terrain_size WATER 3 1
terrain_size DEEP_WATER 3 1
terrain_size GRASS 0 0
terrain_size FOREST 0 0
terrain_size PALM_DESERT 0 0
terrain_size DESERT 0 0
}

I would recommend not using GeneratingObjects.inc.

Ok… why not, though? If I don’t use GeneratingObjects.inc, I’m going to have to type my own code for generating objects, which means I’ll need to know what it was about GeneratingObject.inc that was causing things to go wrong.

He wants you to join the random map discord.
I see that you have not.

Forums are not the best place to ask for information in 2021

Because GeneratingObjects.inc is one size fits none. And by the looks of it you are defining/using pretty basic generations that at most cases might not work properly due to the uniqueness of the map. The GeneratingObjects.inc has many special cases in it too, but then you would have to first identify and understand them, the same goes to GeneratingObjects.inc overall. It is filled with branches that are useless to you and might provide errors.

What you can do is copy-paste some basic generations of objects to your script and then tinker them there. It gives you more accessibility and customisation, not to mention better tracking of issues, if there are any.

I’ve joined the Discord now but I can’t deal with how disorganised it is, with all rms questions being in a single thread. I don’t know how people cope.

Ok, thanks. I had assumed that things weren’t generating properly because there wasn’t enough space left on the map for them (e.g. because of trees getting in the way) but from what you’re saying that’s not true. I’ll have a go copying-pasting-tinkering as you suggest. And then, I guess, post on the Discord rather than here when I inevitably get stuck…