Scripted Weapon Selection
A script handles most of the little details mentioned in the past few chapters (for instance, extracting features, analyzing weapon properties, and dealing with timing). Scripts are very good at providing custom solutions to exotic problems, so this approach makes the most of them. The AI techniques used later in this part (such as decision trees) are great at handling general-purpose solutions to generic problems. The script in this section is not discarded because it can help manage and train the decision tree.
Along with the scripting approach, the following ideas are used (as discussed in the preceding three chapters):
A voting system determines how to rank each of the properties of the weapons. Essentially, many different features are taken into account, and a vote for the most important weapon property occurs. Then, each weapon is evaluated according to the vote, and the best weapon is returned. This works well because there are often more than two candidates, and most of them are legitimate choices.
A quick search on the World Wide Web saves us the hassle of looking through the game source code for the information about weapons. The following statistics can be found in the Quake 2 Weapons and Combat FAQ [Quake2FAQ]. The speed of the projectiles had to be found in the Quake 2 game source code, and are shown in Table 25.1.
The properties of weapons, in the order of Table 25.1, are as follows:
Time units are in seconds, and distances are in Quake 2 units (18 = 1 step). There is radius damage (marked *) around the explosion points of rockets and grenades, as well as damage for a direct hit. The BFG is not included because it is very random (and rarely used). These properties will be declared in a separate file so that they are easy to modify. The script will include this file so that it can be taken into account in the deductions.
Given these facts, the AI must decide how appropriate a weapon is for the current situation. Chapter 23, "Weapon Selection," discussed the concept of a fitness function, combining the features of the current situation with the decision criteria. The result of the fitness function is a single value representing the suitability of a weapon.
Here, the features consist in the layout of the environment, the distance between players, current health, and so forth. The criteria for deciding which weapon to use are actually combinations of these features.
The idea behind a voting system is that the features decide which weapon property they require most, and vote for it (see Figure 25.2). Unlike a democracy, it can be easier to allow more than one vote, and it's even possible to use partial votes (that is, floating-point numbers less than one). The votes are then used to scale the properties of the weapons. Many votes mean that a property is important, so multiply the value by a large number; conversely, few votes mean that the property is not very significant.
Figure 25.2. Overview of the voting system, with the features contributing to the votes. The votes are multiplied by the weapon property, and the weighted sum determines the fitness of the weapon.
Collecting Votes from Features
The first thing to do is to get an expert to determine the importance of properties in different situations. Before the voting begins, the candidates need to be identified. We'll use all the weapon properties that were listed in Table 25.1, as well as two more:
As a reminder, the splash property is the splash damage, denoted by an asterisk in Table 25.1. The DPS property stands for damage per second.
Now, the features of the situation that are involved in the voting must be chosen. Deciding upon these features is a matter of intuition, and their balance no doubt will need to be tweaked during the experimentation phase. As shown in Table 25.2, some features have votes of strength of greater than one, and other features vote for multiple features. The last row is applied independently of any feature, and uses a vote proportional to the ammunition.
After all the votes have been collected, they are multiplied by the value of each weapon property. The sum of the weighted properties gives us the final weapon fitness. The weapon with the highest fitness is selected as the best weapon.
This completes the description of the weapon-selection script. We'll actually implement this in Python because it's the language of preference of the FEAR developers. However, a Lua module and script could easily be substituted.