Omni-bot WikiMain Page | About | Help | FAQ | Special pages | Log in

Category: ET
Printable version | Disclaimers | Privacy policy

Map Scripting Enemy Territory

From Omni-bot Wiki

ET Main Page Map Scripting Archives

Contents

Standard Format

All official map scripts share a common layout. Having a standard for map scripts has several benefits; ease of documentation, debugging, and implementation of scripted goals are among those benefits. A typical ET map script will consist of one Map table and two functions that are automatically called by Omni-Bot:

 global Map = 
 {
 };
 
 global OnMapLoad = function()
 {
 };
 
 global OnBotJoin = function( bot )
 {
 };

Using makegm will ensure that a map script is in a standard format.

Map Table

The Map Table has become an important part of an ET map script as some scripted goals rely on its existence. It also provides a 'safe' place to store map specific information. Typically it will consist of map variables, triggers / functions, and in some cases additional tables:

 global Map =
 {
     SomeGoal = "BUILD_some_construct",
     someVar = true,
     someTable =
     {
         someVar = false,
     },
 
     some_trigger = function(trigger)
     {
         print("some_trigger");
     },
 };

It is important to note that when you add to a table you use a comma and not a semi-colon. Calling functions or referencing variables within the example table is done like this:

 Map.someVar = false; //changes the value of someVar to false
 print(Map.SomeGoal); //will print BUILD_some_construct
 Map.someTable.someVar = true; //changes the value of someTable.someVar to true

The key thing to note is that you need to put Map. in front of whatever you want to call or reference within the Map table.

OnMapLoad

The OnMapLoad function is used to initialize settings for the map. It is automatically called by Omni-Bot whenever a map loads (i.e. /map_restart). Setting up triggers, goal availability, and goal bias' are the most common jobs performed by this function:

 global OnMapLoad = function()
 {
     OnTrigger( "Some Team did Something!", Map.some_trigger );
     SetAvailableMapGoals( TEAM.AXIS, false, Map.SomeGoal );
     SetGoalPriority( Map.SomeGoal, 1.1 );
 };

OnBotJoin

The OnBotJoin function is automatically called by Omni-Bot when a bot joins. Typical usage for OnBotJoin is for setting specific properties on the bot that you want to be map specific. View distance and breakable object distance are the two most commonly used:

 global OnBotJoin = function( bot )
 {
     bot.MaxViewDistance = 2500;
     bot.TargetBreakableDist = 150.0;
 };

Note that it is not necessary to loop through the BotTable every time this is called as this function is called each time a bot joins.

Triggers

A trigger is an event that is recognized by Omni-Bot in game. With map scripting, triggers can be set up to perform operations when a map event occurs. There are two steps to setting up triggers; defining the trigger and setting up the trigger function.

Triggers are most commonly defined in OnMapLoad using the OnTrigger function:

 global OnMapLoad = function()
 {
     OnTrigger("string", function);
 };

The "string" parameter is usually found using the wm_announce messages seen during the game. This must be matched exactly including capitalization, punctuation, and color codes (if any). To see the wm_announce message requires the waypointer to either play through the map and perform the objectives or look through the map script that is included inside a map's pk3 file.

If the wm_announce messages appear in non-standard color, the latter method is often more convenient. The map's native script (not to be confused with the Omni-bot map script) is usually the file <mapname>.script in the /maps/ folder inside the pk3 file. Open the pk3 file with some archive utility, e.g. IZArc.

Another method of finding the string parameter is using the command /bot debugtriggers. This command will output to console everytime a recognized event occurs. The syntax will be similar to:

 <---> Trigger: TagName: The Tank has been repaired! Action: announce Entity: 0x7016dd8c Activator: 0

The string just after TagName: is what the OnTrigger function will expect as the string parameter. For additional information about debugtriggers see the Omni-bot_Command_Reference#debugtriggers page. This method is required for maps that may not have wm_announce messages that correspond to recognized map events.

Once you've collected the triggers you need, the contents of the console can be written to a plain text file by using the command /condump mytextfile. The file will be located in the omnibot folder under the game installation folder. By copying the trigger names from that file instead of typing them, the risk of typing errors is greatly reduced.

The function parameter of the OnTrigger function is the name of a function that the waypointer creates for the particular trigger. These can be named anything the waypointer wants, but should be somewhat intuitive.

Once the string parameter has been identified and a function name has been determined, the trigger definition will look something like this:

 global OnMapLoad = function()
 {
     OnTrigger("The Tank has been repaired!", Map.tank_repaired );
 };

The last part of the setup is to create the trigger function that will contain code for the game to process each time the event occurs. In all official map scripts, this is done inside the Map table:

 global Map =
 {
     tank_repaired = function( trigger )
     {
         //things to do when this event occurs
         print("tank_repaired");
     },
 };

It is important to note is that the function is inside the map table and should have a comma outside the closing bracket and not a semi-colon. The print statement inside the trigger function is not necessary, but is a good way to test that the trigger is working. As an additional service to the users, you can comment these print statements out when you're done testing, so their console isn't flooded with information that doesn't mean much to them.

Supported Triggers

Most events in ET will fall into the following Omni-Bot recognized categories:

If you are unsure if the event you want to set up a trigger for falls into one of these categories, use /bot debugtriggers in game.

NOTE: For the returned trigger (i.e. documents returned) use /bot debugtriggers output for when the flag is returned by expiring (no player returns it). If the regular wm_announce message is used, the event that occurs when the flag expires will not be used. It is recommended to manually steal the flag, /kill and wait for them to be automatically returned. An example can be found in radar.gm. Most of the time it will be something like "Flag returned flag!"

Native Functions

This section consists of Omni-Bot functions specifically designed for use in map scripts.

ChangeSpawnPoint

 syntax: bot.ChangeSpawnPoint(int spawnptid);
 example: bot.ChangeSpawnPoint(1); 
   
 note: the number of the spawn point is map dependant and may require either searching for spawn selection configs or testing the numbers.

GetGameTimeLeft

 syntax: GetGameTimeLeft(); 
 returns: Time left in the game in seconds
 
 example: can be used in maps where you may want the bots to focus on major objectives if there isn't much time left. 

GetGameType

 syntax: GetGameType(); 
 returns: The current game type

GetReinforceTime

 syntax: bot.GetReinforceTime(); 
 returns: Time left before the bots next spawn
 
 example: can be used in maps where you may want to exec a command if the bot is close to a new respawn. 

MaxViewDistance

 syntax: bot.MaxViewDistance = <distance>;
 example: bot.MaxViewDistance = 2500;
 
 note: typically set in OnBotJoin as this sets the property individually

SetAvailableMapGoals

 syntax: SetAvailableMapGoals( Team, true / false, goalname );
 example: SetAvailableMapGoals( TEAM.AXIS, true, "MAP_FLAG_someflag" );
 example: SetAvailableMapGoals( TEAM.ALLIES, false, Map.Flag );
 example: SetAvailableMapGoals( TEAM.AXIS, false, "DEFEND.*" );
 
 note: the goalname parameter supports expressions
 note: this command is the simpler alternative to getting a goal, then setting the availabilty. it's not necessary to do something like this:
       somevar = GetGoal("SOMEGOAL")
       if (somevar)
       {
           somevar.SetAvailable( TEAM.ALLIES, true );
       }

SetGoalPriority

 syntax: SetGoalPriority( goalname, priority, team, class, <optional persistent> );
 example: SetGoalPriority( Map.Flag, 1.0, 0, 0 ); //all teams and all classes
 example: SetGoalPriority( "DEFUSE_somedyno.*", 0.0, TEAM.AXIS, CLASS.ENGINEER, true ); //the persistent parameter is used for dynamic goals that may not have been created yet 

SetMapGoalProperties

 syntax: SetMapGoalProperties( Goal, table )
 example: SetMapGoalProperties( "ATTACK_.*", {mincamptime=15, maxcamptime=30} ); 
 
 note: see OnMapLoad in goldrush.gm for example usage

TargetBreakableDist

 syntax: bot.TargetBreakableDist = <distance>;
 example: bot.TargetBreakableDist = 100; 
 
 note: typically set in OnBotJoin as this sets the property individually
 note: used to allow bots to target breakables like windows. should be set to a relatively low number.

Utility Functions

The functions listed in this section are custom functions created to support specific scenarios in game. They are located in ~/omni-bot/et/scripts and ~/omni-bot/global_scripts respectively.

ETUtilities

ET utility functions are located in the ~/omni-bot/et/scripts/et_utilities.gm file.

ETUtil.ChangeClass

 syntax: ETUtil.ChangeClass( team, originalclass, newclass, revert, maxbots )
 example: ETUtil.ChangeClass( TEAM.ALLIES, CLASS.SOLDIER, CLASS.COVERTOPS, false, 1 );
 
 usage: used in braundorf_b4 to change one bot to covert ops for satcheling the side gate. 
        Once satcheled, the function is called again with the revert flag set to true to 
        have the bot change back to it's original class.

ETUtil.ChangeSpawn

 syntax: ETUtil.ChangeSpawn(team, spawnpoint, numbots)
 usage: used to force bots to use a given spawn point. optionally limiting the number of bots to use the spawn

 example: ETUtil.ChangeSpawn(TEAM.AXIS, 3); //all axis will spawn at location 3
 example: ETUtil.ChangeSpawn(TEAM.ALLIES, 4, 3); //three allies will spawn at location 4

ETUtil.ClearMainGoals

 syntax: ETUtil.ClearMainGoals();
 usage: This function will deactivate all main goals for both teams.
 
 goals deactivated: AMMOCAB, CHECKPOINT, HEALTHCAB, BUILD, PLANT, FLAG, MOUNTMG42, MOVER  

ETUtil.ClearSecondaryGoals

 syntax: ETUtil.ClearSecondaryGoals();
 usage: This function will deactivate all secondary goals for both teams.
 
 goals deactivated: AMMO, HEALTH, ARTILLERY, MOBILEMG42, REPAIRMG42, PLANTMINE

ETUtil.CountClass

 syntax: ETUtil.CountClass( team, class )
 example: ETUtil.CountClass( TEAM.ALLIES, CLASS.ENGINEER ); 
 
 usage: can be used to determine if a team has enough of a critical class for the map

ETUtil.CountTeam

 syntax: ETUtil.CountTeam( team )
 example: ETUtil.CountClass( TEAM.ALLIES ); 
 
 usage: used to count the number of bots on a give team. used in maps like et_ice 
        in a conditional statement for setting max users attacking / defending.

ETUtil.DisableGoal

 syntax: ETUtil.DisableGoal(goalname, <optional true>);
 example: ETUtil.DisableGoal("FLAG_someflag"); 
 
 usage: disables the goal for both teams. the optional true parameter is used to disable all 
        goals except for ROUTE goals.

ETUtil.EnableGoal

 syntax: ETUtil.EnableGoal(goalname);
 example: ETUtil.EnableGoal("FLAG_someflag"); 
 
 usage: enables the goal for both teams.

ETUtil.LimitToClass

 syntax: ETUtil.LimitToClass(goalname, team, class1, class2, class3);
 usage: used to limit specific goals to a specific class or classes
 
 example: ETUtil.LimitToClass("CHECKPOINT.*", TEAM.ALLIES, CLASS.SOLDIER) //only soldiers on the allied team
 example: ETUtil.LimitToClass("CHECKPOINT.*", TEAM.ALLIES, CLASS.SOLDIER, CLASS.MEDIC) //only soldiers and medics

ETUtil.NoSnipe

 syntax: ETUtil.NoSnipe(bot);
 usage: covert ops bots will not choose a garand or k43
 
 note: this is typically called in OnBotJoin

ETUtil.RandomSpawn

 syntax: ETUtil.RandomSpawn(team, spawnpoint);
 usage: used to have bots randomly choose to spawn at the given spawnpoint

ETUtil.SelectWeapon

 syntax: ETUtil.SelectWeapon(bot, weapon);
 usage: the given bot will switch to the given weapon if it is the correct class for the weapon
 
 note: typically used in OnBotJoin to have soldiers choose a specific weapon
 example: ETUtil.SelectWeapon(bot, WEAPON.PANZERFAUST);

ETUtil.SetPrimaryGoals

 syntax: ETUtil.SetPrimaryGoals(priority);
 usage: used for setting priorities of common goals.
 
 note: this is typically called in OnMapLoad and effects the following goals (in order of priority):
       CAPPOINT FLAGRETURN PLANT CHECKPOINT FLAG

ETUtil.ShowActiveGoals

 syntax: ETUtil.ShowActiveGoals();
 usage: shows active goals for both teams
 
 note: should only be used for debugging

ETUtil.StopSniping

 syntax: ETUtil.StopSniping();
 usage: all bots currently using a mauser will switch to a different weapon
 
 note: this is typically called inside trigger functions

ETUtil.SwitchWeapon

 syntax: ETUtil.SwitchWeapon(weapon);
 usage: all qualifying bots will switch to the given weapon
 
 example: ETUtil.SwitchWeapon(WEAPON.PANZERFAUST); //all soldiers will switch to panzer
 note: typically used in trigger functions


Utilities

Utility functions are located in the ~/omni-bot/global_scripts/utilities.gm file.

Util.AddInvVehicle

 syntax: Util.AddInvVehicle( goalname )
 usage: adds a vehicle to the Map.InvVehicle table
        used for script goals in cases where the vehicle is invulnerable, but shows as "dead"


Util.AliveCount

 syntax: Util.AliveCount( team, class )
 usage: returns the number of bots alive on a team with a given class


Util.DisableGroup

 syntax: Util.DisableGroup(groupname, team);
 example: Util.DisableGroup( "somegroupname", TEAM.SOMETEAM );
 
 usage: used to disable a set of goals in the given group for a given team

Util.DistanceView

 syntax: Util.DistanceView(<optional off|0>);
 usage: /bot dist 
        /bot dist off
        /bot dist 0
 
 note: used for determining bot.MaxViewDistance settings. aim at a position as far as you can see and type /bot dist

Util.EnableGroup

 syntax: Util.EnableGroup(groupname, team);
 example: Util.EnableGroup( "somegroupname", TEAM.SOMETEAM );
   
 usage: used to enable a set of goals in the given group for a given team

Util.GetGroup

 syntax: Util.GetGroup(groupname);
 example: Util.GetGroup("somegroupname");
   
 usage: this function will return a table of goals belonging to the given group name

Util.OnTriggerPosition

 syntax: Util.OnTriggerPosition( goalname, wpname, tolerance, wpfunction )
 example: Util.OnTriggerPosition( Map.Mover_train1, "depotyard", 200.0, Map.tug_depotyard );
 
 note: used for setting up positional triggers for movers. 

Util.RemoveGoal

 syntax: Util.RemoveGoal( goalname );
 example: Util.RemoveGoal( "MOVER_truck" ); 
 
 note: this command will remove the goal from the map goal table

Util.SetGoalOffset

 syntax: Util.SetGoalOffset( x, y, z, GoalName );
 example: Util.SetGoalOffset( 0, 0, 30, "BUILD_construct" )
 
 usage: the x y and z parameters are added to the origin of the goal to move the location of where the bots will look for the goal.

Util.SetGoalPosition

 syntax: Util.SetGoalPosition( x, y, z, GoalName );
 example: Util.SetGoalPosition( 4534, 2168, -199, "BUILD_construct" )
 
 usage: used to give the goal a new origin. 
 note: using /devmap to load the map and issuing the /viewpos command in console will give your origin in the map

Util.SetGroup

 syntax: Util.SetGroup(goalname, groupname);
 example: Util.SetGroup("somegoalname", "somegroupname");
 
 usage: this function will add a given goal to a given groupname

Util.ShowGroup

 syntax: Util.ShowGroup(groupname);
 example: Util.ShowGroup("somegroupname");
 
 usage: this function will list all goals in the given group in the console.

Util.SetMaxUsersInProgress

 syntax: Util.SetMaxUsersInProgress( Users, GoalNames );
 example: Util.SetMaxUsersInProgress( 15, "CHECKPOINT.*" ); 
 
 usage: used to set the maximum number of bots going for a particular goal(s).

Util.SetPositionGoal

 syntax: Util.SetPositionGoal( goalname1, goalname2 );
 example: Util.SetPositionGoal( Map.Build_tank_construct, Map.Mover_tank );
 
 usage: sets the origin of one goal to match the origin of another. useful for centering construct goals on movers

Util.ShowGoalInfo

 syntax: Util.ShowGoalInfo(goalname);
 command: /bot sgi 'goalname'
 
 usage: used to print a goals current information in console including the goals health, status of the DEAD flag,
        and the goals position

Util.ShowGoalName

 syntax: Util.ShowGoalName(radius, showOffset);
 command: /bot sgn <radius> <optional true>
 
 usage: issue the command /bot sgn to find the goalname of any goals within 100 units. Optionally expand the radius and
        find your current offset from the goal with /bot sgn 500 true

Util.ShowGoalOffset

 syntax: Util.ShowGoalOffset(goalname);
 command: /bot sgo 'somegoalname'
 
 usage: used to determine a players current offset from a goal. the values given in console can be used for goals that 
        require positional offsets

Util.AddUsePoint

 syntax: Util.AddUsePoint(goalname, position);
 example: Util.AddUsePoint( "somegoalname", Vector3(123, 456, 789) );
 
 usage: used to add a Use Point for a goal at a given position. 

Util.AddUseWp

 syntax: Util.AddUseWp(goalname, waypointname);
 example: Util.AddUseWp( "somegoalname", "somewaypointname" );
 
 usage: used to add a Use Point for a goal at a given waypoints position.

Conditionals

Enemy Territory is a complex game type. Maps are not linear and events do not necessarily happen in a specific order. Conditional statements are necessary in some cases to ensure that availability of goals is consistent with the waypointers idea of a map flow. A conditional statement begins with the 'if' function. In script, it is used to check given paramaters before executing some code:

 if ( a == b )
 {
     //do something
 }

In this example it checks if something is equal to something else before executing any code in the following brackets. If something does not equal something else, anything inside the brackets will be ignored. This conditional can be extended to make something happen if the first conditional was not met with the 'else' commamd:

 if ( a == b )
 {
     //do something
 }
 else
 {
     //do something else
 }

And finally, this can be extended even further using the 'else if' command:

 if ( a == b )
 {
     //do something
 }
 else if ( a == c ) 
 {
     //do something else
 }
 else
 {
     //do something else
 }

Conditionals can get more complex by adding additional checks The following example checks if both are true before executing the code in the example:

 if ( a == b && c == d )
 {
     //do something
 }

If a check is dependant on one of many checks being true, the 'or' operator is used:

 if ( a == b || c == d )
 {
     //do something
 }

To test if something is true or false, the syntax used is:

 if ( !something )
 {
    //do something
 }

The apostrophe in front of the parameter checks if something is false while a != checks if something doesn't equal something else:

 if ( a != b )
 {
    a = b;
 }

Checking if a value is greater or lesser than another value is done as follows:

 if ( a > b || c < d )
 {
     //do something
 }

In ET maps where the map flow is not pre-determined, it is important to add conditionals to some triggers in which goals are activated. While the bots order of objective completion can be set by the waypointer, the waypointer can not predict when a human player may complete a particular objective. So if goals are activated with a specific order in mind and a human player activates a goal out of turn, you may have goals available to bots earlier or later than intended; potentialy breaking the gameplay.

Case Study

Scenario: Map is Fueldump and goals are being activated or deactivated based on the Main Bridge status. When the bridge is built, attack and defend goals are activated and when it is destroyed, goals are deactivated. To add to the complexity, some of the same goals are activated / deactivated based on the status of the footbridge.

The first thing that needs to be done is to create some variables for use in the conditional statements. Official map scripts add these variables to the Map table:

 global Map =
 {
     //conditional variables
     BridgeStatus = 0, //not built
     FootBridgeStatus = 0,
 };

The next step is to set these variables in the appropriate triggers:

 global Map =
 {
     //conditional variables
     BridgeStatus = 0, //not built
     FootBridgeStatus = 0,
 
     footbridge_Built = function( trigger )
     {
         Map.FootBridgeStatus = 1; //built
     },
 
     footbridge_Destroyed = function( trigger )
     {
         Map.FootBridgeStatus = 0; //not built
     },
 
     bridge_Built = function( trigger )
     {
         Map.BridgeStatus = 1; //built
     },
 
     bridge_Destroyed = function( trigger )
     {
         Map.BridgeStatus = 0; //not built
     },
 };

Now that we have status' updating correctly, conditional statements can be added to help ensure goals are active at the appropriate time:

 global Map =
 {
     //conditional variables
     BridgeStatus = 0, //not built
     FootBridgeStatus = 0,
 
     footbridge_Built = function( trigger )
     {
         Map.FootBridgeStatus = 1; //built
         SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Tunnel_Doors.*" );
     },
 
     footbridge_Destroyed = function( trigger )
     {
         Map.FootBridgeStatus = 0; //not built
 
         //if both bridges destroyed, shift the defense back
         if ( Map.BridgeStatus == 0 )
         {
             SetAvailableMapGoals( TEAM.ALLIES, false, "ATTACK_Tunnel_Doors.*" );
             SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Bridge_.*" );
         }
     },
 
     bridge_Built = function( trigger )
     {
         Map.BridgeStatus = 1; //built
         SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Tunnel_Doors.*" );
         SetAvailableMapGoals( TEAM.ALLIES, false, "ATTACK_Bridge_.*" );
     },
 
     bridge_Destroyed = function( trigger )
     {
         Map.BridgeStatus = 0; //not built
 
         //if both bridges destroyed, shift the defense back
         if ( Map.FootBridgeStatus == 0 )
         {
             SetAvailableMapGoals( TEAM.ALLIES, false, "ATTACK_Tunnel_Doors.*" );
             SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Bridge_.*" );
         }
     },
 };

All looks good at this point. At the beginning of the map, the allied bots will be shifting correctly based on both bridges status. There is a potential problem here though. What happens if someone builds or destroys a bridge after the tank is through the tunnel? The goals back by the bridge will be activated again. The solution is to pick a major event to check against and add that to our conditionals. In this case we will check the status of the Tunnel door before activating those goals:

 global Map =
 {
     //conditional variables
     BridgeStatus = 0, //not built
     FootBridgeStatus = 0,
     Tunnel_Doors = true, //doors intact
 
     tunneldoors_Destroyed = function( trigger )
     {
         Map.Tunnel_Doors = false;
     },
 
     footbridge_Built = function( trigger )
     {
         Map.FootBridgeStatus = 1; //built
         
         if ( Map.Tunnel_Doors )
         {
             SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Tunnel_Doors.*" );
         }
     },
 
     footbridge_Destroyed = function( trigger )
     {
         Map.FootBridgeStatus = 0; //not built
 
         //if both bridges destroyed and doors intact, shift the defense back
         if ( Map.BridgeStatus == 0 && Map.Tunnel_Doors )
         {
             SetAvailableMapGoals( TEAM.ALLIES, false, "ATTACK_Tunnel_Doors.*" );
             SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Bridge_.*" );
         }
     },
 
     bridge_Built = function( trigger )
     {
         Map.BridgeStatus = 1; //built
 
         if ( Map.Tunnel_Doors )
         {
             SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Tunnel_Doors.*" );
             SetAvailableMapGoals( TEAM.ALLIES, false, "ATTACK_Bridge_.*" );
         }
     },
 
     bridge_Destroyed = function( trigger )
     {
         Map.BridgeStatus = 0; //not built
 
         //if both bridges destroyed and doors intact, shift the defense back
         if ( Map.FootBridgeStatus == 0 && Map.Tunnel_Doors )
         {
             SetAvailableMapGoals( TEAM.ALLIES, false, "ATTACK_Tunnel_Doors.*" );
             SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_Bridge_.*" );
         }
     },
 };

For a complete example of conditional usage, look through any of the map scripts released with version 0.65.

Scripting Tools

makegm

makemapgm is a command that autogenerates a skeleton map script. Usage of this command will ensure a standard format and save time. Using the command is fairly straight forward:

Step 1: Load the map you want a script for
Step 2: Type /bot makegm in console. It will display a message if executed correctly
Step 3: Copy the mapname.gm file from ~/omni-bot/et/usr to ~/omni-bot/et/nav, Be sure to have backed up any mapname.gm file you may have been working on that exists in the nav folder.

The OnTriggers in OnMapLoad will need to be modified as makemap.gm does not find the information needed. Simply edit the "MISSING STRING" parameter of the OnTrigger function and the triggers should be working correctly.


Debugging Tools

debugbot

debugbot is a valuable tool to use if bots aren't behaving as expected. It will give information about the bots current goal.

 syntax: /bot debugbot all fpinfo
 or: /bot debugbot <bot-name> fpinfo

It is recommended to have only one or two bots connected when issuing this command with the all parameter as it will give debug output for each bot.

ScriptDebug

Script debugging is crucial as a high percentage of errors are syntax related. There are two ways to enable script debugging:

EnableScriptDebug(true); can be placed in et_autoexec.gm while /bot script_debug 1 will need to be executed in console each time the map loads. If an error in script occurs while script debugging is enabled, the error will be listed in console in red text with the line number of the error.

note: in the omnibot.log, script errors will be written whether script debugging is enabled or not.

GameMonkey interpreter

The GameMonkey download available at www.somedude.net/gamemonkey/ contains an interpreter for gm files (gme.exe) that can be used as a syntax checker. With this, you won't have to start the game only to find you forgot a closing bracket or a semicolon.

Ideally, use this with an editor that can run command line applications and capture their output, such as SciTE, PSPad or Notepad++.

print

print is a low level means of debugging a script. It can be used in cases where you want to test if a trigger is working correctly or if the map script has loaded:

 global OnMapLoad = function()
 {
     print("OnMapLoad");
 }

The print statement can also be used in-game via script_run if you want to inspect the value of a variable:
/bot script_run "print(variable)"

show_goals

 syntax: /bot show_goals <optional expression> <optional p>
 usage: the optional expression parameter can be used to display one or several goals. The optional p parameter is used to display any
        priorities that may have been set with the SetGoalPriority function.

show_goals can be useful to test whether or not goals are available when they are expected to be and that they have the expected bias setting. The output from show goals is similar to:

  HEALTHCAB_north_healthcabinet -> 0100 serial 2 priority 0.40
  ALLIES AXIS MEDIC 0.00
  HEALTHCAB_south_healthcabinet -> 0000 serial 5 priority 0.40
  ALLIES AXIS MEDIC 0.00

The number just to the right of the arrow represents teams and status. 1 means it's available for that team while 0 means it is unavailable. With the optional p parameter given, the output will include any priorities set for individual teams and / or classes.

show_goalroutes

 syntax: /bot show_goalroutes <optional>
 usage: used to list routes used for a give goal or goals

draw_goals

 syntax: /bot draw_goals [on|1|off|0] <optional>
 usage: the optional parameter can be used to display one or several goals.

Note: the optional parameter supports regular expressions. /bot draw_goals .*BUILD.* will draw BUILD goals.

This will draw the location of goals to your screen. Useful to see where bots "think" an object is located.

draw_goalroutes

 syntax: draw_goalroutes on/off <optional goal name expression> 
 usage: used to draw the given goal(s) routes

Retrieved from "http://www.omni-bot.com/wiki/index.php?title=Map_Scripting_Enemy_Territory"

This page has been accessed 4,283 times. This page was last modified 17:04, 25 May 2009.


Find

Browse
Main Page
Community portal
Current events
Recent changes
Random page
Help
Donations
Most Recent Blogs
Edit
View source
Editing help
This page
Discuss this page
Post a comment
Printable version
Context
Page history
What links here
Related changes
My pages
Log in / create account
Special pages
New pages
File list
Statistics
Bug reports
More...