Contents
- General Purpose
- Players
- Areas
- Connections
- Objects
- Fair Objects
- Constraints
- Trade Routes
- Triggers
- Disclaimer
GENERAL PURPOSE
rmEchoInfo( string echoString, int level);
Random map echo. Use this to spit out information while debugging a script. It is not shown to the player.
rmRandFloat(float min, float max);
Returns a random float between min and max. This is a random number generator useful for determining random events. Because it is a float, it can handle decimals.
rmRandInt(int min, int max);
Returns a random integer between min and max. This is a random number generator useful for determining random events. Because it is an integer, it cannot handle decimals, but that makes it useful for placing down numbers of objects.
rmSetMapSize( int x, int z);
Sets the size of the map. X and Z are in meters. They do not need to be the same if you want to create a rectangular map. All ES maps scale map size by number of players.
rmSetSeaLevel();
Sets the sea level for the map.
rmGetSeaLevel();
Gets the sea level for the map.
rmSetSeaType(string name);
Sets the sea type for the map. This is used if terrain is initialized to water.
You must use this command before you place water on a map. The sea type must be a valid water type from the random map editor.
rmAreaFractionToTiles(float fraction);
Converts an area from fraction of the map to tile count. Fractions are relative to map size, so sometimes you may want to use them.
rmAreaTilesToFraction(int tiles);
Converts area tile count to fraction of map.
rmXFractionToTiles(float fraction);
Converts an fraction of the map in the x direction to tile count.
rmXTilesToFraction(int tiles);
Converts tile count in the x direction to fraction of map.
rmZFractionToTiles(float fraction);
Converts an fraction of the map in the z direction to tile count.
rmZTilesToFraction(int tiles);
Converts tile count in the z direction to fraction of map.
rmMetersToTiles(float meters);
Converts a distance in meters to a number of tiles.
rmTilesToMeters(int tiles);
Converts a number of tiles to a distance in meters.
rmXMetersToFraction(float meters);
Converts meters into a fraction of the map in the x direction.
rmZMetersToFraction(float meters);
Converts meters into a fraction of the map in the z direction.
rmXFractionToMeters(float meters);
Converts a fraction of the map in the x direction to meters
rmZFractionToMeters(float meters);
Converts meters a fraction of the map in the z direction to meters.
Fractions are relative to map size, so sometimes you may want to use them instead of distances in meters.
rmDegreesToRadians(float degrees);
Converts an angle in degrees to radians.
Particularly useful when players are placed in a circle.
rmTerrainInitialize( string baseTerrain, float height);
Initializes the terrain to the base type and height. Specifies the base terrain to use for a map. If set to water, sea type needs to be defined. Initial terrain is usually grass, sand, snow or water.
rmSetLightingSet(string name);
Sets a lighting set. You can specify a lighting set from the scenario editor to be used for your RMS. This command must be placed after terrain is initialized.
rmSetGaiaCiv(long civ);
Sets Gaia's civilization. This is only useful if you place Gaia objects that vary by civilization, such as special civilisation units.
rmSetStatusText(status, progress);
Sets the friendly cool loading screen text. This text will be seen by players while the map is generating. If you do not at least specify percentages in the progress parameter, the “loading bar” will not advance during map generation.
rmDefineConstant(string name, int value);
Defines an integer constant.
PLAYERS
Player locations need to be determined so that objects and area can be placed “by player.” Player areas must still be created as individual areas.
A special player in an RM script is the "Gaia" player and always has the player number "0" in a map script (see chapter above for more explanations). The following commands refer to human and computer players only:
rmGetPlayerCiv(int playerID);
Gets the civilization the specified player is on.
rmGetCivID(string civilization);
Sets the civilization to compare with the players civilization. Example:
if ( rmGetPlayerCiv(i) == rmGetCivID("Russians")) {
/* do something for player i if he is Russian */
};
These commands are useful for placing specific objects or varying starting resources. They are also useful for triggers that fire or prohibit specific improvements.
rmGetNumberPlayersOnTeam(int teamID);
Gets the number of players on the given team. Useful for scaling area or resources in a team area based on number of players on that team.
rmSetTeamSpacingModifier(float modifier);
Sets the team spacing modifier. Normally, all players are placed equidistant. This command allows you to force team members closer together.
Values of 0.3-0.5 return the best results. Values less than 0.25 may not provide enough space for starting resources.
rmPlacePlayersCircular(float minFraction, float maxFraction, float angleVariation);
Makes a circle of player locations. Places players in a circle. Variation is determined by the difference between the min and max. Angle variation determines whether players are equidistant or can be slightly closer or farther apart. Circular placement is generally the most versatile, but will not work on all map types, such as non-square maps.
rmPlacePlayersSquare(float dist, float distVariation, float spacingVariationfloat);
Makes a square of player locations. Places players in a square, which automatically adjusts to a rectangle for rectangular maps. Unlike the circle, variance here is determined by a plus or minus (the distVariation) off of the mean distance. SpacingVariation determines whether players are equidistant or can be slightly closer or farther apart.
rmPlacePlayersLine(float x1, float z1, float x2, float z2, float distVariation, float spacingVariation);
Makes a line of player locations. Sometimes you will want players to be placed in a line. Texas places each time in a line, while New England places all players in a circle. Using a line placement is not easy because there may not be enough room for player areas or resources. X and Z determine the starting and ending locations of the line. DistVariation determines how far from the line player areas can vary, and spacingVariation determines how much space there is among points along the line where players are placed.
rmSetPlacementSection(float fromPercent, float toPercent);
When placing players in a circle or square, this command allows you to skip part of the circle or square, in essence removing a slice from the pie (maybe you want to fit an ocean or sea in there like in Texas). The default for fromPercent is 0, and the default for toPercent is 1. That means use the whole circle or square. You can pass in something like 0.25 and 0.50 to have the players placed from 25% in to 50% in along the circle or square. For circular placement, 0 is at 9:00, 0.25 is at 12:00, 0.5 is at 3:00, and 0.75 is at 6:00. For square placement (think of the square as a line that follows a square), 0 is at 6:00, 0.25 is at 9:00, 0.5 is at 12:00, and 0.75 is at 3:00.
rmSetPlacementTeam(long teamID);
Sets the team to place. Use this before calling the various rmPlacePlayers functions, and only players on the specified team will get placed. The first team is number 0, the second is number 1, etc. Pass in -1 for the teamID to place all teams (or actually all players that haven't been placed yet).
rmPlacePlayer(int playerID, float xFraction, float zFraction);
Sets one player location. You can use this to place players anywhere. Once a player is placed, it won't be repositioned by any future calls to the various rmPlacePlayers functions. This can be tricky since you often do not know how many players will be placed on the map, since from 2-12 players can play any map.
Here are a few examples of things you can do:
Put the first team in the center of the map and all other teams around the outside:
rmSetPlacementTeam(0);
rmSetPlayerPlacementArea(0.3, 0.3, 0.7, 0.7);
rmPlacePlayersCircular(0.4,0.3,rmDegreesToRadians(5.0));
rmSetPlacementTeam(-1);
rmSetPlayerPlacementArea(0, 0, 1, 1);
rmPlacePlayersCircular(0.4,0.3,rmDegreesToRadians(5.0));
Put player one in the bottom corner, player two in the right corner, and the rest of the players in a line from the left corner to the top corner (9:00 to 12:00):
rmPlacePlayer(1, 0.2, 0.2);
rmPlacePlayer(2, 0.8, 0.2);
rmPlacePlayersLine(0.2, 0.8, 0.8, 0.8, 20, 10);
rmSetPlayerPlacementArea(float minX, float minZ, float maxX, float maxZ);
Sets the area of the map to use for player placement. Use this command if, for example, you want to place players in one quadrant of a map.
rmSetPlayerArea(int playerID, int areaID);
Sets a player's 'official' area.
rmSetTeamArea(int teamID, int areaID);
Sets a team's 'official' area. When you want an area to belong to a player (i.e. this is the location from which you will place player resources) assign it to a player. Teams work the same way. Usually you want to iterate through number of players using for(i=1; <cNumberPlayers).
rmPlayerLocXFraction(int playerID);
Gets a player's start location x fraction.
rmPlayerLocZFraction(int playerID);
Gets a player's start location z fraction. Use these commands when you don’t know where a player’s starting location is and you need the values to place other areas or resources.
AREAS
Areas are regions on a map. They are often irregular in shape, but can be rectangular as well. Some areas are used for placing specific terrain, like a cliff or ocean, while others are just used as boundaries for other areas. Special types of areas are player areas, which belong to a certain player, or team areas, which belong to a team. Saying these areas “belong” is just a convenient method of making sure other areas or objects are placed in that area.
rmCreateArea(string name, int parentAreaID);
Creates an area. Creates an area and lets you name it. Areas without a parentArea use the entire map as their parentArea. You can also make existing areas the parentArea, in order to place a sub-area within a player area, for example. Areas will generally try to place several times and will return an error message if they fail. To ignore this error message, use setAreaWarnFailure below.
rmSetAreaSize(float minFraction, float maxFraction);
Set the area size to a min/max fraction of the map. The min and max can be set to the same value if you want no size variation. Experiment with different values to make sure your area is not too large or too small to be seen. Even if your area does not place special terrain, it can be helpful to temporarily paint the area with a distinct texture, such as black or snow, to see where and if it is actually getting placed.
rmSetAreaLocation(int areaID, float xFraction, float zFraction);
Set the area location. Sometimes you want to place an area in a specific location, such as 0.5, 0.5, the center of the map.
rmSetAreaLocPlayer(int areaID, int playerID);
Set the area location to player's location. This is a shortcut for placing an area at the player’s location. Generally, this is used when tiny player areas are first placed as placeholders, then SetAreaLocPlayer can be used to make larger player areas later or to place a sub-area (such as a terrain patch) near the player’s Town Center.
rmSetAreaLocTeam(int areaID, int teamID);
Set the area location to team's location. Just like SetAreaLocPlayer except it applies to team areas.
rmBuildArea(int areaID);
Builds the specified area. Actually builds the area. Choosing when to use this command can have a big effect on your map. For example, if you define a lake area and then build it, land that is placed later can stick into the lake or be placed as islands. On the other hand, if the land and water are built at the same time, they will try to avoid each other (if the proper constraints are set). Generally, player areas should all be built at the same time to make sure there is enough space for ever player.
rmBuildAllAreas();
Simulatenously builds all unbuilt areas. Does not include connections.
rmSetAreaTerrainType(int areaID, string terrainTypeName);
Sets the terrain type for an area. Often, you want to paint in an area with a certain terrain. Use the terrain names from the scenario editor. Forests, cliffs, and water are handled differently. Use AreaTerrainType for terrains such as grass, snow, ice, and sand.
rmPaintAreaTerrain(int areaID);
Paints the terrain for a specified area.
rmSetAreaBaseHeight(int areaID, float height);
Sets the base height for an area. If not specified, the area will adopt the height of the parent area, including the base height of the map if no parent area is specified. Make sure to place land higher than water if you want to place land objects (such as TownCenter) later.
rmSetAreaWarnFailure(int areaID, bool warn);
Sets whether the area build process will warn if it fails. It is very easy to over-constrain areas to the point where there is no room for them. This can cause two problems: the map may take a long time to generate, or if you are in debug mode (see above), the debugger will pop up and generation will stop. Sometimes you want to catch these errors, but when you are done with your map it is a good idea to set SetAreaWarnFailure to false.
rmSetAreaForestType(int areaID, string forestName);
Sets the forest type for an area.
Paints the area with a forest type. Use the forest types from the scenario editor.
rmSetAreaWaterType(int areaID, string waterName);
Sets the water type for an area. Paints the area with a water type. Use the water types from the scenario editor. Because water types automatically change elevation and can place objects, they tend to affect areas a little larger than specified. Just allow plenty of room.
rmSetAreaCliffType(int areaID, string cliffName);
Sets the cliff type for an area. Cliffs are handled differently from other terrain in order to allow you to handle features like ramps. However, you can use setAreaTerrainType to place an impassable cliff-texture as a normal area as well. CliffName should use a cliff type from the Editor.
rmSetAreaCliffPainting(int areaID, bool paintGround, bool paintOutsideEdge, bool paintSide, float minSideHeight, bool paintInsideEdge);
Set cliff painting options for an area. Determines how a cliff is painted with impassable and passable textures. PaintGround - Specifies if the ground should be painted or just left whatever it already is. Defaults true. PaintSide - Specifies if the cliff sides should be painted. Defaults true. PaintEdge - Specifies if the cliff edge should be painted. This is the area between the cliff side and the ground. Defaults true. MinSideHeight - Specifies the minimum height that a cliff tile must be sloped before treating it as a cliff side. Set to 0 to have the minimum amount of cliff sides painted. Defaults to 1.5.
rmSetAreaCliffEdge(int areaID, int count, float size, float variance, float spacing, int mapEdge);
Set cliff edge parameters for an area. Determines whether there should be pathable ramps or not connecting the top of the cliff to the surrounding area. Count - Number of cliff edges to create. The count times the size should not be more than 1.0. Defaults to 1. size - This specifies how much of the area's outline should be turned into cliff edges. It should be between 0.0 and 1.0. Set to 1.0 to make the whole area surrounded. Defaults to 0.5. Variance - The variance to use for the size. Defaults to 0.0. Spacing - Spacing modifier. This should be between 0.0 and 1.0. The smaller this is, the closer together the cliff edges will be. Defaults to 1.0. MapEdge - Specifies where the cliff edge should be in relation to the map edge. Set to 0 for any, 1 to be away from the map edge, or 2 to be close to the map edge. Defaults to 0.
rmSetAreaCliffHeight(int areaID, float val, float variance, float ramp);
Set an area's cliff height. Val - Make positive for raised cliffs and negative for lowered cliffs. Defaults to 4.0.
Variance - The variance to use for the height. Ramp - This is used to determine how quickly the height ramps up to the cliff height (it refers to steepness in this context, not pathable ramps to reach the top of a cliff). Defaults to 0.5.
rmAddAreaCliffEdgeAvoidClass(int areaID, int avoidID, float minDist);
Adds a class for an area's cliff edge to avoid. You can tell a cliff edge to avoid a certain class, such as a connection. Remember that connections must be created before the cliff (see below).
rmAddAreaTerrainLayer(int areaID, string terrain, float minDist, float maxDist);
Adds a terrain layer to an area. Terrain layers allow you to place a border of one or more textures around an area. For example, you can have "texas\ground3_tex" and "texas\ground4_tex" around an area of grass. You can specify multiple layers for an area, as long as the minDistance for one starts where the maxDistance for another leaves off. Because different textures overlap one another you may need to experiment with distances to get the correct effect. Here is an example:
rmSetAreaTerrainType(bonusIslandID, "texas\ground2_tex");
rmAddAreaTerrainLayer(bonusIslandID, "texas\ground6_tex", 13, 20);
rmAddAreaTerrainLayer(bonusIslandID, "texas\ground5_tex", 6, 13);
rmAddAreaTerrainLayer(bonusIslandID, "texas\ground4_tex", 0, 6);
rmSetAreaTerrainLayerVariance(int areaID, bool variance);
Specifies if the area should vary the terrain layer edges. Usually, variance in terrain layers looks better, but sometimes you might want to turn it off. Defaults to true.
rmSetAreaMinBlobs(int areaID, int blobs);
Sets minimum number of area blobs.
rmSetAreaMaxBlobs(int areaID, int blobs);
Sets maximum number of area blobs. An area can be placed with multiple blobs. Blobs are placed independently, using the minimum and maximum distances below. Areas made with a single blob will be circular. Areas made with multiple blobs can be come long and sinuous.
rmSetAreaMinBlobDistance(int areaID, float dist);
Sets minimum blob distance.
rmSetAreaMaxBlobDistance(int areaID, float dist);
Sets maximum blob distance. Specifies how far apart blobs can be from each other. The greater the distance, the more the area will tend towards serpentine instead of circular (envision a chain of beads). However, if you specify many blobs, this variation may become obscured as more and more blobs are placed for the area.
rmSetAreaCoherence(int areaID, float coherence);
Sets area coherence (0-1). Coherent areas tend to stay together more. The effect is harder to notice on smaller areas.
rmSetAreaSmoothDistance(int areaID, int smoothDistance);
Sets area edge smoothing distance. Distance is number of neighboring points to consider in each direction. Water areas benefit from more smoothness as it eliminates small bumps and indentations.
rmSetAreaHeightBlend(int areaID, int heightBlend);
Sets how smoothly area height blends into surroundings. Corresponds to the smooth tool in the Scenario Editor. Usually a heightBlend of 0 will leave geometric-looking jagged edges. A heightBlend of 1 will smooth smaller areas. A heightBlend of 2 will smooth larger areas or areas of disproportionate heights. Anything above 2 may flatten an area completely.
rmAreaID(string name);
Gets area ID for given area name.
rmAddAreaInfluencePoint(int areaID, float xFraction, float zFraction);
Adds an area influence point.
rmAddAreaInfluenceSegment(int areaID, float xFraction1, float zFraction1, float xFraction2, float zFraction2);
Adds an area influence segment. You may want an area to grow towards specific points or lines. A circular area placed at the center of the map with an influence point of 1, 1 will produce a peninsula that protrudes towards 12 o’clock. Influence points and segments can be useful in getting areas, such as rivers, to extend beyond the edge of the map.
rmAddAreaRemoveType(int areaID, string typeName);
Add an unit type that the specified area removes. Sometimes you may want an area to clean itself of objects, such as removing trees from ice. This will only work if the objects are already placed before the area, which is the reverse of how most ES maps are generated. You can reference specific units or abstract types, such as “unit” and “building.”
rmAddAreaTerrainReplacement(int areaID, string terrainTypeName, string newTypeName);
Adds a terrain replacement rule to the area. If you place an area with no terrain specified, it will use the terrain of the parent area (including the base map). However, specifying terrain replacement will paint an area only when another texture is present. This command is most useful with connections, where you want to replace water with land where a connection goes across a river, or replace rock with snow for mountain passes.
bool rmAddAreaToClass(int areaID, int classID);
Add given area to specified class. The reason to add areas to classes is so you can refer to the entire class later on instead of the individual areas. This is most useful when placing objects (you can say just place in a class) or constraints (you can say to avoid a certain class).
int rmDefineClass(string className);
Define a class with the given name. Like any variable, Classes must be defined before they can be used the first time.
rmClassID(string name);
Gets class ID for given class name.
CONNECTIONS
Connections are special areas that are used to connect other areas. They are typically used to place land-bridges or mountain-passes among players. Connections must be placed after the areas they are trying to connect, but often need to be defined before those areas if the area needs the rmAddConnectionArea command.
rmCreateConnection(string name);
Creates an connection. Defines a new connection.
rmSetConnectionType(int connectionID, int connectionType, bool connectAll, float connectPercentage);
Sets the connection type. This command determines which players are connected. The valid values for connectionType are:
- cConnectAreas: This is the default that is used if you don't call rmSetConnectionType. You have to specify each area to be connected by calling rmAddConnectionArea.
- cConnectPlayers: Connect all player areas.
- cConnectAllies: Connect all ally player areas.
- cConnectEnemies: Connect enemy player areas. Currently this one ignores the connectAll parameter (it treats it as true no matter what). Just let me know if you think it's important for it to work a certain way when connectAll is false... one thing I thought of is connecting each player to its closest enemy.
Set the connectAll parameter to true if you want all of the areas to get connected to all of the other areas. Set it to false to have the areas connected sequentially where the first area gets connected to the second area, the second area gets connected to the third area, etc.
You can use the connectPercentage parameter to reduce the number of connections that are generated. For example, if you set it to 0.5, then half of the connections will get generated. The ones that are generated are randomly chosen. Some ES maps with connections connect all players when player number is small (<6) and uses a connection percentage on larger maps, otherwise so many connections can get placed that the barrier (like water or rock) is obscured.
rmAddConnectionArea(int connectionID, int areaID);
Adds an area to the connection. This is only valid if you set the connection type is set to cConnectAreas. You must specify this while defining the area, after the connection is defined, and before building the connection.
rmSetConnectionPositionVariance(int connectionID, float variance);
Sets the position variance of a connection. The connection will normally start at the area's position, but this allows it to vary from that position. You can set this to -1 for it to pick completely random positions within the starting and ending areas. This command is often needed when specifying multiple connections (for example, one within a team and another between teams) so that the connections do not overlap.
bool rmAddConnectionStartConstraint(int connectionID, int constraintID);
Add specified constraint for a connection start point.
bool rmAddConnectionEndConstraint(int connectionID, int constraintID);
Add specified constraint for a connection end point. If setConnectionPositionVariance isn’t working out, you can also specify constaints for the endpoints of the connection itself. This way you can have connection endpoints avoid impassable land or player areas, for instance.
rmSetConnectionWidth(int connectionID, float width, float variance);
Sets the width of a connection. Because connections are often the only pathable area over a barrier such as water or rock, set this wide enough to prevent pathing problems, typically > 8.
rmSetConnectionBaseHeight(int connectionID, float width);
Sets the base height of a connection.
rmSetConnectionCoherence(int connectionID, float width);
Sets area coherence (0-1).
rmSetConnectionWarnFailure(int connectionID, bool warn);
Sets whether a connection warns on failure.
rmSetConnectionHeightBlend(int connectionID, float width);
Sets how smoothly connection height blends into surroundings.
rmSetConnectionSmoothDistance(int connectionID, float width);
Sets connection edge smoothing distance (distance is number of neighboring points to consider in each direction).
rmAddConnectionTerrainReplacement(int connectionID, string terrainTypeName, string newTypeName);
Adds a terrain replacement rule to the connection. These commands all work exactly as they do for areas, but must be called out specifically for connections.
rmSetConnectionTerrainCost(int connectionID, string terrainTypeName, float cost);
Sets the terrain cost for a connection. When you need a connection to avoid a type of terrain, set this value. If you place roads between players, you might want them to avoid forests or cliffs. The cost must be greater than or equal to 1, or set to -1 to specify a terrain is impassable.
rmSetConnectionBaseTerrainCost(int connectionID, float cost);
Sets the base terrain cost for a connection. This is the cost that will be used for all terrains that don't have a cost set with rmSetConnectionTerrainCost. The default cost for each terrain type is 1 if this is not called.
rmBuildConnection(int connectionID);
Builds the given connection. Make sure the areas are built first. RmBuildAllAreas does not include connections.
rmAddConnectionToClass(int connectionID, int classID);
Adds the connection to specified class. Useful with constraints for areas or objects placed after the connection.
bool rmAddConnectionConstraint(int connectionID, int constraintID);
Add specified constraint to a connection. Useful when the constraint is applied to the connection. As with all constraints, the connection can only avoid areas or objects that are placed before it is placed.
OBJECTS
Objects include anything placed on a map that is not a terrain. Buildings, units and resources are all objects. Objects can even be collections of many different units. Just remember that objects are always placed as clusters and sometimes it might be easier to place 2 different objects than to add different types of units to one object.
bool rmAddObjectDefToClass(int objectDefID, int classID);
Add given object def to specified class. Useful for using class constraints.
rmCreateObjectDef(string name);
Creates an object definition. Used to define a new object.
rmSetObjectDefMinDistance(int defID, float dist);
Set the minimum distance for the object definition (in meters).
rmSetObjectDefMaxDistance(int defID, float dist);
Set the maximum distance for the object definition (in meters). These distances apply to the object location. If the object location equals a player’s location, then these are the min and max from the player starting area (usually the Town Center). A useful approach is to place the object at location 0.5, 0.5 (the center of the map) and assign a maxDistance of half of the map. See the subchapter "Map Grid" above for more explanations.
rmAddObjectDefItem(int defID, string unitName, int count, float clusterDistance);
Add item to object definition. Objects are defined in the random map script and can be named anything. Units, on the other hand, use specific names from the game, such as Villager Greek, Palm or TownCenter (the game’s name for a Town Center). Cluster distance is only the maximum that the object can be placed from the location, and is applied after the min and max distance are applied (i.e. a maxDistance of 10 and a clusterDistance of 5 could actually place an object 15 m from the location). When placing a single unit, clusterDistance can be 0. If multiple units are added to the object, they should use a clusterDistance > 0 or they will place on top of each other. Here are two examples:
int farCowsID=rmCreateObjectDef("far cows");
rmAddObjectDefItem(farCowsID, "cow", 1, 0.0);
int rock2ID=rmCreateObjectDef("rock2");
rmAddObjectDefItem(rock2ID, "rock limestone small", 1, 1.0);
rmAddObjectDefItem(rock2ID, "rock limestone sprite", 3, 3.0);
rmPlaceObjectDefAtLoc(int defID, int playerID, float xFraction, float zFraction, long placeCount);
Place object definition at specific location for given player. Placing objects this way is useful when you don’t want to place them for every player, as in the case where you place different units for different civilizations. You can set int playerID to 0 to make sure nobody owns the object. Here’s a nice shortcut:
for(i=0; <cNumberPlayers)
{
if(rmGetPlayerCiv(i) == rmGetCivID("Russians"))
rmPlaceObjectDefAtLoc(transportRussiansID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
else if(rmGetPlayerCiv(i) == rmGetCivID("Germans"))
rmPlaceObjectDefAtLoc(transportGermansID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
else if(rmGetPlayerCiv(i) == rmGetCivID("French"))
rmPlaceObjectDefAtLoc(transportFrenchID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
}
rmPlaceObjectDefPerPlayer(int defID, bool playerOwned, long placeCount);
Place object definition per player. This command is often the fastest way to place objects, particularly when compared to doinf for loops over player number. However, it isn’t applicable when you don’t want to place the object at least once for every player. Return playerOwned as false if you want the object to belong to gaia.
rmPlaceObjectDefAtAreaLoc(int defID, int playerID, int areaID, long placeCount);
Place object definition for the player at the given area's location. The difference between this and placeObjectDefAtLoc is that the latter needs an X, Z coordinate, while this command just finds the area’s center location.
rmPlaceObjectDefInArea(int defID, int playerID, int areaID, long placeCount);
Place object definition for the player in the given area. Places the object randomly within the entire area (as apposed to the center location).
rmPlaceObjectDefAtRandomAreaOfClass(int defID, int playerID, int classID, long placeCount);
Place object definition for the player at the location of a random area in the given class.
rmPlaceObjectDefInRandomAreaOfClass(int defID, int playerID, int classID, long placeCount);
Place object definition for the player in a random area in the given class. The difference between these two is that the first uses the area’s location while the second just finds a random location within an area. Return playerID as 0 to place an object not owned.
rmGetNumberUnitsPlaced(int objectDefID);
rmGetUnitPlaced(int objectDefID, int index);
rmGetUnitPlacedOfPlayer(int objectDefID, int playerID);
These three commands can be used to detect failed cases of object placement. Perhaps you want to try and place an object a second time with fewer constraints if it fails the first time. Here is an example from Acropolis:
for(i=1; <cNumberPlayers)
{
int startingOutpostID=rmCreateObjectDef("Starting Outpost "+i);
int outpostRampConstraint=rmCreateCliffRampConstraint("onCliffRamp"+i, rmAreaID("player"+i));
int outpostRampEdgeConstraint=rmCreateCliffEdgeMaxDistanceConstraint("nearCliffEdge"+i, rmAreaID("player"+i), 2);
rmAddObjectDefItem(startingOutpostID, "Outpost", 1, 0.0);
rmAddObjectDefConstraint(startingOutpostID, avoidOutpost);
rmAddObjectDefConstraint(startingOutpostID, outpostRampConstraint);
rmAddObjectDefConstraint(startingOutpostID, outpostRampEdgeConstraint);
rmAddObjectDefToClass(startingOutpostID, classOutpost);
rmPlaceObjectDefInArea(startingOutpostID, i, rmAreaID("player"+i), 6);
/* backup to try again */
if(rmGetNumberUnitsPlaced(startingOutpostID) < 4)
{
int startingOutpostID2=rmCreateObjectDef("Less Optimal starting Outpost"+i);
rmAddObjectDefItem(startingOutpostID2, "Outpost", 1, 0.0);
rmAddObjectDefConstraint(startingOutpostID2, avoidOutpost);
rmAddObjectDefConstraint(startingOutpostID2, outpostRampConstraint);
rmAddObjectDefToClass(startingOutpostID2, classOutpost);
rmPlaceObjectDefInArea(startingOutpostID2, i, rmAreaID("player"+i), 1);
}
}
rmSetIgnoreForceToGaia(bool val);
Can be used to force any placed object, even resources, to belong to a player.
FAIR OBJECTS
These special commands are designed to place critical resources, such as TownCenters and sometimes Silver Mines. They are expensive and slow, so should not be used for many objects, but can insure that objects that “must place” are present on a map.
int rmAddFairLoc(string unitName, bool forward, bool inside, float minPlayerDist, float maxPlayerDist, float locDist, float edgeDist, bool playerArea, bool teamArea);
Adds some fairLoc placement info. For each fairLoc you specify the following settings: optional object name to use (for check placement), forward or back (forward means towards the enemy), inside or outside (inside means towards an ally), min/max distance from the player, min distance from other locations, and min distance from the edge of the map. You can also add regular constraints to it. Specifying playerArea or teamArea forces the location to that area, providing these areas are defined. Useful for keeping a TownCenter on a player’s island rather than across a river.
bool rmPlaceFairLocs();
Sets fairLoc placement locations. After each fairLoc is created, you call rmPlaceFairLocs which will calculate the actual positions, one per player per fairLoc. These are just positions (or locations) so you can use them for anything such as placing units or creating areas.
rmResetFairLocs();
Resets fairLoc placment info. Once you are done with a set of fairLocs and want to create another set, you should call rmResetFairLocs. This clears out any fairLocs you previously added.
int rmGetNumberFairLocs(int playerID);
Gets a player's number of fairLocs.
float rmFairLocXFraction(int playerID, int index);
Gets a player's fairLoc x fraction.
float rmFairLocZFraction(int playerID, int index);
Gets a player's fairLoc z fraction.
Fair Loc example for TownCenters:
id=rmAddFairLoc("TownCenter", true, false, 70, 120, 60, 40); /* forward outside */
rmAddObjectDefConstraint(id, TownCenterAvoidImpassableLand);
rmAddObjectDefConstraint(id, playerConstraint);
if(rmPlaceFairLocs())
{
id=rmCreateObjectDef("far TownCenter2");
rmAddObjectDefItem(id, "TownCenter", 1, 0.0);
for(i=1; <cNumberPlayers)
{
for(j=0; <rmGetNumberFairLocs(i))
rmPlaceObjectDefAtLoc(id, i, rmFairLocXFraction(i, j), rmFairLocZFraction(i, j), 1);
}
}
CONSTRAINTS
Constraints are used for areas, connections, and objects. They make sure that objects avoid other objects, that objects are placed near certain areas and similar restrictions.
int rmCreateBoxConstraint(string name, float startX, float startZ, float endX, float endZ, float bufferFraction);
Make a box constraint. Box constraints are simply four line segments that subdivide the map. Creating a box constraint can be used to keep areas or objects from getting too close to the center
int rmCreateAreaOverlapConstraint(string name, int areaID);
Make an area overlap constraint. Prevents areas from overlapping.
int rmCreateAreaConstraint(string name, int areaID);
Make a constraint that forces something to remain within an area. You can’t specify distance, only that an object or area must remain within the area.
int rmCreateAreaDistanceConstraint(string name, int areaID, float distance);
Make an area distance constraint. Specifies a minimum distance that an object or area can be from an area. Useful for keeping resources from getting too close to a TC or other resources.
int rmCreateAreaMaxDistanceConstraint(string name, int areaID, float distance);
Make an area max distance constraint. Specifies a maximum distance that an object or area can be from an area. Useful for keeping resources from getting too far away from a player.
int rmCreateEdgeConstraint(string name, int areaID);
Make a constraint that forces something to remain within an area's edge. Area edges are not large, so this can be tricky.
int rmCreateEdgeDistanceConstraint(string name, int areaID, float distance);
Make an area edge distance constraint. The minimum distance an area or object can be to an edge.
int rmCreateEdgeMaxDistanceConstraint(string name, int areaID, float distance);
Make an area edge max distance constraint. The maximum distance an area or object can be from an edge.
int rmCreateCliffEdgeConstraint(string name, int areaID);
Make a constraint that forces something to remain within an area's cliff edge.
int rmCreateCliffEdgeDistanceConstraint(string name, int areaID, float distance);
Make an area cliff edge distance constraint.
int rmCreateCliffEdgeMaxDistanceConstraint(string name, int areaID, float distance);
Make an area cliff edge max distance constraint. Cliff edges are handled differently from other areas and need their own constraint. You are often better off telling an object or area to avoid impassable land.
int rmCreateCliffRampConstraint(string name, int areaID);
Make a constraint that forces something to remain within an area's cliff ramp edge.
int rmCreateCliffRampDistanceConstraint(string name, int areaID, float distance);
Make an area cliff ramp edge distance constraint.
int rmCreateCliffRampMaxDistanceConstraint(string name, int areaID, float distance);
Make an area cliff ramp edge max distance constraint. Ramps are the areas of cliffs that have pathable terrain, typically for reaching the top of a cliff. Acropolis has ramps that have towers on the edges of the ramps.
int rmCreateClassDistanceConstraint(string name, int classID, float distance);
Make a class distance constraint. Once you define a class of objects or areas, you can then set a constraint to it.
- int playerConstraint=rmCreateClassDistanceConstraint("stay away from players", classPlayer, 20);
int rmCreateTypeDistanceConstraint(string name, int classID, float distance);
Make a type distance constraint. Types can be specific units, such as Chicken, or abstract types, such as Huntable.
int rmCreateTerrainDistanceConstraint(string name, string type, bool passable, float distance);
Make a constraint to avoid terrain with certain a passability. This is a useful constraint because you can have land objects avoid impassable land, such as water or cliffs, or have water objects avoid the shore.
int avoidImpassableLand=rmCreateTerrainDistanceConstraint("avoid impassable land", "land", false, 10.0);
int rmCreateTerrainMaxDistanceConstraint(string name, string type, bool passable, float distance);
Make a constraint to be close to terrain with certain a passability. Useful for keeping seaweed or transports in the water but near a beach, or Hippos or Crocodiles on the beach near the water.
bool rmAddAreaConstraint(int areaID, int constraintID);
Add specified constraint to an area. Once you have a constraint defined, this is how you make an area adhere to it.
bool rmAddFairLocConstraint(int fairLocID, int constraintID);
Add specified constraint to a fairLoc placement. Once you have a constraint defined, this is how you make a Fair Loc adhere to it.
bool rmAddObjectDefConstraint(int defID, int constraintID);
Add specified constraint to given object def. Once you have a constraint defined, this is how you make an object adhere to it.
rmConstraintID(string name);
Gets constraint ID for given constraint name.
TRADE ROUTES
Trade routes are a new feature in the Age series. You create a trade route by placing waypoints for the paths. Later, you place "SocketTradeRoute" objects to the trade route. Trade routes should be created and built straight after the map terrain and player areas were created. All additional objects such as resources, forests, etc. should be placed with a trade route constraint to avoid the routes. Also, make sure you always place waypoints on connected land.
int rmCreateTradeRouteDistanceConstraint(string name, float distance);
Creates an area constraint of all trade routes to avoid them with distance in meters.
int rmCreateTradeRoute();
Creates a trade route. Like all other rm creations for objects and terrain it is of type integer and can be defined like:
int tradeRoute1ID = rmCreateTradeRoute();
bool rmAddTradeRouteWaypoint(int tradeRouteID, float startX, float startZ);
Adds a waypoint to the tradeRouteID with the startX, startZ coordinates (0.0-1.0) of the map.
bool rmAddRandomTradeRouteWaypoints(int tradeRouteID, float startX, float startZ, float variationX, float variationZ);
Adds a random waypoint to the tradeRouteID with the startX, startZ coordinates (0.0-1.0) of the map and a random variation variationX, variationZ in meters. If you want to make your trade route as a loop or circle then your last added waypoint should have the same coordinates as your first "rmAddTradeRouteWaypoint".
bool rmBuildTradeRoute(int tradeRouteID, string texture);
Builds the trade route defined before. The texture can be "dirt", as example.
vector rmGetTradeRouteWayPoint(int tradeRouteID, float distance);
Gets the location for a trade route socket on the trade route. The distance is the length of the trade route in percent, 0.0 is trade route starting point, 1.0 is the end of the route. This command will be appied after the tradeRouteID was created and built.
TRIGGERS
These commands are used to incorporate triggers from the scenario editor into a random map script. Triggers can get complicated quickly and can also create an unfair map, so they must be used with caution. A full explanation of all the triggers is beyond the scope of this article, but you can generate a random map script within the scenario editor to see how the triggers are created-just look at the triggers as if you had set them up manually. You can also look at the "C:\...\Age of Empires III\trigger\typetest.xml" file for help with debugging RMS triggers.
Furthermore, a trigtemp.xs file is generated every time when loading your RMS into the map editor. It will show you all triggers you set into your random map. This file is in xs-trigger code, which looks a bit different from the RMS file. You can find this file in the directory:
"C:\...\My Documents\My Games\Age of Empires 3\trigger\trigtemp.xs" .
rmCreateTrigger(string triggerName);
Used to create a new trigger. Example:
rmCreateTrigger("MyTrigger1");
rmSwitchToTrigger(int triggerID);
This command is useful for setting up triggers by player. You need to define all the triggers first, but then you can switch to different ones to specify their conditions and effects. Example:
rmSwitchToTrigger(rmTriggerID("MyTrigger1"));
rmTriggerID(string triggerName);
Like areas and objects, triggers must be defined before they can be used.
rmSetTriggerPriority(int priority);
Sets the trigger priority. priority has values between 0 (low) and 4 (highest).
rmSetTriggerActive(bool active);
Sets the activity of the trigger straight after the map was loaded. If you want to fire this trigger later in game select "false", else "true".
rmSetTriggerRunImmediately(bool runImmediately);
runImmediately should always be "true" if you use the trigger for firering cinematics or sounds.
rmSetTriggerLoop(bool loop);
Sets the repetition mode of the trigger. Be careful using loops, since they can easily run mad and stop. Better use 2 triggers instead and fire then towards each other, using the "Fire Event" trigger effect.
rmAddTriggerCondition(string conditionType);
rmSetTriggerConditionParam(string paramName, string value, bool add);
rmSetTriggerConditionParamInt(string paramName, int value, bool add);
rmSetTriggerConditionParamFloat(string paramName, float value, bool add);
rmSetTriggerConditionParamArmy(string paramName, int playerID, int armyID, bool add);
Refer to C:\...\Age of Empires III\trigger\typetest.xml for lists of available conditions and their parameters.
rmAddTriggerEffect(string effectType);
rmSetTriggerEffectParam(string paramName, string value, bool add);
rmSetTriggerEffectParamInt(string paramName, int value, bool add);
rmSetTriggerEffectParamFloat(string paramName, float value, bool add);
Refer to C:\...\Age of Empires III\trigger\typetest.xml for lists of available effects and their parameters.
rmSetTriggerEffectParamArmy(string paramName, int playerID, int armyID, bool add);
rmCreateArmy(int playerID, string armyName);
rmAddUnitsToArmy(int playerID, int armyID, int objectDefID);
Triggers that affect armies require that the armies be defined first.
rmSetVCFile(string filename);
You can set up alternate victory condition files for your RMS. This feature is fairly complex and should only be attempted by an advanced user.
How to insert triggers in your script:
Order:
- It is recommended to add all triggers at the end of the script since some triggers need parameters which were already defined and placed on the map. Add all triggers straight before the last "}" bracket in the xs script.
- First create ALL triggers you want to insert in your script, then switch to each trigger separately and insert the conditions, effects and its parameters. This is very important since you cannot fire a trigger you have not created before, and the map will not load.
Example setup:
// Triggers:
for (j=1; <=14) {
rmCreateTrigger("MyTrigger"+j);
}
/* above there are now 14 triggers created with the names "MyTrigger1", "MyTrigger2"..."MyTrigger14" */
rmSwitchToTrigger(rmTriggerID("MyTrigger1"));
for(i=1; <= cNumberNonGaiaPlayers){
rmAddTriggerEffect("Grant Resources");
rmSetTriggerEffectParamInt("PlayerID",i);
rmSetTriggerEffectParam("ResName","Food");
rmSetTriggerEffectParamInt("Amount",1000);
}
rmSetTriggerPriority(4);
rmSetTriggerActive(true);
rmSetTriggerRunImmediately(true);
rmSetTriggerLoop(false);
rmSwitchToTrigger(rmTriggerID("MyTrigger2"));
...
...
rmSwitchToTrigger(rmTriggerID( "MyTrigger14"));
...
DISCLAMER
Most of the content above was originally posted on Hyena Studios - AOE3 RMS Tutorial (archive.org) and last edited by user M0nTy_PyTh0n. (Version 0.93)
Have additional questions about modding? You can ask questions and talk with other mod creators in the following places: