Random maps in AoE3 are created based on a map script which uses some functions that give instructions to the game engine on:
- how to generate the map terrain (land, water, cliffs, rivers)
- how to place objects on the terrain (resources, buildings, decoration)
To create random maps you need to know some basic programming. For example you need to know stuff like:
- what is a variable (and how you declare/define it)
- what is a function (and what does it return, which parameters can it use)
- data types
- each statement must end with a terminator (semicolon) in order to be executed
- flow control / algorithms
- comments
This is an example of a simple map script:
void main(void) {
rmSetMapSize(300, 300);
rmSetMapElevationParameters(cElevTurbulence, 0.02, 7, 0.5, 8.0);
rmSetMapType("greatPlains");
rmSetMapType("grass");
rmSetMapType("land");
rmSetBaseTerrainMix("default");
rmTerrainInitialize("great_plains\ground3_gp", 0);
rmSetLightingSet("default");
rmSetPlacementSection(0.25, 0.75);
rmSetTeamSpacingModifier(0.7);
rmPlacePlayersCircular(0.33, 0.33, 0);
int TC= rmCreateObjectDef("Player TC");
rmAddObjectDefItem(TC, "TownCenter", 1, 0.0);
rmSetObjectDefMinDistance(TC, 0.0);
rmSetObjectDefMaxDistance(TC, 5.0);
for(i=1; <cNumberPlayers) {
int id=rmCreateArea("p"+i);
rmSetPlayerArea(i, id);
rmSetAreaSize(id, 0.1, 0.1);
rmSetAreaLocPlayer(id, i);
rmPlaceObjectDefAtLoc(TC, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
}
}
AOE3 maps need a few minimal things to start:
- a main function in which all the other functions are executed (like in all C-types of languages)
- a defined size - here we used this function:
rmSetMapSize(300, 300);
which sets the size in (virtual AOE3) meters on width and length. If the width and legth of the map are the same the map will have the shape of a circle. If these are unequal the map will be a rectangle.
- the terrain must be initialised with a ground brush and a height, such as:
rmTerrainInitialize("great_plains\ground3_gp", 0);
The brushes paths can be found inside the art/Art.bar files with AOE3Ed Archive Viewer. The height I set here is 0.
- there must be some functions which set where players will spawn, such as:
rmSetPlacementSection(0.25, 0.75);
rmSetTeamSpacingModifier(0.7);
rmPlacePlayersCircular(0.33, 0.33, 0);
- each player needs a player area and a starting unit, or else the map fails to load:
So we define a Town Center object which every player will get and make it spawn in each player area, using a loop:
int TC= rmCreateObjectDef("Player TC");
rmAddObjectDefItem(TC, "TownCenter", 1, 0.0);
rmSetObjectDefMinDistance(TC, 0.0);
rmSetObjectDefMaxDistance(TC, 5.0);
for(i=1; <cNumberPlayers) {
int id=rmCreateArea("p"+i);
rmSetPlayerArea(i, id);
rmSetAreaSize(id, 0.1, 0.1);
rmSetAreaLocPlayer(id, i);
rmPlaceObjectDefAtLoc(TC, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
}
This is an empty map, though, so you will need to create more areas inside it, maybe add a trade route, some forests, some ponds or rivers and resources.
You can save this small map script in a text file with the extension .xs (for example SettlerMassacre.xs). The game needs an XML file too in order to read some metadata about the map (the name of the map, the loading screen, the description, etc). So create an .xml file with the same name (SettlerMassacre.xml) and place this code in it:
<?xml version = "1.0" encoding = "UTF-8"?>
<mapinfo detailsText = "Settler massacre" imagepath = "units\villagers\villager_portrait" displayName = "Settler massacre" cannotReplace = ""
loadDetailsText="The ultimate settler showdown." loadBackground="ui\home_city\intro_hc">
<loadss></loadss>
</mapinfo>
Now place these two files in /My Documents/My Games/Age of Empires 3/RM3/ , launch the game (I assume you're using the game with all expansion packs) and now you can find your map, when you select custom maps: Settler Massacre.[This message has been edited by Neuron (edited 02-12-2015 @ 07:48 AM).]