Flylib.com

Books Software

 
 
 

Practical Demo

Summary

This chapter discussed the interaction between the weapon-selection capability and the game engine, used to gather information and perform the weapon changes:

  • The weapons are modeled as symbols; their properties need to be learned or included into the AI.

  • The interfaces with the environment are extended to provide queries for spatial restriction.

  • Queries to the personal state and inventory are also provided, allowing the animat to determine health and weapons available.

  • Information about enemy damage is handled indirectly, thanks to callbacks and events sent by the environment.

  • All the interfaces were chosen to be compatible with the existing ones and are simple to use.

The next chapter provides a simple prototype for weapon selection using scripting facilities and a voting system.

Practical Demo

Sir Obvious is an animat that makes use of the interfaces defined in this chapter. It checks the inventory to find the weapons and corresponding ammo available and prints the result to a debug console. Health changes and the constriction of the terrain are also worthy of Sir Obvious 's comments. The source and demo is available online at http://AiGameDev.com/.


Chapter 25. Scripting Tactical Decisions

Key Topics

  • Foundations in Scripting

  • Scripted Weapon Selection

  • Evaluation

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 performs weapon selection using a voting system, implemented in a scripting language.

This chapter covers the following topics:

  • An overview of scripting languages, from a very high-level point of view. The focus is drawn to the advantages of scripting as an essential tool in our reactive architectures, complementing the generic AI techniques discussed throughout this book. This discussion covers typical features of scripting environments, the languages, and how scripts can be considered as other components in the AI system.

  • The principles behind voting systems, notably how they can achieve weapon selection. A script is used to implement the voting system.

  • An evaluation of the system, and a description of the experimentation procedure used to set up the voting system in practice. Some of the problems with adjusting votes are resolved by suggesting a learning approach.

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 certainly very commonly used in AI -and particularly in computer games . The need for convenient scripting languages extends beyond traditional game AI approaches; scripting will not die out as AI improves ; it will serve a different purpose (other than behaviors). Systems with modern AI techniques benefit from scripting languages providing the glue between basic components .

This section briefly covers scripting languages, without focusing on any one solution in particular. Much of the lower-level details of each language (for instance, Python or Lua) can be found in their thorough documentation.

Scripting Languages

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 generally required to implement the same algorithms.

Scripting languages are often ideal complements to standard programming languages. For example, C++ is a compile-time, statically typed language that offers the potential for amazing performance. Scripting languages are usually interpreted at runtime and dynamically typed, implying they are very flexible, albeit slower. Scripts allow easy modification and reduce the need for compiling and hard-linked code (builds are expensive), customization is much easier, and prototyping is faster.

Script Environments

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 processed thanks to an interpreter , or virtual machine. The interpreter executes each of the statements in the script as operations (for instance, to modify variables , or call core functions). This results in the capability of scripts to provide the same functionality as normal programs.

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 considered as black box components with well-defined interfaces exposing their functionality. Scripting environments are no different. This is one of the reasons we can provide a high-level overview without going into any details of specific languages.

Integrating the scripting environment into the application is called embedding it. Conversely, integrating the native language into a scripting environment is known as extending 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 weave these scripts into the architecture, described in the next two sections.

Exporting Interfaces

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.

graphics/25fig01.gif

Importing Interfaces

On the other hand, the scripting module can also import interfaces from other components. This allows scripts to gather the data themselves , without relying on being passed information.

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 interacts with the interpreter .

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 name :



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 prototypes is quite difficult because the interface needs to handle any parameter types. Providing two overloaded functions, Param and Result achieves this in a flexible fashion; only floating-point numbers are shown here, but integers and strings could be handled just as easily:



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.