This chapter discussed the interaction between the weapon-selection capability and the game engine, used to gather information and perform the weapon changes:
Chapter 25. Scripting Tactical Decisions
The previous chapters prepared the way for a preliminary implementation by analyzing the platform, defining (providing an understanding of) the problem, and providing a specification to interact with the world. The first prototype
This chapter covers the following topics:
At the end of this chapter, the strengths and weaknesses with scripted voting systems will be more obvious, particularly as a solution to weapon selection. Analysis points in the direction of hybrid approaches, including a learning component, will be discussed. But first, let's take a deeper look at scripting languages in game AI.
Foundations in Scripting
Although scripting is not a product of AI research, it's
Scripts are generally much simpler to write than standard programs. Thanks to loosely typed -or even typeless -syntax (variable types do not always need to be declared explicitly), more flexibility is immediately available to the programmer. Scripting languages also benefit from dynamic typing; the type-checking only happens during execution of the instructions. For these reasons, fewer lines are
Scripting languages are often ideal complements to standard programming languages. For example, C++ is a compile-time, statically typed language that offers the
for amazing performance. Scripting languages are usually interpreted at runtime and dynamically typed,
The major advantage of scripts is that they can be loaded and executed at runtime without a separate compilation phase. There generally is a compilation phase, but this is often done dynamically -at the same time the script is loaded. For efficiency, the precompiled code can often be saved for later as bytecode (that is, sequences of instructions as platform-independent binary code).
Then, the bytecode is
The scripting environment is the area of memory where all the necessary variables reside, as well as each of the functions defined by the script. This is the core of the scripting system, and the main part of the code required to support the scripting language.
Integration as a Component
Most other AI techniques can be
Integrating the scripting environment into the application is called
it. Conversely, integrating the native language into a scripting environment is known as
it. After that's done, the AI engine has the capability to load and run any script, combined with native code. There are two ways to
Components higher up in the architecture hierarchy that include the scripting language often need to interact with it. Just like other AI components, this is done by exporting interfaces. Third-party components can then easily call the underlying functions.
Using a high-level interface, it's possible to pass all the data to the script before it runs. This means the script is fully isolated, and can only deal with the information it is provided. In Figure 25.1, on the left, only a high-level interface is exported, allowing the parent component to interact with the script. On the right, the scripting environment imports the input and output interfaces, so the script can interact directly with the world.
Figure 25.1. Integrating the scripting environment with the AI architecture.
On the other hand, the scripting module can also import interfaces from other components. This allows scripts to gather the data
Conceptually, the interface components are nested within the scripting environment, because the script depends on them. In the architecture, the script is a higher level in the hierarchy.
A Scripting Module
The scripting environment can be accessed by an interface that fits into our AI framework. All we really need is the ability to call functions and query the scripting environment. The interface in Listing 25.1 is not directly reflected in the scripts; it merely
Listing 25.1 Simple Python Function to Evaluate the Benefit of Weapons
def EvaluateWeapon(type,ammo): if ammo > 0: if type == "railgun": return 2 return 1 return 0
Function calls are relatively simple to handle because we can refer to the function by
bool Run( const string& function );
In some cases, parameters are required and the result must be queried (for example, in the Python snippet shown in Listing 25.1). Supporting such arbitrary function
void Param( const float f ); void Result( const float & f );
Finally, generic functions for querying and modifying the scripting environment are sometimes necessary. These overloaded functions set and retrieve the content of global variables of arbitrary types:
void Set( const string& name, const float f ); bool Get( const string& name, const float & f );
The process of importing interfaces into the scripting environment is handled differently because there is no need for a runtime interface for this. Instead, this will generally be handled during initialization time. The idea is to convert the existing C++ interfaces (for instance, vision or motion) into Python code, using an automated interface wrapper.