Random Map creation is not done within the game. This will be a guide for creating random map scripts. Largely, the work is done within Windows Notepad or a similar text editor tool.
Credit
Most of the content within this guide was originally posted on Hyena Studios - AOE3 RMS Tutorial (archive.org) and last edited by user M0nT y_PyTh0n. (Version 0.93)
Content
- How to create map files
- Variables
- Functions
- Conventions
- Script Order
- Map Grid
- Object Names
- A Simple Random Map
- How to test the map
- Now us have some fun!
- How to get help
How to create map files
Maps consist of two files: an .xs file and an .xml file. If the map is called MyRandomMap then the files will be MyRandomMap.xs & MyRandomMap.xml. To begin, both files can be created via Notepad.
- Open Windows Explorer with Win+E
- Locate this directory C:\Users\\Games\Age of Empires 3 DE\<0>\RandMaps
- Separately, open Notepad or another text editor
- Save the file as your desired map name and add “.xs” as the suffix
- Set the Save as Type field to All Files
- Ensure there are no other suffix or file types listed. In this example we will use MyRandomMap.xs.
- Repeat steps 3-6 for the .xml file
Note: the name of the map file must be unique. Re-using existing names from the game will not work.
Variables
Variables will define many aspects of the custom map, including strings, numbers and operators. Variables must be defined before they can be used within the code.
Here is an example of a variable definition:
Int myCounter = 1;
The colours are code for the following:
<variable type> <variable name> <is equal to> <predefined value> <execute this>
All variables should be named and using a certain format. The first letter of the variable should always be lower case. If the variable must be multiple words, they can be joined, but separated using capitalization on the start of each word (except for the first). For example “myCounter” or “myGameStart”.
Typical variable examples:
- Integer numbers (Numbers without decimals) - Example: int myCounter = 1;
- Float numbers (Numbers with decimals) - Example: float myFraction = 0.28;
- String (Strings contains letters, numbers and signs) - Example: string myUnitName = “My Hero”;
- Bool expressions (Expression that checks validity) - Example: bool myCheck = “false”; The bool expression can only be true or false.
Once a variable is defined in the script and given a value, the value is held unless it is later changed again.
myCounter = 2;
myFraction = 0.53;
myUnitName = “My New Hero”;
MyCheck = “false”;
Variables can also be added like this:
Float myNewFloat = myCounter + myFraction;
The above defines a new float variable, myNewFloat, and set the value to be the sum of myCounter & myFraction which is 2.53. Other operations could also be used here for variable numbers such as subtraction (-), multiplication (*) or division (/).
string myNewName = myUnitName+” “+myCounter;
In this example, a new string (myNewName) is defined and given the value of myUnitName+” “+myCounterFraction, which will be “My New Hero 2”.
The “ “ adds the space between the string and the myCounter value.
Note: When using “=” in the script, the variable on the left of “=” will receive the value from the right side of the “=”. After setting the value of a variable, it can then be used on the right side of an equation and it will use the previously set value.
AOE3:DE variables:
These variables are predefined by AOE3:DE when starting/launching the finished RM script. The most important ones are:
- cMapSize (integer) = 0, if map size is chosen normal; = 1, if map size is chosen large
- cNumberNonGaiaPlayers (integer) = amount of players when running/starting the RMS
- cNumberPlayers (integer) = amount of players + gaia player when running/starting the RMS = cNumberNonGaiaPlayers+1
- cNumberTeams (integer) = amount of teams when running/starting the RMS.
Note: Get these values first when setting up and starting a game with your RMS!
Summary
- Variables will be defined exactly in this order:
<variable type> <variable name> <is equal to> <predefined value> <execute this>
- There exist 4 types of variables: Integer, Float, String and Boolean (Bool).
-
- Once a variable is defined, you don't have to write the variable type again and can use it's value in the script.
- If our variables are numbers, we can use them like it in a math expression.
- String variables can be added and will add the string or number to it's end.
- AOE3:DE variables don't have to be defined nor have to be set to a value. You get these values at game start.
FUNCTIONS
A function in a program code (like the random map script) can also contain an equation. It can even contain a few equations and also commands. We can also write the Math function y=x+2 in RMS code. It would look like this:
int myRMSFunction (int x=0) { return(x+2); }
You see, we need a bit more to define, in order to tell the AOE3:DE program, which kind of variables we want to use. First, we gave our function a name (myRMSFunction) and defined it as an integer variable. In the brackets () we defined the input variable x. You see, we defined also x as integer with value 0, but we can change this value when we call this function later in our script. To call a function just means that we want to execute this function and want to get the result. Now, let's call this function:
myRMSFunction (3);
The "3" is inserted into the brackets, so this means that x now has the value "3" instead of the previous value "0". Since calling this function, everything within the brackets {} will be executed. Since x is now "3", we get a value for the variable myRMSFunction, which is "5" and surely of type integer, as we defined it before. The command "return" just executes the equation in the brackets of "return()". Now you can easily see, that myRMSFunction(3) is nothing but the y of our math equation, when using x=3. Even more, we are now be able to use this function like a regular integer variable! However, do not forget to insert a correct variable into the bracket, since x has to be an integer. Well, why don't we use float for x and myRMSFunction? Simple answer: Don't use it if not necessary, since calculating integers works much faster than calculating floats.
Now we are able to call this function in our RMS as often as we want and with different integer values.
In a random map script there are two different kinds of functions, predefined functions and custom functions:
Predefined Function
These functions are already defined by the AOE3:DE program. Most of them start with the letters "rm...".
Example: "rmEchoInfo("Large map");".
These functions are all explained below. Some of these functions just execute something (they are called void functions), others can return a value or variable (they are called int, float or string functions), and some other functions can compare values or variables (like if, else, while, case, etc. They are called operator functions). There are also some math functions which work in RMS (like sqrt(x) for the square root of x).
Custom Functions
The most important custom function is called "void main(void) {}" and ALWAYS has to be included once in your RMS! The "void" before "main" means, that this function doesn't return any value, it just executes something. The "void" in the brackets () means, that the function "main" doesn't need any additional variables, so it just executes all commands and definitions, which are added in the {} brackets.
Typically, there is no need for further custom functions in a random map script. However, they get pretty useful, if we want to repeat commands over and over again. If you want to use further custom functions, there are two rules to follow:
- All additional custom functions BEFORE defining the function main.
- Custom functions can be called in a definition of a new custom function, but the function being called has to be defined BEFORE the call.
Using Operator Functions
As we already have seen, operator functions are predefined functions. They are needed to compare values or variables, using operators. The most common operators are:
- i == j , means "i" has the same value as "j"
- i < j , means "i" has a lower value than "j"
- i > j , means "i" has a higher value than "j"
- i <= j , means "i" has a lower or the same value as "j"
- i >= j , means "i" has a higher or then same value as "j"
- i != j , means "i" has NOT the same value as "j"
- i || j , means "i" OR "j", this is a boolean operator, "i" OR "j" has to be TRUE to proceed
- i && j , means "i" AND "j", this is a boolean operator, "i" AND "j" has to be TRUE to proceed
- i % j , means "i" modulo "j". In simple words: "i" AND "j" have to be integers. Divide "i" by "j" as much as you can. If you can divide i (k*j) times, (k is also an integer), then subtract this amount and look at the rest (i%j = i - k*j). If i<j, then k is 0.
Example: 1%4=1, 2%4=2, 3%4=3, 4%4=0, 5%4=1, 6%4=2, 7%4=3, 8%4=, 9%4=1, 10%4=2, ...
Now let's have a look at the operator functions. We insert the following into the main function:
int i = 0;
int j = 0;
for (i=1; <= 10) {
if (i<4) j=1;
else if (i<6) j=2;
else j=3;
}
The first two lines just define the 2 integers i and j. Next line start a for-loop, beginning from i=1 til i=10, so it runs 10 times, since the for-loop increases the variable i by 1 after each loop. If there is more than 1 command in your function (here the for function) you need the brackets {}. We have 3 commands in this bracket. The first command "if (i<4) j=1;" can be read as "If i is smaller than 4, then set j equal to 1". The next command else if starts working (and only then!), when the if command above is not fulfilled anymore. For this case j will be set to 2. The last command in this loop, else, is always necessary when you used an else if command before! If the last else if command is not fulfilled, then set j=3. Surely, we could have added more else if commands between if and else!
So, the result of "j" for each "i" in the for-loop is:
i = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
j = 1, 1, 1, 2, 2, 3, 3, 3, 3, 3
CONVENTIONS
Some conventions to keep in mind:
- The script is case-sensitive. Example: int, Int and inT are 3 different things!
- All variables (such as integers and floats) must be defined the first time they are used. If they are redefined after that, you must leave out the “int” of “float”.
Original: int numCows = 0;
Subsequent: numCows = 2;
- Variables must not be named or defined by reserved names or commands, like "int", "float", "string", as well as all further "rm***" commands. Example: Avoid "int int = 4;" or "string float = "A Name";".
- Semicolon: The Semicolon ; always finishes a command line. This is where AOE3:DE will know, that the definition or command before the semicolon shold be executed next. Always use a semicolon after EVERY definition or command.- There are many shortcuts for making scripts, and some are shown at the end of this file. Conditional statements can make use of “if”, “else” and “if else”. Do loops can run through a list of commands multiple times, and is particularly useful for duplicating areas or objects for each player.
- Comments can be specified by inserting // at the beginning of a line or enclosing text in /* and */. Comments can remind you (and anyone else reading your map) what each section is trying to do, and commenting out sections of a map script can help in debugging problems.
SCRIPT ORDER
Order of the scripts is important. You must build land before you can place objects on it. Objects will only respect the constraints of areas and objects that are already placed. You can’t use a variable that you haven’t defined.
MAP GRID
Maps are oriented along an X, Z grid. Y is elevation. The origin of the grid, (0,0), is located at the bottom of the screen. When using fractions, (0.5, 0.5) is the middle of the map, (1, 0) is the right corner of the map at 3 o’clock, (0, 1) is the left corner of the map at 9 o’clock, and (1, 1) is the top of the map at 12 o’clock.
The grid uses 2x2meters square tiles. You can see these tiles also in your scenario editor. Select "View" in the editor and chose "Grid". Each small and white rectangle is 1 tile. Each large and blue rectangle is 5x5 tiles (=10x10 meters).
A 4-player map is probably about 400 m along one side. Small buildings occupy 1 tile (=2x2 meters) and small units (like small rocks or a bundle of grass) occupy a quarter tile (=1x1 meters) of space.
OBJECT NAMES
Unit Names
All object names refer to a protounit name. What’s the difference between a unit and a protounit? Unit names in the game are a friendlier version of the protounit name. For example, the protounit name for “Villager” is “Settler”. The protounit name for “Town Center” is “TownCenter”. So, most of the unit names have a similar or the same protounit name. You will find all protounit names in your AOE3:DE installation directory:
"\Age of Empires III\data\proto.xml".
Technology Names
Technologies are for example "attack", "shield", "armor", "hitpoints", etc. . All technology names refer to a techtree name. You will find all techtree names in your AOE3:DE installation directory:
"\Age of Empires III\data\techtree.xml".
Both files are very long xml (text) files. I recommend to use an "XML Viewer" program to find the protounit you need. A very good freeware program is the "Mindfusion XML Viewer". You can download it here.
Mindfusion XML Viewer
(the XML Viewer shows you a searchable treetable of the proto.xml content)
Note: Do NOT edit this file. It will cause problems in game.
Trigger Names
Triggers are not needed for a regular random map, but we short want to explain it here for completeness. You can include all trigger effects and conditions from the scenario editor into a random map script. For the triggers we need the trigger effect and condition names, its parameter names (if any) and the corresponding custom variables. You will find all trigger related names in your AOE3:DE installation directory:
"\Age of Empires III\trigger\typetest.xml".
Now, we open this file in the XML Viewer (see above) and get something like this:
(how to find the trigger effect and condition names for our xs script file)
In the RM script it will be inserted, similar to this:
rmCreateTrigger("FoodForAllPlayers");
rmSwitchToTrigger(rmTriggerID("FoodForAllPlayers"));
for(i=1; <= cNumberNonGaiaPlayers){
rmAddTriggerEffect("Grant Resources");
rmSetTriggerEffectParamInt("PlayerID",i);
rmSetTriggerEffectParam("ResName","Food");
rmSetTriggerEffectParamInt("Amount",1000);
}
rmSetTriggerPriority(4);
rmSetTriggerActive(true);
rmSetTriggerRunImmediately(true);
rmSetTriggerLoop(false);
The explanation for the commands is in Scenario Editor: Triggers.
Terrain Names
This is a bit different than for units and technologies. Terrains refer to a painted texture. These texture files can be found in a compressed archive of graphic files. The files are bar-compressed (similar to zip) and have the file extension "bar". You will find all texture files for terrains and other pictures and icons in your AOE3:DE installation directory:
"\Age of Empires III\art\art1.bar".
"\Age of Empires III\art\art2.bar".
"\Age of Empires III\art\art3.bar"
To view these files we need a "Bar Explorer" program.
However, we just need the names. Well, let us pick the terrain from the Scenario Editor. We chose "ground2_tex". In the AOE3:DE Archive Viewer we find the path "Art\terrain\texas\ground2_tex.ddt", We only need the name shown as blue bold. In a RMS line it will be inserted, similar to this:
rmTerrainInitialize("texas\ground2_tex",4);
Other Object Names
Names for water, cliffs, forests, etc. are mainly the same as shown in the scenario editor. Explore the original AOE3:DE scripts if you need a special name for an object you have seen in these maps. The "ALT+F" hotkey is your friend finding it!
Note: There might already be some lists for names around on the next. But remember: Each game patch can change the names, and even more the attributes and parameters. So with the methods above you are always on the secure side finding the correct names.
XML FILES
Map scripts use the file extension .xs but they are text files and can be edited with any text editor. However, in order to play on a new map, you must also create an xml file with the same name as your .xs file. .xml is a markup language similar to HTML used by Web pages. Most Web browsers can view xml files, but you may need to open the file in another application, such as an xml editor or even a text editor. Required in the map xml file are shown below in blue bold: the map’s name and description, plus an optional preview image.
xml files for random maps look like this:
<?xml version = "1.0" encoding = "UTF-8"?>
<mapinfo detailsText = "My Map Description." imagepath = "ui\random_map\all_maps" displayName = "My Map" cannotReplace = ""
loadDetails="" loadBackground="ui\random_map\all_maps">
<loadss>ui\random_map\new_england\new_england_ss_01</loadss>
<loadss>ui\random_map\new_england\new_england_ss_02</loadss>
<loadss>ui\random_map\new_england\new_england_ss_03</loadss>
</mapinfo>
A SIMPLE RANDOM MAP
Each custom random map consists of two files. If your map is called "MyMap", then you have to create two files, called "MyMap.xs" and "MyMap.xml".
Example:
NOTE: The text in grey is not necessary, its only for your help. Since it is marked as unreadable for the RMS builder, you can include it into your real file!
MyMap.xs contains:
/* A SIMPLE RANDOM MAP - by Author - Version 1.0 */
include "mercenaries.xs"; /* This loads the mercenaries needed for regular gameplay RMS! */
void main(void) { /* This is the main entry point for your RMS! */
rmSetStatusText("",0.01); /* This is the value for the map generation progress bar when starting the game */
/* (value 0.00 - 1.00) */
int myTiles = 8000; /* This is a typical variable for the map size */
if(cMapSize == 1) { /* This if function checks if map was selected normal or large. cMapSize (1=large, 0=normal) */
myTiles = 12000; /* This is a typical variable for the map size, when map chosen large! */
rmEchoInfo("Large map"); /* This is an output information only for the RMS debugger! */
}
int mySize = 2.0*sqrt(cNumberNonGaiaPlayers * myTiles);
/* Above the size of the map will be redefined. */
/* Since the map size is now proportional to the square root of the player number, */
/* the map area will be proportional to the player number! */
rmEchoInfo("Map size="+mySize+"m x "+mySize+"m"); /* Another output information only for the RMS debugger! */
rmSetMapSize(mySize,mySize); /* This command will build the map size */
rmSetSeaLevel(0); /* This command will set the sea level in meters height */
rmSetSeaType("Amazon River"); /* This command will set the sea texture, if there is water */
rmTerrainInitialize("texas\ground2_tex",4); /* This command will set the map as water or land map */
/* If you want water, replace "texas\ground2_tex",4 with "water",0 and the defined SetSeaType texture will be used! */
rmSetStatusText("",0.20); /* This is the next value for the map generation progress bar, the bar increases */
/* Areas can be added here: */
rmSetStatusText("",0.40); /* This is the next value for the map generation progress bar, the bar increases */
/* Players are added here: */
/* The following command will align the place for the player areas randomly in a circle: */
rmPlacePlayersCircular(0.3, 0.3, rmDegreesToRadians(0.0));
/* Now we start a loop for every player: */
for(i = 1; <= cNumberNonGaiaPlayers) {
/* We define an area for every player: */
int id = rmCreateArea("Player"+i);
/* We define the height of each player area: */
rmSetAreaBaseHeight(id,4.0);
/* We define the coherence of each player area (1.0 = smooth circe, 0.0 = roughest circle): */
rmSetAreaCoherence(id,1.0);
/* We define the height blend of each player area: */
rmSetAreaHeightBlend(id,2);
/* We define the center of the player area: */
rmSetAreaLocPlayer(id,i);
/* We define the size of the player area: */
rmSetAreaSize(id,0.001,0.001);
/* We define the area of the player area: */
rmSetPlayerArea(i,id);
/* We define the terrain of the player area: */
rmSetAreaTerrainType(id,"texas\ground3_tex");
/* We have defined all neccessary variables for the player area, now we can build it: */
rmBuildArea(id);
/* We 1. define a new object, 2. we add a starting TownCenter to it, 3. we place/build it onto the map: */
int towncenterID = rmCreateObjectDef("Starting Towncenter"+i);
rmAddObjectDefItem(towncenterID,"TownCenter",1,0.0);
rmPlaceObjectDefAtLoc(towncenterID,i,rmPlayerLocXFraction(i),rmPlayerLocZFraction(i),1);
}
rmSetStatusText("",0.60); /* This is the next value for the map generation progress bar, the bar increases */
/* Objects can be added here */
rmSetStatusText("",0.80); /* This is the next value for the map generation progress bar, the bar increases */
/* Triggers can be added here */
rmSetStatusText("",1.00); /* This is the next value for the map generation progress bar, the bar is full! */
}
/* This is the end of our xs-file! */
MyMap.xml contains:
<?xml version = "1.0" encoding = "UTF-8"?>
<mapinfo detailsText = "My Map Description." imagepath = "ui\random_map\all_maps" displayName = "My Map" cannotReplace = ""
loadDetails="" loadBackground="ui\random_map\all_maps">
<loadss>ui\random_map\new_england\new_england_ss_01</loadss>
<loadss>ui\random_map\new_england\new_england_ss_02</loadss>
<loadss>ui\random_map\new_england\new_england_ss_03</loadss>
</mapinfo>
Explanations for the XML commands you can find above.
The result of this map is a map with flat terrain and terrain texture "texas\ground2_tex". An object for each player is added: A starting towncenter object. The town centers are placed symmetrical in a circle. The content in the xml file between and should not be changed, unless you know the image paths (see Terrains).
Now you can copy and paste the text above into your files and try it out!
HOW TO TEST THE MAP
For TESTING the map script:
For testing the map script you should enable the debugger. The debugger is an AOE3:DE build-in program which allows you to find errors in your XS script. The debugger is deactivated by default - even if you see the "Debugger" button in the scenario editor.
a. How to enable the debugger:
The easiest way is to create a new link icon for AOE3:DE onto your desktop. Select your "Age of Empires III" icon on your desktop, then right click on it and chose "Create Link". You will get a new icon on your desktop: "Age of Empires III (2)". Now, right click on your new "Age of Empires III (2)" icon, then right click on it and chose "Properties". In the popup menu you see the target line similar to this:
"C:\...\Age of Empires III\Age3.exe"
Add the green text below and press "ok". That's it!
"C:\...\Age of Empires III\Age3.exe" +debugRandomMaps
(for debugging AI scripts it is +debugAI, but not needed here)
Note: Do NOT use the "user.cfg" file to enable the debugger. This can cause problems with future patches of the game.
b. How to debug your random map:
Now run AOE3:DE by clicking your new AOE3:DE debugger icon, then select your new map in the Scenario Editor by chosing "File -> New -> Type='Your map' and enable the debugger button!". Then generate it.
For PLAYTESTING the map script with the computer players offline:
You MUST move your map files (MyMap.xs and MyMap.xml) from the AOE3:DE installation directory
"C:\...\Programs\Microsoft Games\Age of Empires III\RM\"
to your windows profile directory, usually
"C:\...\My Documents\My Games\Age of Empires III\RM\"
If you JUST COPY your files you get problems later!
For Re-editing your custom map files, move your files back to the previous directory!
Notes:
- Do NOT publish or play any maps online which did NOT pass the debugger without errors!
- NEVER EVER use map names for your new map which already exist, neither offline (SP) nor online (MP: LAN or ESO2)!
- Feel free to modify AND rename the original AOE3:DE random map scripts - you have paid for it!
- Do NOT modify or use parts of custom random map scripts without permission by the authors.
Most RM scripters leave their name and address in the script header. So, contact them BEFORE you publish their modified script!
NOW LET US HAVE SOME FUN!
We change the original AOE3:DE "Texas" map from summer skin to winter skin. After reading this small sub chapter you will be able to create and play the following map:
The original "Texas" map:
Your new "Texas Winter" map:
Features:
- The map you will create here has EXACTLY the same gameplay as the original "Texas" map!
- It can be played single player mode, multiplayer mode and even on ESO2 (It was already published, so avoid the last step - PUBLISHING. If you want to make this map unique, read the complete tutorial here.).
Step "0":
If you have any questions, later, scroll up to the top of this site and select the item in the menu to the left.
Step 1:
First we copy the original map files to another directory:
The original map files are called "texas.xs" and "texas.xml" and are usually located in the directory:
"C:\...\Programs\Microsoft Games\Age of Empires III\RM\".
Copy them to any other directory, as example "C:\".
Step 2:
Now rename these files as follows:
"texas.xs" -> "texas winter YourName.xs" - (just replace YourName with your nickname, in all Steps)
and
"texas.xml" -> "texas winter YourName.xml".
Then, right click on each file - one by one - and select "Properties". In the popup property menu disable "write protection" for each file. Now you are allowed to edit these files without any warnings.
Step 3:
Now, move both renamed files back to the directory where you copied them from, usually:
"C:\...\Programs\Microsoft Games\Age of Empires III\RM\".
Step 4:
Now open your "Notepad" and open your new file "texas winter YourName.xml".
Note: Better use a text editor which shows you the line you are currently working on. Like WinEdt 5.4, or any other. By the way, this text editor rocks, and I use it regularly - especially for RMS. "Texturizer 1.7" or higher is also great. But, now back to basics...
The file content is:
<?xml version = "1.0" encoding = "UTF-8"?>
<mapinfo details = "25997" imagepath = "ui\random_map\texas" displayNameID = "25996" cannotReplace = ""
loadDetails="35876" loadBackground="ui\random_map\texas\texas_map">
<loadss>ui\random_map\texas\texas_ss_01</loadss>
<loadss>ui\random_map\texas\texas_ss_02</loadss>
<loadss>ui\random_map\texas\texas_ss_03</loadss>
</mapinfo>
Change it into (black bold text only ... and avoid line breaks!):
<?xml version = "1.0" encoding = "UTF-8"?>
<mapinfo details = "25997" imagepath = "ui\random_map\texas" displayName = "Texas Winter YourName" cannotReplace = ""
loadDetails="35876" loadBackground="ui\random_map\texas\texas_map">
<loadss>ui\random_map\yukon\yukon_ss_01</loadss>
<loadss>ui\random_map\yukon\yukon_ss_02</loadss>
<loadss>ui\random_map\yukon\yukon_ss_03</loadss>
</mapinfo>
(If you want to know what the changes will do, just read the subchapter "XML FILES" above - but not needed here).
Now, save the XML file. Cool, your own XML file is finished! Now the XS file ...
Step 5:
Change the following lines in your "texas winter YourName.xs" file (the changes appear colored):
NOTES:
- Do NOT make line breaks while typing the text in!
- ONLY the text in Courier Font should be changed in the corresponding script line!
- The outlined grey text: /* old ... */ can be neglected if you like. It is only for your help.
/* Line 001:*/
// TEXAS WINTER - made by YourName - with help of M0nTy_PyTh0n's RMS Tutorial /* old was "TEXAS" */
/* Line 002:*/
// CurrentMonth Year - The Tutorial can be found here: https://web.archive.org/web/20100421112530/http://hyenastudios.mugamo.com/aoe3rmstutorial.htm#I /* old was "October 2003" */
/* Line 061:*/
rmSetLightingSet("Yukon"); /* old lighting was "Texas" */
/* Line 065:*/
rmSetBaseTerrainMix("yukon snow"); /* old terrain mix was "texas_grass" */
/* Line 066:*/
rmTerrainInitialize("yukon\ground1_yuk", 5.0); /* old terrain was "texas\ground1_tex" */
/* Line 067:*/
rmSetMapType("yukon"); /* old map type was "texas" */
/* Line 068:*/
rmSetMapType("snow"); /* old map type was "grass" */
/* Line 184:*/
rmAddObjectDefItem(randomTreeID, "TreeYukon", 1, 0.0); /* old object was "TreeTexasDirt" */
/* Line 192:*/
rmAddObjectDefItem(StartAreaTreeID, "TreeYukon", 1, 0.0); /* old object was "TreeTexasDirt" */
/* Line 246:*/
rmSetAreaTerrainType(westDesertID, "yukon\ground4_yuk"); /* old terrain was "texas\ground4_tex" */
/* Line 247:*/
rmAddAreaTerrainLayer(westDesertID, "yukon\ground1_yuk", 0, 4); /* old terrain was "texas\ground1_tex" */
/* Line 248:*/
rmAddAreaTerrainLayer(westDesertID, "yukon\ground2_yuk", 4, 10); /* old terrain was "texas\ground2_tex" */
/* Line 249:*/
rmAddAreaTerrainLayer(westDesertID, "yukon\ground8_yuk", 10, 16); /* old terrain was "texas\ground3_tex" */
/* Line 251:*/
rmSetAreaMix(westDesertID, "yukon snow"); /* old terrain mix was "texas_dirt" */
/* Line 270:*/
rmSetAreaTerrainType(id, "yukon\ground2"); /* old terrain type was "texas\ground2" */
/* Line 704:*/
rmSetAreaCliffType(cliffEastID, "Rocky Mountain2"); /* old cliff type was "Texas Grass" */
/* Line 710:*/
rmAddAreaTerrainLayer(cliffEastID, "yukon\ground2_yuk", 0, 2); /* old terrain was "texas\ground2_tex" */
/* Line 745:*/
rmSetAreaCliffType(cliffWestID, "Rocky Mountain2"); /* old cliff tpye was "Texas" */
/* Line 751:*/
rmAddAreaTerrainLayer(cliffWestID, "yukon\ground2_yuk", 0, 2); /* old terrain was "texas\ground2_tex" */
/* Line 809:*/
rmSetAreaForestType(westForest, "yukon forest"); /* old forest type was "texas forest dirt" */
/* Line 845:*/
rmSetAreaForestType(eastForest, "yukon snow forest"); /* old forest type was "texas forest" */
Done Editing! Congratulations!!!
Step 6:
Now, save both edited files and move (MOVE! NOT COPY!) both files to your custom random map directory, usually:
"C:\...\My Documents\My Games\Age of Empires III\RM\" .
Step 7:
Play your new map! Select your map in the Skirmish startup menu by pressing the "Custom Maps" button.
Enjoy!
FINAL NOTES:
- You can also make the changes line-by-line and generate the map in the scenario editor to see the effects. Sometimes you have to load the map a few times (or with different player number) to see it.
- If you did not succeed, go to this chapter above!
- If you are too lazy modifying this map by your own, then shame on you ;) , but download it here!
- Do NOT publish this map online. I already did it! But, now there are new possibilities for you to make new maps, right?!
HOW TO GET HELP
Some ways to get help:
- Look at Ensemble Studios official RM scripts to learn conventions and shortcuts. A lot of lines in their RM scripts have comments for your
better understanding. - Use the XS debugger (see above).
- Using the console, you can get help for any command by typing: help(“command”)”
- Look online. Fan sites are often a great source of information on random map scripting.
- Keep it simple. If something in your script seems to be breaking, try and isolate the problem.
Have additional questions about modding? You can ask questions and talk with other mod creators in the following places: