RC++ A Rule Based Language for Game AI

"Game AI" is the high-level control code for computer entertainment applications. Games are diverse, and the nature of game AI reflects this diversity. However, game AI, in contrast to rendering code and other game code, is distinguished by employing a high density of predicates on rapidly changing game state, and a high density of operations that change game state. Traditional programming languages, such as C and C++, are not designed to facilitate the creation of such code, unlike high-level AI rule-based languages. RC++, a full-featured, rule-based extension to C++, designed for Sony Computer Entertainment’s PlayStation2 hardware, is described. RC++ is based on OPS5 (Forgy, 81) and Poprulebase, a rule-based extension to the Pop-11 programming language. It combines optimised execution associated with OPS5 with the syntactical style and some of the useful features of Poprulebase. It is designed to facilitate the rapid creation of game AI by automating many of the common programming tasks associated with creating game rules, while maintaining the flexibility of C and C++ when required. The aim of the paper is to demonstrate the applicability of rule-based programming to game AI in general, and the usefulness of RC++ for game AI in particular. THE RULES OF THE GAME Currently, most game AI code consists of the implementation of behavioural rules that encapsulate knowledge about a particular game domain. For example, rules to control racing cars, footballers, enemies, and so forth. There are many different types of ‘rule’. The equations of motion that control a bouncing ball are ‘behavioural rules’ in a general sense. Such rules normally involve analytical or 1 Poprulebase is part of the Poplog programming system, which contains the languages Pop-11, Prolog, Lisp, ML, and the SIM_AGENT toolkit. It is freely available from http: // www.cs. bham.ac. uk/ research/ poplog/ freepoplog.html. numerical solutions to equations involving real numbers. In contrast, a rule to decide whether a footballer should pass or shoot involves conditions on world state, which may be represented not just by real numbers, but by symbolic representations of states-of-affairs, or combinations of such quantitative and qualitative information. These two types of behavioural rule require very different implementation strategies. Physical equations, in particular, require techniques from numerical mathematics, whereas ‘if-then’ rules require a different approach. This paper presents a language, called RC++, which is designed to facilitate the coding of ‘if-then’, as opposed to physics-based, rules. There are also many different types of game ‘agent’. A bouncing ball does not need to remember facts about its world, whereas a virtual footballer needs to remember where his team-mates are, what the current team strategy is, and so forth. Many games implement both kinds of agent: passive objects governed by approximations to physical laws and active agents constrained by those laws, but able to store information, make decisions, and perform actions that change the virtual environment. Examples are balls (passive, controlled by physical equations) and footballers (active, controlled by rules) in a football game, or cars and drivers in a racing game. The distinction between passive objects and active agents is reflected in the game industry’s distinction between physics modelling and game AI. Implementing behavioural rules for active agents is required by all games and is an everyday task for the game AI programmer. Rules are to AI as polygons are to graphics. The aim of RC++ is to provide methods and tools that allow easy scripting of high volumes of predetermined or logicbased events for game characters to perform, and ease the implementation difficulties of more sophisticated techniques required for correspondingly more intelligent behaviour. PROCEDURAL LANGUAGES C and C++ are fundamentally procedural languages. They are not ideally suited to writing rule-based AI code. Game AI code, in contrast to other game code, tends to be condition-rich, requiring many tests on state and conditional branching based on the results of those tests. A procedural implementation, such as a C implementation, codes condition checking on state as a succession of ordered ‘if’ or ‘switch’ statements. There is nothing intrinsically wrong with this approach. However, it does require the programmer to not only specify the condition and the actions to be executed if the condition holds, but also under what circumstances the test should be checked, where and how the predicated state should be stored, how the predicated state should be accessed, and when and how the state should be created and deleted. In addition, if the condition needs to be checked against multiple instances then the programmer must write looping code, including determining under what conditions the loop should terminate. Finally, the procedural programmer must incrementally abstract parts of conditions as separate function calls for reuse in other conditions: this takes time, and, if not performed, leads to a proliferation of 'same-but-slightly-different' conditional statements and code bloat. In summary, development times are increased by the need to perform a large number of peripheral programming tasks: it is never simply a matter of writing ‘rules’. Hence, scripting languages for game AI based on procedural languages, such as Java or subsets of C, are misguided: they are too similar to the main game language. The extra complexity introduced to the development process is not offset by any new language advantages. And any benefits obtained from the extra level of indirection between AI code and game engine code introduced by using a procedural scripting language can be also be obtained by simply implementing a good AI/game engine interface. In contrast, RC++ is specialised for writing game AI. It partially automates many of the peripheral tasks associated with creating game AI code. Programmers, and eventually designers, are able to concentrate on writing the rules themselves. RULE-BASED LANGUAGES RC++ is a rule-based extension to C++. Rule-based languages are based on a simple model of computation that is particularly suited to the direct encoding of large collections of highly conditional knowledge that constitutes intelligence within a particular domain, and hence are ideally suited to controlling intelligent agent behaviour. For example, they form the basis of all expert systems (e.g., the CLIPS language (Giarratano, 93), and JESS (Friedman-Hill, 00), a rule language written in JAVA), a technology widely used, and also agent toolkits (not yet widely used), such as SIM_AGENT (Sloman & Poli, 95; Baxter et al., 97). Rule-based languages are executed by a production system, which consists of a working memory (WM) that stores information or ‘assertions’, a ruleset that defines under what circumstances assertions in WM should change, and a scheduler that repeatedly applies rules to assertions in WM. Every rule has a condition part, a boolean expression that can be checked against assertions in WM, and an action part that alters assertions in WM. For example, a production system might have the following assertions in WM: [Person ^Name Fred ^is 10] [Person ^Name Mary ^is 11] [Person ^Name John ^is 17] // A ‘Person’ data type has two attributes: ‘^Name’ // and ‘^is’. The first attribute contains labels, // the second attribute contains numbers. and a ruleset consisting of a single rule: