Generated Maps

Getting Started
The modding community embraces your desire to learn how to create generated maps for Age of Empires IV!

First step resources
Before getting started with generated maps, these resources are highly recommended as first steps:


 * Official Introduction to Generated Maps
 * Debug generated maps in your browser (source: https://github.com/Drumsin/aoe4-generated-map-debugger)
 * Join the Unofficial AoE4 Modding Discord for assistance

Studying Lua from official skirmish maps
Studying the Lua code from official skirmish maps is a great way to accelerate learning. The terrainlayout directory located within the archive Data.sga, contains useful library functions, and the Lua code used to generate these official skirmish maps.

How to extract the contents and access the Lua code:


 * 1) From the Age of Empires IV Content Editor. From the top menu, navigate to File » Open (Not "Open Mod")
 * 2) Navigate to your installed Age of Empires IV game directory and open file: Age of Empires IV\cardinal\archives\Data.sga
 * 3) Once Data.sga is opened, in the directory tree, extract the directory data:scar\terrainlayout to your local disk. You can do this by right clicking on the folder name, "terrainlayout", and selecting "Extract".
 * 4) Choose a location on your local disk to save the terrainlayout directory.
 * 5) You can open and view these extracted files in any text editor/IDE, or the official Age of Empires IV content editor.

Studying attributes/settings from official skirmish maps
Seeing existing settings from an official map can serve as a guide when configuring your map attributes in map_gen_layout. This could be settings such as: resource distribution, contested ranges, erosion, terrain smoothing, and more.


 * 1) From the Age of Empires IV Content Editor. From the top menu, navigate to File » Open (Not "Open Mod")
 * 2) Navigate to your installed Age of Empires IV game directory and open file: Age of Empires IV\cardinal\archives\Attrib.sga
 * 3) Once Attrib.sga is opened, in the directory tree, navigate to attrib:attrib\map_gen\map_gen_layout\skirmish_maps\
 * 4) From the skirmish_maps directory you can open a map ".rgd" file.
 * 5) Open a map rgd file and navigate the data tree to view specific settings.

Arguments

 * null

Returns
teamMappingTable (table)

Examples
From the library\map_template.lua

Arguments

 * null

Returns
mapSize (int)

Examples
From the library/map_template.lua

Arguments

 * metersPerSquare (int)

Returns
mapSize (int)

Examples
From the library/map_template.lua

Arguments

 * null

Returns
teamTable (table)

playersPerTeam (table)

Examples
From the library\map_template.lua

Placing Player Starts
Apart from the default functions described in the official documentation and generated map template, you can also place players completely manually.

To take teams into account, setup the team mapping table to know which player belongs to which team. The following is an example of placing team members on the same row next to each other, with one row per team. Critically, note how playerIndex works differently from playerID!

For example, with the following setup in the game lobby:

The code above results in this start:

If you do not care about teams when placing players, a simpler way is to use worldPlayerCount directly. In the following example, we place all players on the first row next to each other.

When placing players manually without using the default helper functions, the game does not automatically add starting resources at player locations, so it is generally recommended to place one of the tt_player_start terrain types at the same coordinates:

Community Functions
Helpful map gen functions made by the community to set you on your way!


 * Circle fill
 * Circle outline
 * Determine closest or furthest edge from a tile
 * Diagonal cross
 * Draw box
 * Draw number of tiles in a ring that are positioned randomly

Erosion
A response from one of the Relic developers on how the erosion system works.

Erosion and droplets are a connected system, and terrain smoothing is a bit of a separate pass.

You can imagine the erosion and droplet system like a rain cloud that covers the whole map - based on the droplets_per_cell attribute, you will get a droplet that falls on potentially every map cell and then travels down the terrain based on slope and angle. When a droplet is on a steep slope, it picks up velocity and carves more out of the terrain, and when it is on a shallow slope, it slows down corresponding to the friction attribute and eventually stops when it gets below the "end_droplets_below_velocity" threshold. The velocity_erosion_strength attribute controls how aggressively terrain is eaten away, and the max_erosion_depth controls how much of the base terrain can be eaten away by the erosion system. We do a number of these droplet paths, which you control with the max_droplet_iterations attribute. This is what can get you mountains that have nice looking shearing, as well as the rivulets that you can see going down hills on some of the maps. Whenever you see a patch note talking about "reducing erosion multipliers", it's typically been because I've seen instances of erosion digging the terrain too strongly and creating impasse on a hill when it's dug too much of the terrain up.

The terrain smoothing is a whole different thing - it's essentially a smoothing kernal pass that's done on the height map during the magnification process going from the coarse grid of terrain types that the Lua script passes in that results in the final height map you see in game. Playing with the height_over_width, for example, controls how much neighboring terrain types blend their heights together - it's why placing a few mountains together ends up with larger mountains. All of the fractal shift variables control how erratic the terrain can generate away from the set height values.

Global Distribution Balancing
Question & Answers with Relic developers on the prioritization on how the global distribution system works.

I've noticed instances with some global distributions where the balance of trees is heavier on one side of the map, and it looks as though the side with the least amount of trees is because of the stealth forest (from the global distribution) taking it's place.

"With global distributions, it isn't using any sort of player balancing, so it doesn't really have any concept of 'side of the map', it just will spawn things anywhere the score map says is available up to the spawn amount. If the stealth forest entry is above it in the list, the stealth woods will spawn first and take up the space, but they aren't ever trying to spawn on a certain side of the map."

Do global distributions take into account existing hand-placed resources?

"Yes, they do, as every resource respects a single global occupation map that tells the resource placement system whether a given cell has an object occupying that space already. It's always just a matter of order of operations to determine what will get placed in a given spot first, with local resources (Lua terrain type resources) -> balanced resources -> global distributions being the spawn order"