FritzBot ET Creating Waypoints

From Bots-United Wiki

Jump to: navigation, search

This is the main reference for waypointing maps for FritzBot ET. For more advanced waypointing follow the category link at the bottom of the page to see the complete list of articles. For help on installing and running FritzBot ET see the main topic FritzBot ET.

Contents

[hide]

Creating Waypoints

A tutorial is coming soon. A lot of features are still in development, so a complete tutorial is not possible yet. In the meantime, there are two tools available to get you started:

The recommended steps for those of you that want to get started prior to a full tutorial are to first read the RTCW tutorial, then view the fundamental changes listed below. Once you have a basic understanding, Hobbit's waypoint tool is an excellent tool to use.

To help you use Denny's tutorial and understand the differences between the RTCW and ET versions of FritzBot, the new Fritzbot_ET_waypointing_tutorial provides a lesson plan that gives corrections and quiz questions for new ET waypointers.

For now, this article will be set up as a reference to all the commands needed for ET waypointing.


Goal Tracker

The Goal Tracker is a method that is used to help the bots to 'understand' a maps' progression. When certain events take place on a map, the Goal Tracker will be updated. When a round starts, the Goal Tracker is set to 0. This is important to understand when placing actions on a map because bots will only see actions as usable if they have the same "Goal Number" as the current Goal Tracker value. In the RTCW Tutorial, this is referred to as the action_group and is explained here. Keep in mind that in FritzBot ET, it's called action_goal (action_group is independent of the goal in ET).

The console command /goal_num displays the current goal tracker state.

Events that increase the goal tracker are:

  • Dynamite Objective being destroyed
  • Major Construction Being Built
  • Objective being stolen (i.e. docs or gold)

Events that decrease the goal tracker are:

  • Objective Returned

note: If more than one of the above objectives are in the same Goal Number, only the first one completed will increase the goal tracker

Actions that have the same Goal Number as the Goal Tracker are active. All other actions are not active.

Different from the RTCW version, FritzBot ET provides for a full environment to control the active state of all actions through the aiscript. Accordingly most ET waypoints only use the action_goal control for the goal 0 start of the round. See Fritzbot_Goal_Tracker for further discussion.

Node Basic Concepts

Nodes are placed in the maps to tell the bots that a certain part of the map is usable. By connecting nodes together, a grid can be created on a map that gives bots paths to their goals (actions).

The maximum number of nodes is 1024 (0-1023).

--Tips--

  • Nodes should be no more than 2.5 seconds apart
  • Limit the number of 90 degree turns in the pathing. Not many people move around a map taking 90 degree turns, so lets not make the bots do it.
  • Walk through the map in editor mode and see if there are any 'shortcuts' that are left unpathed.
  • Keep in mind that the bots can travel to the very edge of a node's radius, then move to the next radius. Use /node_drawradius 1 to see the radius. This is especially useful when pathing for narrow hallways or tight corners
  • One way paths should only be used when absolutely necessary (i.e. a jump down)

More about nodes can be read here. Keep in mind that the node_flags have been changed in ET while reading through it.

Node Properties

Each node has several properties. In editor mode /node_drawhud 1 will show the properties of the closest node to where you are standing.

Image:nodehud-con.jpgImage:nodehud-rad.jpg


The full command for adding a node is:

/node_add <flag> <radius> <entity> <team> <group>

That may be a bit much to type in a single command. Each property has a default value that can be edited with the waypoint tool or with additional commands.

Typically it's best to add a node to the map by just typing /node_add in the console. You can then chose to use the waypoint tool to edit the properties or use the following commands in the console:

/node_flag <nodeNumber> <flagNumber>       - sets the node flag
/node_radius <nodeNumber> <radius>         - sets the node radius
/node_ent <nodeNumber> <entity>            - sets the node entity (only used for spawn flags)
/node_team <nodeNumber> <team>             - sets the usability of the node to only one team (1 axis, 2 allies)
/node_group <nodeNumber> <group>           - sets the node group (leave at default)
/node_connect <nodeNumber> <nodeNumber>    - creates a one way path 
/node_disconnect <nodeNumber> <nodeNumber> - removes a one way path
/node_resetlinks <nodeNumber>              - removes all connects from a node (outgoing connections)
/node_move <nodeNumber>                    - moves the node to your current position
/node_autoconnect                          - creates a two-way path between the just-placed node and the previous node placed
/node_num                                  - identifies the node nearest to your position (apparently)

Node Flags

Hobbit's Waypoint Tool has all of the node flags available in pull-down menus, but for those that are interested in the variables, they are listed here:

-- NODE FLAG --	        -- FLAG NUMBER --	
NODE_INVALID		-1 <- a null node type (not valid!)
NODE_NORMAL		0 <- the default
NODE_LADDER_TOP	        1 <- node is at the top of a ladder
NODE_LADDER_BOTTOM	2 <- node is at the bottom of a ladder
NODE_SPAWNFLAG		3 <- node is next to a spawnflag
NODE_BUTTON		4 <- not used yet
NODE_JUMP		5 <- bots will jump between nodes with this flag set
NODE_LEAP	        6 <- a one-way jump - low health bots beware!
NODE_CONSTRUCTABLE	7 <- not used
NODE_WALK		9 <- bots will walk to this node

To edit a node flag in the editor mode, the console command is /node_flag <nodeNumber> <nodeFlag>

Example: Let's say you placed node number 5 at the bottom of a ladder. You would then type in console /node_flag 5 2.

It's recommended to just make a note of the node number and flag it requires so you can add them with Hobbit's Waypoint Tool. The tool will also provide validation for the nodes.

Below is a listing of each node flag with some notes on how / when to use them.

node_invalid

/node_flag <nodeNumber> -1

Used to deactivate a node. only use this if you have an extra node on the map that you can't place anywhere else.

node_normal

/node_flag <nodeNumber> 0

Default setting for nodes. nothing special about this node, treat it normally.

node_ladder_top

/node_flag <nodeNumber> 1

Used at the top of ladders. this gives the bots a hint on how to handle navigating down ladders. It causes them to slow down and walk to this node as well. IF you don't want them walking a long distance to a top ladder node, connect it to a normal node close by.

node_ladder_bottom

/node_flag <nodeNumber> 2

Used at the bottom of ladders. this gives the bots a hint on how to handle navigating up a ladder and what to do if they get stuck on one.

node_flag

/node_flag <nodeNumber> 3

Used for the node closest to a spawnflag. this gives a hint to the bot that a flag is nearby.

-IMPORTANT- when setting a node_flag to 3, the nodes' entity also needs to be set to the entity number of the flag /node_ent <nodeNumber> <entity>

node_button

/node_flag <nodeNumber> 4

-NOT IMPLEMENTED YET-

node_jump

/node_flag <nodeNumber> 5

Used to make the bots jump across gaps. two successive nodes need to be set with node_flag 5 for it to work. It should not be used on a node that is the "closenode" of an action (see note 2 of the closenode property described under #Action Properties below)

node_leap

/node_flag <nodeNumber> 6

This flag is used to warn bots that a dangerous jump down is ahead. It should have been named "node_DON'T LEAP" because it is primarily intended for wounded bots. Bots with less than 30% health will not make the jump and will look for a way around it. Use this flag carefully because if there is no suitable detour, they will freeze in place and go no further, wherever they are. Be sure to test the path with a wounded bot to make sure that this doesn't happen. The flag must be set for the nodes at the each end of the jump. It should not be used on a node that is the "closenode" of an action (see note 2 of the closenode property described under #Action Properties below), and it should be avoided on nodes connecting crossing paths because it affects movement on each.

node_constructable

/node_flag <nodeNumber> 7

-NOT IMPLEMENTED YET-

node_walk

/node_flag <nodeNumber> 9

Used to make the bots walk to a node. As they approach a node marked as a walk node, they will walk to it. Used for some areas you wouldn't want them to jump off, like narrow ledges.

Action Basic Concepts

Actions are in place to give the bots something to do. Without them, they will stand in place and let you know they have nothing to do. More about actions can be read in the RTCW tutorial here. Keep in mind while reading that the action types have changed / expanded for ET.

The maximum number of actions is 256 (0-255).

--Tips--

  • Place non-objective actions around a map in positions that human players would play them
  • Use a radius of 45 or lower for most actions. Any radius larger than 45 and you may get more than one bot "sharing" the same action
  • Start with the objective actions and test them
  • Add actions in one phase of the map at a time, then test
  • If you're testing your waypoints and some bots start spamming "no goals", you can type /bot_pause 1 to stop the spamming and begin troubleshooting.
  • If you forgot where you placed an action you can turn off the display of other actionTypes with /node_drawonly <actionType> to speed up the search.

Action Properties

Each action has several properties. In editor mode, /node_drawhud 2 will show the action properties of the closest action to where you're standing.

Image:actionhud-rad.jpg

The full command for adding an action is:

/action_add <axisAction> <alliedAction> <radius> <entity> <active> <group> <goal> <class> <prone> <behind> <behindGoal>

As you can see, that's a lot to type in a single command. Each variable has a default value and can be set with additional commands. So typically when adding an action, you should just set the axis action and allied action. You can then use the Waypoint Tool to edit the rest of the properties.

/action_add -1 0 is an example of adding an allied camp action. The rest of the actions' properties will be set to the default values. If you would like to edit the properties in the editor rather than with the tool, below is a list of commands:

/action_axis <actionNumber> <actionType>      - sets the axis action type 
/action_allies <actionNumber> <actionType>    - sets the allied action type 
/action_radius <actionNumber> <radius>        - sets the radius 
/action_ent <actionNumber> <entityNumber>     - sets the entity number 
/action_active <actionNumber> <foreverNumber> - sets whether the action number should be active forever (1 yes, 0 no)
                                                See Fritzbot_Goal_Tracker for further discussion.
/action_group <actionNumber> <groupNumber>    - sets the group number 
/action_goal <actionNumber> <goalNumber>      - sets the goal number 
/action_class <actionNumber> <classesNumber>  - sets which classes can use this action
/action_prone <actionNumber> <proneNumber>    - sets whether or not the bot should prone when using this action (1 yes, 0 no)
/action_links <actionNumber> <linkedActions>  - links actions together(like a camp action linked to an aim action)
/action_closenode <actionNumber> <NodeNumber> - specifies the closest path node to the action (helps the bots find it)
                                                Note 1:  The closenode is automatically updated when you move the action, 
                                                         but it may not be correct if you later move the node
                                                Note 2:  Do not use a specially-flagged path node like a jump or a ladder 
                                                         as the closenode for an action because the node's special-handling
                                                         code can interfere with that of the action.
                                                Note 3: It is best to use a node that is available to both teams for any
                                                         closenode even for actions that are only defined for the same team
                                                         as the node. (You might forget later, add an opposing team action
                                                         and wonder why some bot zombies occasionally.)
/action_move <actionNumber>                   - moves the action to your current position
/action_num                                   - identifies the action nearest to your position (apparently) 

* action_behind and action_behindGoal aren't implemented at this time.

Action Types

Hobbit's Waypoint Tool has all of the action types available in pull-down menus and does validation, but for those that are interested in the variables, they are listed here. Actions that are suitable for use in the aiscript are marked with an asterisk.

-- ACTION TYPE --    		-- ACTION NUMBER --
ACTION_INVALID			-1 <- the default, a NULL action.
ACTION_CAMP			 0 <- short-term camping goal
ACTION_MG42			 1 <- marker for a fixed mg42
*ACTION_CONSTRUCT_MINOR	         2 <- marker for minor things: MG42s, towers
ACTION_AIM			 3 <- tells the bot where to look while camping
*ACTION_DYNAMITE		 4 <- dynamite non-constructible objects
*ACTION_DEFUSE			 5 <- defuse dynamite
*ACTION_SPAWNFLAG		 6 <- marks a spawn flag
ACTION_DELIVER			 7 <- marks the delivery point for stolen objects
*ACTION_STEAL			 8 <- marks the location of an object to steal
ACTION_DEFEND			 9 <- long term place to camp
ACTION_AIRCAN			10 <- airstrike hint
ACTION_ARTY			11 <- artillery hint (not yet implemented)
ACTION_ROAM			12 <- patrol location
ACTION_SNIPE			13 <- sniper camp for coverts
ACTION_PANZER			14 <- panzer camp for soldiers
ACTION_NADE			15 <- grenade goal for barriers, etc. (not yet implemented)
ACTION_ENGCAMP			16 <- camp for engineers (for dual-objective maps only)
ACTION_ALTROAM			17 <- route destination
ACTION_MG42CAMP		        18 <- fixed mg42-camp goal, doubles as a mg42 marker
*ACTION_CONSTRUCT_MAJOR	        19 <- MAJOR construction goals, like bridges, water pumps
ACTION_TANK			20 <- for tanks (not yet implemented)
ACTION_TRAIN			21 <- railgun train (not yet implemented)
*ACTION_CMDPOST		        22 <- command post
ACTION_SMOKECAN		        23 <- smoke-can hint for coverts
ACTION_MINEPLANT		24 <- area to plant mines
ACTION_MINEHUNT		        25 <- area to spot mines
ACTION_SUBVERSION		26 <- area to sneak into (not yet implemented)
ACTION_SATCHEL			27 <- covert's satchel goal
ACTION_MOBILEMG42_CAMP		28 <- camp for mobile mg42 soldiers
ACTION_BUTTON			29 <- button or lever a bot needs to use (not yet implemented)
ACTION_UNUSED                   30 <- reserved
ACTION_UNUSED                   31 <- reserved
*ACTION_PLANT_CONSTRUCT         32 <- dynamite a constructible object
*ACTION_EVENT_EXPIRE            33 <- catches entities leaving the game
*ACTION_EVENT_EXPLODE           34 <- catches walls or doors blowing up

The action type helps determine the bot behavior both within the action radius and in the path leading to the action. Some actions are just for aiscript testing (expire, explode...) and the bot ignores them. Others only affect the bot if it happens to pass a certain closenode (minehunt, smokecan, aircan, action_mg42). But most of the action types the bot is actively drawn to, navigating to the node of the action's closenode property. Once there in most cases the bot will seek out the action node (exceptions: roams and alt-roams the bot need not seek to enter the action radius). And once the bot is touching or inside the action radius, if the action requires a direction then the bot turns to face one of the linked aim actions.

action_invalid

/action_<team> <actionNumber> -1

This is the default setting for action types. Using the /action_add command will add an action, but because both teams' action types default to -1, it will be invisible in the editor until you specify one of the team-specific actions.

action_camp

/action_<team> <actionNumber> 0

A short-term camping goal. Set the entity number of a camp action to 1 to cause the bot to remain standing instead of kneeling. Useful for snipers standing behind walls.

REQUIRES: a link to an aim action /action_links <actionNumber> <aimAction>

action_mg42

/action_<team> <actionNumber> 1

A marker for a fixed mg42. Use when you want a bot to only use the mg42 when it is in the area and spots an enemy. This is not a camp action.

REQUIRES: the entity number of the mg42 (misc_mg42) to be defined with /action_ent <actionNumber> <entity>

To get the bot to be in the area consider adding a roam action nearby.

action_construct_minor

/action_<team> <actionNumber> 2

A construct action for minor constructions (ladders, barriers, fixed mg42 nests, etc) that are not priority objectives.

REQUIRES: the entity number of the construct (trigger_obj_info on the materials) /action_ent <actionNumber> <entity>

action_aim

/action_<team> <actionNumber> 3

Tells the bot where to look while camping. This is what you will use for /action_links on the actions that require it. The bot will detect any un-disguised enemy in its FOV (field of view) centered on the aim action, so the position of the aim action is not too critical. You can use multiple aim actions for a single camp and the bot will randomly rotate between all of them.

In order for an aim action to be valid, it needs to be set for the correct team and be "active" in the same goal_num of the actions that are linked to it.

To be safe, you can set the goal number (/action_goal <actionNum> <goal> 0 and make it active forever (/action_active <actionNumber> 1). A simple waypointing technique is to define a few aim points in the open areas between the two teams, then re-use them for all camps in the area (that can see them) of either team.

action_dynamite

/action_<team> <actionNumber> 4

A dynamite action for non-constructible objects.

REQUIRES: the entity number of the dynamiteable (trigger_obj_info) /action_ent <actionNumber> <entity>

If used on an entity that targets a func_constructible (even if you can't re-construct it) it will need the aiscript to disable it when completed.

action_defuse

/action_<team> <actionNumber> 5

A defuse action. Typically this is combined with the dynamite action, but set for the opposite team. /action_add 5 4 is an example of adding an action with both dynamite and defuse goals (axis defuse, allies plant)

REQUIRES: the entity number of the dynamiteable (trigger_obj_info) /action_ent <actionNumber> <entity>

action_spawnflag

/action_<team> <actionNumber> 6

A spawnflag action.

REQUIRES: the entity of the spawnflag (team_WOLF_checkpoint)

See the node_flag section about additional requirements of setting up a spawnflag correctly.

action_deliver

/action_<team> <actionNumber> 7

Tells the bot where to take documents /gold /key /etc. Bug Note: to ensure delivery, the deliver action should be on a second navigation node that is within the area a delivery can take place. A bug in FritzBot Et can leave a bot carrying the stolen object at the navigation node that precedes the node that has the deliver action. By putting 2 navigation nodes inside the area for delivery and placing the action on the second node in the path, this occasional bug is avoided. This bug is in addition to the goalnum issue in aiscripts on steal action tests.

action_steal

/action_<team> <actionNumber> 8

A steal action for documents /gold /key /etc

REQUIRES: the entity of the object to be stolen (team_CTF_blueflag or team_CTF_redflag)

action_defend

/action_<team> <actionNumber> 9

A longer-term camp action. Set the entity number to 1 to cause the bot to defend in a standing position.

REQUIRES: a link to an aim action /action_links <actionNumber> <aimAction>

action_aircan

/action_<team> <actionNumber> 10

An airstrike hint. This is a secondary goal; meaning that if a field op passes through the radius of this action with a full charge-bar, it will toss an airstrike in the direction of the center of the action.

Use sparingly if at all, field op bots will use aircans when fighting without this hint. For more info see Tips_on_Good_AirCan_Action_Placement.

action_arty

/action_<team> <actionNumber> 11

NOT IMPLEMENTED YET

action_roam

/action_<team> <actionNumber> 12

An action used to make the bots patrol a certain area. They will go to the roam action, then immediately move on to the next goal (action).

action_snipe

/action_<team> <actionNumber> 13

A specialized camp action for covert ops with scoped weapons. Covert ops with scoped weapons will prefer to use this while other classes will ignore it.

REQUIRES: a link to an aim action /action_links <actionNumber> <aimAction>

Set the entity number of a snipe action to 1 to cause the bot to remain standing instead of kneeling. Useful for snipers standing behind walls.

Note: it's best to set up at least two of these in each goal_num you want them in. The reason for this is because the bots by default do not like to choose the same action twice in a row.

action_panzer

/action_<team> <actionNumber> 14

A specialized camp action for a soldier with a panzerfaust. Soldiers with panzerfausts will prefer to use this while other classes will ignore it.

REQUIRES: a link to an aim action /action_links <actionNumber> <aimAction>

Note: it's best to set up at least two of these in each goal_num you want them in. The reason for this is because the bots by default do not like to choose the same action twice in a row.

action_nade

/action_<team> <actionNumber> 15

NOT IMPLEMENTED YET

action_engcamp

/action_<team> <actionNumber> 16

Intended for use only in dual_objective maps with dynamite goals as the main objectives. By default, the engineers number one priority will be to plant dynamite. This action has an equal priority to dynamite actions, so they will randomly choose to defend their own objective.

Advanced waypointers may chose to use these camps carefully in other styles of maps on the following considerations;

  • Used for the defending team,
  • Only active when there are few engineer tasks and none of critical priority elsewhere in the map,
  • Placement is such as to defend a high priority target,
  • The number of engineers playing exceeds the number of active engineer camps (typically just 1 engineer camp).
action_altroam

/action_<team> <actionNumber> 17

This is used for the route system and will be described in more detail in that section.

action_mg42camp

/action_<team> <actionNumber> 18

A camp action for fixed mg42's.

REQUIRES: the entity number of the mg42 (misc_mg42) to be defined with /action_ent <actionNumber> <entity>

Note: this does not require an aim action

action_construct_major

/action_<team> <actionNumber> 19

A construct action for major constructions (bridges, ramps, etc)

REQUIRES: the entity number of the construct (trigger_obj_info on the materials) /action_ent <actionNumber> <entity>

action_tank

/action_<team> <actionNumber> 20

NOT IMPLEMENTED YET (See the aiscript section re: vehicle related commands).

action_train

/action_<team> <actionNumber> 21

NOT IMPLEMENTED YET. See FAQ.

action_cmdpost

/action_<team> <actionNumber> 22

An action for command posts

REQUIRES: the entity number of the command post(trigger_obj_info) /action_ent <actionNumber> <entity>

note: for neutral command posts, covert ops will know when they need to satchel them. For team-specific command posts, a satchel action will be required if you want them to destroy it.

action_smokecan

/action_<team> <actionNumber> 23

A smoke-can hint for covert ops. This is a secondary goal, meaning that if a covert op passes through the radius of this action with a full chargebar, it will toss the smoke can in the direction of the center of the action.

action_mineplant

/action_<team> <actionNumber> 24

A place for engineers to plant mines

REQUIRES: the action_ent on the mine plant actions is used to tell them how many mines to plant at the actions' radius. The ent shouldn't be set to more than 3 for this, and typically it's best to set it to 2. No more than 10 mine-plant actions can be active at once or the game will crash.

action_minehunt

/action_<team> <actionNumber> 25

A hint for covert ops to look for mines at a specific location

REQUIRES: a link to an aim action /action_links <actionNumber> <aimAction>

Note: covert ops by default will randomly look for mines, so this action isn't absolutely needed for them to find them. The higher the skill level setting is for the bots, the better they are at spotting them on their own (independent of this action).

Suggested use is to put an aim action in a normally mined area, and place the minehunt action in different distant area where covert ops may pass.

action_subversion

/action_<team> <actionNumber> 26

NOT IMPLEMENTED YET

action_satchel

/action_<team> <actionNumber> 27

A satchel action for coverts to destroy minor constructs or command posts.

REQUIRES: the entity number of the construct (trigger_obj_info on the materials) /action_ent <actionNumber> <entity>

action_mobilemg42_camp

/action_<team> <actionNumber> 28

A specialized camp action for soldiers with a mobile mg42. Soldiers with a mobile mg42 will prefer to use this while other classes will ignore it.

REQUIRES: a link to an aim action /action_links <actionNumber> <aimAction>

Note: it's best to set up at least two of these in each goal_num you want them in. The reason for this is because the bots by default do not like to choose the same action twice in a row.

action_button

/action_<team> <actionNumber> 29

NOT IMPLEMENTED YET. See FritzBot_Buttons_And_Levers.

New with Fritz ET Ver. 0.70

action_unused

/action_<team> <actionNumber> 30

RESERVED FOR FUTURE USE

action_unused

/action_<team> <actionNumber> 31

RESERVED FOR FUTURE USE

action_plant_construct

/action_<team> <actionNumber> 32

This is a dynamite plant goal for constructible objects. This action can also be used for defusing dynamite at constructs. Set action_prone to 1 to make it a priority defuse action.

REQUIRES: the entity number of the construct (trigger_obj_info on the materials) /action_ent <actionNumber> <entity>

On multi-stage constructs this action is ignored by bots if the construct is not at built final stage.

action_event_expire

/action_<team> <actionNumber> 33

Use this to catch certain entities leaving the game (like the tank barriers on goldrush).

REQUIRES: the entity number of the barrier (trigger_obj_info on the materials) /action_ent <actionNumber> <entity>

action_event_explode

/action_<team> <actionNumber> 34

Use this to catch objects blowing up (like the doors on goldrush or the walls of fueldump).

REQUIRES: the entity number of the object (func_explosive) /action_ent <actionNumber> <entity>

Can often be used instead of the testing the dynamite plant action for aiscript purposes (assuming a suitable func_explosive exists).

Action Groups

/action_group <actionNumber> <group>

Action grouping is extremely useful for managing actions in the aiscript. It's really important to keep track of the actions you have in a particular group, and what the group is used for. At the bottom of the Oasis.aiscript, you will see an example of one way to keep track of the groups:

//ACTION GROUP DEFINITIONS
// Group 1 - Allied Actions if they own flag and Old City Water Pump isn't constructed
// includes actions: 35, 37, 38, 39

*Tip: using the command /action_group_info will list all the actions in a particular group. For instance, /action_group_info 1 will list all actions in group 1 (in console).

So using this example, further up in the Oasis script, you will see how we can manipulate all 4 of these actions with a single command:

action 4 // Old City Wall
{
 ...snip...
 //deactivate the allied actions in the old city
 deactivateAction_Group 1
 ...snip...
}

Listing the action groups at the bottom of the script is not necessary, but it's good to have for a reference. If you write up a separate description of the sequence of game strategy you used, you can copy the listing to it. Creating a strategy and defining the action groups beforehand can help you organize your thoughts and limit the amount of re-editing and testing. Since in FritzBot ET you are free to use any valid action group numbers in any order do not be afraid to spread you initial plan over the whole range of numbers. At any stage of the game you can conceivably need 2 or 3 groups (ex. axis only actions, allied only actions, and other actions). If later on you don't need a planned-for group number it can be skipped.

The default action group is zero, so actions that are activated individually in the aiscript will normally (unless you set them otherwise) be group 0. For that reason we do not normally activate/deactivate group 0 in the aiscript. Group 0 may also be used for actions that remain active for the entire round (ex. most aim-only actions, explode actions, expire actions...). The latter always-active actions are normally activated at the start of the round by their goal num 0 setting .

Action Classes

Action classes are used in some cases to limit actions to a certain class or classes.

/action_class <actionNumber> <bitFlag>

The bitFlag number for this is determined by using the following table:

0 - all classes
1 - soldiers 
2 - medics
4 - engineers
8 - field ops
16 - covert ops

Example: Lets say we wanted action number 9 to only be used by field ops, engineers, and medics. To do this, we look at the table above and add all the classes numbers together (8 field ops + 4 engineers + 2 medics = 14).

So /action_class 9 14 will set action 9 as only useable by field ops, engineers, and medics


Routes

By default, bots will travel to their goals using the shortest path. The route system gives a waypointer the option to specify alternate routes for the bots to take. A full description of routing can be found in The Route System.

Each route has several properties. In editor mode /node_drawhud 3 will show the properties of the closest route to where you are standing.

Image:Route_HUDrad.jpg

The command for adding a route is: /route_add <radius> <team>

The full command for adding a route: NOTE: the previously documented form for this command /route_add <actions 1-6> <radius> <pathactions 1-6> <team> DOES NOT seem to work !

The maximum number of routes in FritzBot ET is 64 (0-63).

In FritzBot ET, any action can be routed to. So, one fundamental change to the route system is the number of route_actions. In RTCW, you could only specify one action per route node. In ET, you can specify up to 6.

Route properties:

/route_actions <routeNumber> <action1> <action2>....<action6>       - sets the actions for the route
/route_radius <routeNumber> <radius>                                - sets the route's radius
/route_pathactions <routeNumber> <altRoam1> <altRoam2>...<altRoam6> - links the alt_roam actions to the route
/route_team <routeNumber> <team>                                    - sets route's team. 1 = axis, 2 = allies. Team is required
/route_move <routeNumber>                                           - moves the route to your current position

AI Scripts

AI Scripts are used to control the gameplay beyond what the Goal Tracker does. You can read more about them in the RTCW tutorial here. When reading that page keep in mind that in the ET version, a lot of things have been added. Hobbit's waypoint tool can be used when creating AI scripts for FritzBot ET. Read about how it works here. The aiscript can be edited in a text editor too if you prefer; name the file <mapname>.aiscript and place it in ~/fritzbot/bots/scripts. ( or ~/fritzbot-dev/bots/scripts if using the dev mod folder ) Place the header info at the top of the file and be sure to have an end-of-file code (#EOF) at the bottom. If you're just starting to waypoint a new map, that's all that's necessary. You can add action tests to it as the need arises.

The header has changed in FritzBot ET and needs to be at the top of every aiscript in this exact order, with the appropriate value for each parameter. The last two parameters can be omitted if the map has no vehicles.

bot_SightDist <dist>			// How far the highest skill bot can see on this map (2000 - 3000 normally)
spawnflag_is_priority  <num>		// Should bots focus on spawnflags? (0 = No, 1 = Yes)
cmdpost_is_priority  <num>		// Are cmdposts critical on this map? (0 = No, 1 = Yes)
construct_is_priority  <num>		// Should engs focus more on constructibles (0 = No, 1 = Yes)
map_has_vehicle  <num>			// 0 = No, 1 = Tank/Truck, 2 = Train
vehicle_entity_number <ent>		// Vehicle "script_mover" entity num
vehicle_team_owner <num>		// 1 = Axis, 2 = Allies

Below the header are action tests. Action tests are 'triggers' that are called after an event on the particular action occurs during gameplay. The basic setup for an action test is:

 action x // the action (x = the number of the action)
 {
   ..keywords go here..
 }

A simple example of how it works is as follows. Say we have action 1 as a dynamite action at a wall. And after the wall is destroyed, we want the bots to be able to go through it by connecting nodes 5 and 6:

 action 1 // the wall
 {
   node_connect 5 6 true //true tells it to create a 2 way path
 }

The script system is used to control the bot responses to certain events in the map beyond what the Goal Tracker does. Expanding on our example, lets say we want the bots to assist / defend our wall plant and then when the wall is destroyed, have them move through to the next set of goals. Action Group 1 will be the assist / defend wall plant actions for non-engineers and Action Group 2 will be the actions we want to make available after the wall is destroyed:

 action 1 // the wall
 {
   node_connect 5 6 true // create a 2 way path
   deactivateAction_Group 1 // deactivate the action group we set up for the wall plant assist / defend
   activateAction_Group 2 // activate the actions on the other side of the wall that was just destroyed
 }

There are some actions / events in a map that will require conditional statements. An example is barrier constructs. If a barrier is constructed, we will want to make sure nodes are disconnected so the bots don't think that they can go through them. And when the barrier is destroyed, we want to make sure the nodes are connected:

 action 2 // a barrier construct
 {
   if_construct_built_true 2 // the conditional statement
       node_disconnect 7 8 true // what to do if the conditional statement is met
   if_construct_built_false 2
       node_connect 7 8 true //barrier isn't built, connect the nodes
 }

Not all events trigger the associated action test aiscript block, just the important events. For example construct actions that are not completed but which decay or stop at an intermediate stage (i.e. multi-stage constructs like tank bridge in Fueldump) do not trigger the aiscript for these middle events. But damaging a multi-stage construct will trigger the aiscript. For an example on how you can trigger the aiscript for a non-supported event see Making_Bots_Respond_To_Dynamite_Planted_Events.


There is a limit to the number of action tests that an aiscript file can have. (Empirically it seems to be 16 in rev. 0.70B final (The Keyword Fix Beta 0.70C allows a limit of 32 action tests).)


An important thing to note is that an action that is disabled so that bots do not pursue it, can still in some circumstances trigger the associated action test. This 'feature' is useful when creating fake entities like func_constructs in the map script to communicate game states to the aiscript. The action added to the waypoints for such fake entities are left disabled to prevent the bots from treating them as real. In tests; major and minor construct actions (2 and 19) and spawn flag capture actions (6) do trigger their action tests in the aiscript even when not enabled. To prevent unwanted effects add additional conditions to the if... statements in those action test as needed. When the action will no longer need bot support for the remainder of the match it can be killed preventing any calls to the associated aiscript action test.

Keywords

Keywords fall into 2 categories; conditionals and regular. Regular keywords can be used in the action tests at any time. Conditionals require a regular keyword to be on the very next line. The following are all of the keywords available: The maximum number of keywords allowed in an aiscript is 256.

node_connect

node_connect <node1> <node2> <true / false>

used to connect nodes after an action occurs. requires true or false at the end. true means create a 2 way connection between the nodes, and false means create a one way connection between the nodes

action 1 // test action
{
 node_connect 1 2 true //create a two way connection
 node_connect 3 4 false //create a one way connection
}
node_disconnect

node_disconnect <node1> <node2> <true / false>

used to disconnect nodes after an action occurs. requires true or false at the end. true means disconnect a 2-way connection between the nodes, and false means disconnect a one-way connection between the nodes

action 1 // test action
{
 node_disconnect 1 2 true //disconnect a two-way connection
 node_disconnect 3 4 false //disconnect a one-way connection
}
openNodeGrpToTeam

openNodeGrpToTeam <node_group> <axis / allies>

A rarely needed way to change the team settings on all the nodes in a specific node_group (group #1 or higher). For example if a map dynamite objective permanently opens what was a team door (example Bremen_b2) then the waypointer may use a node_connect that connects through the door bypassing the team specific node. Alternately the team specific node can be modified into a node for both teams. A limitation to openNodeGrpToTeam is that effectively it can only be used once for any node group. And unlike node_connect/disconnect, it can only add a team, it can't remove a team from a group of nodes. This command is mostly used where there are too many nodes to handle with just node-connects. It may also help in cases where nodes are specially placed say for a path that only becomes available after an objective is exploded and bots should ignore these nodes until then.

activateAction

activateAction <actionNumber>

Sets the actions goal number to match the goal tracker; activates it.

action 1 // test action
{
 activateAction 2 // activate action number 2 after action 1 occurs 
}
deactivateAction

deactivateAction <actionNumber>

Sets the actions goal number to -1; deactivates it.

action 1 // test action
{
 deactivateAction 2 // deactivate action number 2 after action 1 occurs 
}
activateAction_Group

activateAction_Group <groupNumber>

Sets the goal number of all actions in a group to match the goal tracker; activates them.

action 1 // test action
{
 activateAction_Group 1 // activate action group number 1 after action 1 occurs 
}
deactivateAction_Group

deactivateAction_Group <groupNumber>

Sets the goal number of all actions in a group to -1; deactivates them.

action 1 // test action
{
 deactivateAction_Group 1 // deactivate action group number 1 after action 1 occurs 
}
resetNodeFlag

resetNodeFlag <nodeNumber> <nodeFlag>

used to reset a nodes flag after an event occurs. Most commonly used for spawn flag nodes when the spawn flag disappears after an event. An example of this is on Oasis; when the Old City wall is destroyed, the spawn flag is removed from the game.

action 1 // test action
{
 resetNodeFlag 1 0 //set the node back to normal because the spawn flag is removed after this event occurs
}
if_obj_home_false

if_obj_home_false <actionNum>

used for when the object (documents, gold, parts, key etc.) is stolen. This is a conditional test and requires a regular keyword to be on the next line.

action 1 // a steal action
{
 if_obj_home_false 1 //the action number here must be set to the steal actions number
     activateAction_Group 3 // activate actions near the deliver action
 if_obj_home_false 1 //you can't have 2 regular keywords after a conditional statement
     deactivateAction_Group 2 // deactivate the action group we had set up for defending the objective
}
if_obj_home_true

if_obj_home_true <actionNum>

used for when the object (documents, gold, parts, key etc.) is recovered. This is a conditional test and requires a regular keyword to be on the next line.

action 1 // a steal action
{
 if_obj_home_true 1 //the action number here must be set to the steal actions number
     deactivateAction_Group 3 // deactivate actions near the deliver action
 if_obj_home_true 1 //you can't have 2 regular keywords after a conditional statement
     activateAction_Group 2 // activate the action group we have set up for defending the objective
}

A special case for maps that have concurrent major objectives when the steal action is active will use the test below to ensure that the steal action remains active until captured. This prevents a situation where a change in the goal tracker can disable the steal action when it is recovered.

action 1 // a steal action
{
 if_obj_home_true 1 //the action number here must be set to the steal actions number
     activateAction 1 // re-activate this same steal action to ensure it is in sync with changes in the goaltracker
. . .
}
if_construct_built_false

if_construct_built_false <action_number>

used to manipulate nodes and / or actions based on the status of the construct.

 action 2 // a barrier construct
 {
   if_construct_built_false 2 //the action number here must be set to the constructs action number
       node_connect 7 8 true //barrier isn't built, connect the nodes
 }

For multi-stage constructs if_construct_built_false is true during the intermediate stages until the construction is completely built.

if_construct_built_true

if_construct_built_true <action_number>

used to manipulate nodes and / or actions based on the status of the construct.

 action 2 // a barrier construct
 {
   if_construct_built_true 2 //the action number here must be set to the constructs action number
       node_disconnect 7 8 true //barrier is built, disconnect the nodes
 }

For multi-stage constructs if_construct_built_true is true only when the construction is completely built (built final in the map script file).

if_fda_owner_allies

if_fda_owner_allies <action_number>

used to manipulate nodes and / or actions based on the status of the flag.

 action 2 // a spawn flag
 {
   if_fda_owner_allies 2 //the action number here must be set to the flags action number
       activateAction_Group 1 // allies have the flag, so activate these actions
 }
if_fda_owner_axis

if_fda_owner_axis <action_number>

used to manipulate nodes and / or actions based on the status of the flag.

 action 2 // a spawn flag
 {
   if_fda_owner_axis 2 //the action number here must be set to the flags action number
       activateAction_Group 1 // axis have the flag, so activate these actions
 }
if_action_false

if_action_false <actionNumber>

Checks the goal number of an action to see if it has happened. It references the goal number of the action. If the goal number is the current goal number or greater, it assumes that the action has not happened.

For this example, let's say we have 2 walls that need to be destroyed to gain entry into an area and you have 2 objectives behind the wall. Stalingrad is an example of this type of map setup. If one wall is destroyed, the allied team can reach both main objectives to plant. So, in each action test for the walls, certain action groups are activated. And because we aren't forcing a specific order for this, we need to activate those actions in both wall tests. It is possible for one of the main objectives to be destroyed before one of the walls is destroyed. Because of this, we want to check the status of the tanks before activating any actions. This will keep them from attacking or defending a tank that has already been destroyed.

 action 1 //western wall on Stalingrad
 {
 if_action_false 64 //west tank dynamite action
   activateAction_Group 3 //west tank actions (attack and defend for non-engineers)
 if_action_false 63 //east tank dynamite action
   activateAction_Group 2 //east tank actions (attack and defend for non-engineers)
 }
 action 2 //main gate on Stalingrad
 {
 if_action_false 64
   activateAction_Group 3 //west tank actions
 if_action_false 64
   activateAction_Group 5 //some more actions
 if_action_false 63
   activateAction_Group 2 //east tank actions
 if_action_false 63
   activateAction_Group 4 //some more actions
 }
if_action_true

if_action_true <actionNumber>

Checks the goal number of an action to see if it has not happened. It references the goal number of the action. If the goal number is less than the current goal number, it assumes that the action has not happened.

same principle as if_action_false, but checks to see if the action has happened already. see if_action_false for an example script

if_obj_captured

if_obj_captured <actionNumber>

used in maps where a single deliver action doesn't end the map. Rommel_final is an example of this. On Rommel_final, once the key is delivered, the script connects the nodes into the cystern area and activates / deactivates actions so they can start this phase of the map

action 3 // key card on Rommel_Final
{
 if_obj_captured 3
   node_connect 184 185 true //connect the nodes now that the key is captured
 if_obj_captured 3
   activateAction 5 //activate the dynamite action
 if_obj_captured 3
   activateAction_Group 3 //activate the water cistern actions (defend and attack)
 if_obj_captured 3
   deactivateAction_Group 2 //deactivate the key card deliver actions (defend and attack)
}

New with Fritz ET Ver. 0.70

if_allied_cp_built_true

if_allied_cp_built_true <action_number>

used to manipulate nodes and / or actions based on the status of the command post. Requires that the command post action have the correct entity number, otherwise the game may crash.

 action 7 // a command post
 {
   if_allied_cp_built_true 7 //the action number here must be set to the CP action number
       activateAction 23 // when the allies build the CP, activate action 23
 }
if_allied_cp_built_false

if_allied_cp_built_false <action_number>

used to manipulate nodes and / or actions based on the status of the command post. Requires that the command post action have the correct entity number, otherwise the game may crash.

 action 7 // a command post
 {
   if_allied_cp_built_false 7 //the action number here must be set to the CP action number
       deactivateAction 23 // if the allies have not built the CP, deactivate action 23
 }
if_axis_cp_built_true

if_axis_cp_built_true <action_number>

used to manipulate nodes and / or actions based on the status of the command post. Requires that the command post action have the correct entity number, otherwise the game may crash.

 action 12 // a command post
 {
   if_axis_cp_built_true 12 //the action number here must be set to the CP action number
       activateAction 47 // when the axis build the CP, activate action 47
 }
if_axis_cp_built_false

if_axis_cp_built_false <action_number>

used to manipulate nodes and / or actions based on the status of the command post. Requires that the command post action have the correct entity number, otherwise the game may crash.

 action 12 // a command post
 {
   if_axis_cp_built_false 12 //the action number here must be set to the CP action number
       deactivateAction 47 // if the axis have not built the CP, deactivate action 47
 }
Logical Operators

The logical operators AND and OR can be used to combine a pair of conditional action tests.

action 5  // an action test
{
// If BOTH the spawn flag is owned by the allies AND the construct is built, then action Group 9 
// is activated                            
	if_fda_owner_allies 3 AND if_construct_built_true 14
		activateAction_Group 9
		
// If EITHER the documents are home OR action 25 hasn't happened, then action 34 is activated 		
	if_obj_home 2 OR if_action_false 25
		activateAction 34
} 

An important thing to remember when using these operators is that they are called ONLY when the particular action test is called. In some cases you will need to have the same statement inside both action tests. For example, we want to have group activated only if a team holds a flag AND a construct is not built:

action 1  // a spawn flag
{
	if_construct_built_false 2 AND if_fda_owner_allies 1
		activateAction_Group 3
}

action 2  // the construct action
{
	if_construct_built_false 2 AND if_fda_owner_allies 1
		activateAction_Group 3
}
 

This is necessary because there is no set order in which these actions are completed and because the state of each of the actions may change during the game.

Now FritzBot ET does not support brackets nor longer chains of logical operations in a single line. Rarely is that a problem but in some more complex maps you may want to use a longer logical condition. For those cases there are ways to extend the condition over multiple statements. The topic Long Conditional Tests In Fritzbot ET provides examples.

(For an example I suggest reading FritzBot_Buttons_And_Levers and note how action 6 is used.)

set_Map_Has_Vehicle true/false

Sets whether or not there is a vehicle in the map that the bots should worry about. In goldrush, for example, after the church doors (Bank doors) are blown there is no further use for the tank, and after the gold crates are loaded on the truck, the truck must be activated so it can be fixed and attacked.

set_Vehicle_Number <entity num>

Sets the entity number of the vehicle entering the game. In Goldrush this command is used to switch from the tank entity to the truck entity when the gold is stolen.

set_Vehicle_Owner Axis/Allies

Sets the current vehicle owner, determining who will fix it and who will attack it.

action 138  //  the church door event_explode
{
	set_Map_Has_Vehicle false  // remove the bots' interest in the current vehicle, the tank
}

action 139  //  the gold steal action
{
	if_obj_captured 139
		set_Map_Has_Vehicle true  // alert the bots that there is a new vehicle in the game
		
	if_obj_captured 139
		set_Vehicle_Number 178	//script_mover entity number of the truck
		
	if_obj_captured 139
		set_Map_Owner Allies	// Allies will fix and Axis will attack the truck
}
Wait

Delays execution of keywords.

action 2  // an action test
{
	wait 5                       // wait 5 seconds after action 2 occurs, then
	activateAction_Group 3       // activate Group 3

	activateAction_Group 7       // no wait for Group 7
}

When the action test is called, it will wait 5 seconds before activating Group 3. It wil not wait 5 seconds to activate Group 7. The keyword must be on the very next line after the "wait." If you want a delay for Group 7 as well, put an additional "wait" just above that line. The maximum delay is 500 seconds.

The wait command can be stacked inside conditional statements as well.

action 5  // an action test
{
	if_construct_built_false 13     // when action 5 occurs and if the construct is built, then
		wait 20                 // wait 20 seconds, then
		activateAction_Group 6  // activate Group 6
}

and...

action 5  // an action test
{
	wait 20                 	// when action 5 occurs wait 20 seconds, then
	if_construct_built_false 13     // check if the construct is built and if so
		activateAction_Group 6  // activate Group 6
}

(NOTE: the 2 examples are equivalent ONLY if the construct 13 is unchanged at the beginning and end of the 20 second delay. You should use the second form cautiously as I have sometimes noticed problems in some maps suggesting that the condition is not being updated after the wait delay)

kill_Action

Sets the actions type and group number to -1. Because the action type is -1 (invalid), even if the action is activated, no bot will ever use it.

Used to permanently turn off an action, even if it is scripted to be turned on. Consider the case where a dynamite plant action is carried out against a bridge construct. You want the dynamite plant action #7 to be active when the bridge is standing and you want your engineers to ignore it when it is destroyed. So you toggle it off and on like this:

action 8  // a bridge construct action
{
// ...snip...
// Toggle the bridge dynamite action
  	if_construct_built_true 8
  		activateAction 7     // Dynamite the bridge if it has been built
  	if_construct_built_false 8
  		deactivateAction 7  // Ignore the bridge if it has been destroyed
// ...snip...	  		
}

But after the tank has crossed the bridge there is no need to keep blowing it up. Normally you would deactivate both actions 7 and 8 to keep the bots away. But what if a human player decides to blow it up anyway, and after he does another human on the other team rebuilds it? The action 8 test triggers and action 7 gets activated. So we kill the dynamite action forever to prevent the bots from responding.
kill_Action is also typically applied to a spawn flag action (6) when the flag entity is removed from the map. kill_Action can also be used to remove smoke_can hints when no longer needed.

action 9  // tank event_explode action when it crosses the bridge
{
	deactivateAction 8
	kill_Action 7
 }
default

This defines a group of actions that will run at startup of the game. Usually these are actions that you want to delay for a time after the game starts (to run actions without delays at game start, simply set their goal_num to 0). Do not use "activateAction_Group 0" here because it is unnecessary and will just cause a flurry of "no goals" spam at startup. The default group works just like action tests except that it is run at startup and it ignores conditional statements.

The original purpose of this action test was to delay the activation of actions in Goal Number 0. Any actions that are placed in goal number -1 (off) can be activated in goal number 0 with the default action test.

REQUIRES that it be placed at the start of the aiscript immediately after the headers.

Here's an example from Caen2:

bot_SightDist 2000		// How far the highest skill bot can see on this map
spawnflag_is_priority  1	// Should bots focus on spawnflags?
cmdpost_is_priority  1		// Are cmdposts critical on this map?
construct_is_priority  1	// Should engs focus more on constructibles
map_has_vehicle  1		// 0 = No, 1 = Tank, 2 = Train
vehicle_entity_number 188	//  Tank "script_mover" entity num
vehicle_team_owner 1		// 1 = Axis, 2 = Allies

default	// Run these at game start
{
// Let Allied engineers complete minor tasks before blowing bridge
	wait 20
	activateAction_Group 18	// Bridge dynamite_plant

// Activate Allied air-strike hint & roam at NW bldg corner
// after initial contact has been made near iron gate
	wait 45
	activateAction_Group 9

// <snip>
}

note: it is not necessary to activate any actions or groups that are already preset to goal number 0 (because they are already on).

Debugging Aiscripts

For some ideas on how to debug your aiscript file see Debugging_Aiscripts.

ET Map Scripting

More Keywords

barrierRemove keyword

An important keyword not available in the aiscript that you may need is barrierRemove. This FritzBot-only keyword is used the used in the .script file to remove troublesome barriers from the map, such as vent grates, barbed-wire barriers, and windows that a bot cannot punch though by himself. If a simple obstruction blocks a bot's path he can usually break through on his own, but cannot if it requires a grenade or if it isn't in his direct path.

The code to remove the obstruction must be installed in your map's .script file which you can find in the map.pk3, located in /etmain. Its script is located in the "maps" folder of the map.pk3, along with some other files. Open the map.pk3 with your unzip software and find the script file. It'll have the same name as the map with a .script extension. Click on it and drag a copy to your fritzbot/maps folder. Do not remove the original from the pk3. If the fritzbot/maps folder is missing, create it first. (Note: or use fritzbot-dev/maps if using the dev mod folder ). Make sure that you have set /sv_pure 0 so your soon-to-be modified version of the script will be used when you run the map (instead of the original in the .pk3).

Using a text editor, insert the barrierRemove trigger code into the script file at the beginning of the file as shown for each barrier that you want to remove. Use the "func_explosive" entity number. Each removed entity must be in its own "trigger". Include your modified file with your waypointing package when you release it.

Here's an example from Foo Fighter:

game_manager  // part of the map script file
{             // ditto
	spawn // ditto
	{     // ditto
 	
 		barrierRemove		// Window glass for axis panzer
		{
			129
		}

		barrierRemove		// Window glass for sniper
		{
			139
		}
	
		// <remainder of the map script file>

More Advanced Script Options

FritzBot supports ETPro map scripting; which makes it possible to create entities in maps. Originally implemented for dynamiting the back door on Seawall Battery, other uses were soon realized. For some information about how to modify map scripts for use with FritzBot, a reference is available here: Fritzbot_Map_Scripting

How to waypoint with tanks

By default, the bots know where an active vehicle is and will escort, fix, and attack it automatically. But it will be as a mob. It would be better if the attack and defense actions could be choreographed to move along with the vehicle. Panzer positions could be set up ahead of the vehicle, barriers constructed before it gets there, and defenses that are left behind shut down. To accomplish this, you need to know where the vehicle is, or more specifically, when it has reached pre-determined checkpoints. A detailed step-by-step procedure to do this is described in Creating a fake toi.



Waypointing Aids

Pre-release Checklist

TomTom has prepared a Fritzbot ET Waypoint Pre-release Checklist to help you remember all the little details that need to be checked before releasing your waypoints for general public use. Make good use of it!

Making a Waypointing Configuration File

Once you get the hang of waypointing basics you will want to speed up many operations and depend less on the console and FritzBot in-game menu. To that end, creating a config with waypointing related key bindings is one tool you will want to explore. See the article FritzBot_ET_Waypointer's_Config_File.

Waypointing Quick reference

coming soon


Waypoint Troubleshooting

Problem: bots are standing in place and spamming that they are stuck and have no valid goals.

The first thing to do in this case is to type bot_pause 1 to get the "no goals" messages to stop. Then do the following:

  • check to make sure the bots have actions available in the current goal (/goal_num in console to find current goal)
  • check the pathing to make sure they can reach the goals
  • double-check the nodes properties along a path to make sure the node_team is correct for them all
  • check the aiscript to make sure you are turning on the actions at the right time
  • make certain that every class of bots has at least 2 active actions that constitute goals available at all stages. (some actions are not counted as valid goals, but merely suggestive

Problem: bots move about but do not fight.

  • Check that your aiscript is in the correct subdirectory, with the correct mapname and .aiscript filetype.
  • Verify that at the top of your aiscript you set the bot_SightDist parameter to a reasonable value (>1000, <4000).
  • Verify the correct position of the #EOF at the end of the aiscript.

Problem Engineer bots sometimes stand around with or without spamming Error messages.

  • Review all engineer actions as to their triggers.
    • If using the goal tracker (trigger by goalnums) verify that it is impossible for any of the engineer actions (dynamite, construct etc.) to be enabled prior to becoming accessible. Remember that the goal tracker does not differentiate between dynamite actions and that human players may not play by the rules.
    • If using the aiscript to trigger the engineer actions verify that the actions (or action-groups) are properly disabled whenever the paths are disconnected to them. Pay particular attention to the effect of re-constructible barriers.
  • Verify that the closenode values of the engineer actions are not for nodes with flags that are problems such as;
    • Nodes that are team specific for the opposite team only.
    • Nodes that are flagged for jumps or leaps (can be a problem).

Problem: can't get an action to work like I want it to

Most actions are fairly simple to set up and control, but some can be tricky at times

  • open a nav file that came with the FritzBot release and look to see how a similar action has been set up
  • ask questions in the waypoint forum. A lot of help is available there

Problem: actions are not activating or deactivating when I want.

If you used the goal-tracker method then other objectives may be changing the goal_num at a time you did not anticipate. If you used aiscript control then;

  • check your logic, does it cover all relevant combinations and in all related action test blocks. Is another action test block interfering. Is the action correctly controlled for all relevant action events.
  • check the console for error messages related to that action or at the start when FritzBot reads the aiscript. A syntax error in the aiscript may prevent the remainder of the aiscript being read and used.
  • verify the total number of action tests in the aiscript is within the limit for your version of FritzBot ET.

Problem: Fritz is crashing when I load a specific map

  • if it crashes before you get to limbo there may be an serious error in one of the files. Verify that the #EOF appears at the end of the aiscript and bots file. Look for unclosed action test blocks, verify that you have not exceeded the maximum number of action tests and keywords. If you exceed 16 action tests you must use the keyword fix beta .dll. Check for spelling errors in keywords.
  • verify that the map itself is not the problem by loading it in plain vanilla ET.
  • start the map without the .aiscript file (rename, move or delete the .aiscript then start FritzBot). If still crashing try loading without the .bots file and any modified .script file.
  • if the map crashes after the warmup then it might be the .nav file

Problem: Fritz is crashing at certain times while testing new waypoints

Remove any bot config files that you may have for your map, start the node editor and do the following:

  • double check the entity numbers you have set for all constructs (command posts included).
  • if a construct disappears on a map after a certain event happens, be sure to disable that action in the script.
  • double check the entity numbers on all other actions and any nodes tied to capture-flag-actions. No other nodes should have node_ent values other than 1023.
  • if fake entities are added in a modified map script file;
    • verify that their target, targetname, and scriptname properties do not conflict with pre-existing entities.
    • verify that any added trigger scriptblocks in the map script use unique names,
    • make certain that the script file only performs "alertentity" on any fake func_explosives a single time,
    • check that the extra scripted entities do not add too many trigger_objective_infos. Also check that the total number of entities is not increased to the point that there are not enough left for game-play created entities.

Problem: bots are getting stuck on walls or in doorways

There are a few reasons this may happen. Go to the spot they are getting stuck and do the following:

  • double check the node connections to make sure the pathing isn't going through the walls
  • type cg_drawradius 1 and check the radii in the area. Do node radii spokes poke through to the other side of walls?
  • if it's at a construct or dynamite-able barrier, check the aiscript and make sure the node_connects are occurring at the right time.

Problem: Covert Ops are standing in place doing nothing

This will happen if the bot has a goal that it can't reach:

  • double check pathing to every available covert ops specific action (satchel actions)
  • double check the entity numbers for the satchel actions
  • verify all other actions the Covert Op is allowed to perform are only active when a valid path is available without a uniform.

Problem: Engineer is planting dynamite repeatedly even after the objective is destroyed

A few things may cause this:

  • double check the entity number of the dynamite action. It should be that of the correct trigger_objective_info entity.
  • verify that you used action_construct_plant actions on constructibles or if not, that you disable the action_dynamite when if_construct_built_false tests true in the aiscript.
  • for one-time objectives determine whether the trigger_objective_info targets a func_explosive or a func_construtible. Sometimes a mapper uses a func_constructible instead of a func_explosive on one-time objectives that can not be rebuilt.
  • if using the goal_tracker method, check and make sure that the dynamite action is not set to active forever.

Problem: Engineer is not planting dynamite on built constructibles

  • double check the entity number of the action_construct_plant action. It should be that of the correct trigger_objective_info entity.
  • verify that the related construct action is active and of high enough priority to focus the engineers to dynamite it.
  • Note: you may have a map with multiple-stage constructions like the bridge in fueldump. Using an action_construct_plant the bots will only dynamite the built final stage. Using an action_dynamite the bots will dynamite until made to stop, but no built-in aiscript test exists to stop them at any stage. (It takes special advanced map scripting to provide mid-stage dynamiting support.)

Problem: Changes to the waypoint don't seem to be saving

A few things may cause this:

  • check that you have set /sv_pure 0 so you can load in the unpacked nav files you saved.
  • make sure you are doing a /node_save and then a /map_restart. Doing a /vid_restartforces a reload but unsaved changes are lost.
  • make sure you don't have waypoints inside of a pk3 file in the \fritzbot directory for the same map
  • if you are editing nodes with the waypoint tool, sometimes you will have to restart FritzBot ET to see the changes

Problem: My waypoint nav file just got wiped!

There are a couple of common mistakes to avoid, and don't forget to backup your waypoints regularly.

  • don't bind keys to any of the clear commands like node_clear or action_clear. You might hit the key without realizing it.
  • don't do a node_save (or hit a key with a node_save binding) prior to your waypoints being first loaded. When you first enable the editor on entering the map your old waypoints are not yet loaded for editing. So at that point use /vid_restart to load in your old waypoints and make them visible. Then use /node_save when you have changes to save.

Gameplay / Balance

Gameplay and Balance are the most important things to test in waypoints. If gameplay is bad and / or the map is too hard or too easy to win, then your waypoints aren't ready to release. The best thing to do is to play the map a lot on both teams. This will help find areas in the map that a human player may be able to 'exploit'. In these areas, add some actions to help prevent it. It's a good thing if the bots give each other a nice balanced game, but at this point of the waypoint development we should start to focus on what human players will experience. After all, we aren't creating the waypoints for the bots to play by themselves :p

When you think you have waypointed the gameplay so that the bots will defend / use the map to prevent a human player unreasonably exploiting anything, it is a good idea to check balance for the two teams. You cannot expect to have properly tested the map in even a half-dozen plays and unless you can 'exploit' some friends, this means all your time playing both teams in different roles and tallying the results. However you can also run unattended games with no human players (since bots don't sleep) and get the results afterwards. More on how to do this can be found in Unattended_Testing_Methods.

Tweaking the Balance

There are some maps where no matter what waypoint tweaks you make, the balance isn't quite right. In this case, adjusting the spawntimes is recommended. Some people may think that isn't a good idea, but the real thing that matters is how the gameplay feels. This is a mod, so adjusting spawn times to improve gameplay seems reasonable to me. It should however be used as a last resort and most likely will require a lot of testing to get it just right.

If it gets to the point where you find that you need to adjust spawn times a little, open up the map's pk3 file and make a copy of the <mapname>.script file. Place that file in \fritzbot\maps and open it in your favorite text editor. At the top of the file you will see something similar to this:

// Game rules
wm_axis_respawntime	30
wm_allied_respawntime	20

Adjust these in small increments until you find the right balance. Once you are happy with how the game feels, you are ready to release the waypoints for others to try and test. You can expect feedback on the waypoints and that is a good thing. Ultimately they will be packaged with the next release of FritzBot and become official waypoints.

Releasing Waypoints

Once you are ready to post or send files, it's best to package them into a pk3 file. Grab this file here and read the readme included. It is important that the files reside in the correct subdirectories inside the pk3 file.

Include in the pk3 file some text file identifying revision, author, date and other things of special note. The preferred revision-readme form is here README-_mapname_revM.mm.txt

After getting the waypoint files packaged into a pk3, you can post them to the filebase or email them to one of the FritzBot team members for testing / posting.


Permanent link to this page