by Alex J. Champandard
This article provides an overview of the development tools inside the SDK, explains how the AI logic is structured, and then dig deeper into the level scripts.
Examining the AI Scripts in Call of Duty 4’s Developer Tools
Call of Duty 4: Modern Warfare received high praises from AiGameDev.com readers during the 2007 Game AI Awards; in fact, it was the runner-up for the community award. Admittedly, the AI in the game doesn’t necessarily shine for technical reasons, but it’s wonderfully put together within the whole story, and has arguably become one of the best examples of scripted level design.
Infinity Ward released the Mod Tools for COD4:MW, so it’s a perfect opportunity to take a look under the hood to figure out how the developers structured the engine and its scripts. There’s a lot to learn from, whether you’re building a story-driven game or not.
Screenshot 1: Squad behaviors in Call of Duty 4: Modern Warfare
Download and Installation
Compared to the mod tools of other games (like F.E.A.R.’s SDK), this one is particularly easy to install. In fact, it’s just a plain ZIP file!
You’ll need a PC version of COD4:MW to get the tools up and running. But luckily, the game is not required to download and extract the Mod Tools.
The Mod Tools link can be found at the top of this page.
Once the download is complete, extract it to the same directory as the game itself.
Screenshot 2: AI configuration files within the COD4 mod tools.
Finding Your Way Around
The technology at Infinity Ward is originally based on a Quake 3 engine license, dating back to the first few games in the franchise. Obviously the technology has changed heavily, but there are traces left throughout the scripts and data files (e.g. autogenerated QUAKED files), along with very similar concepts (e.g. worldspawn in levels).
Generally speaking, this engine takes a heavily data-driven approach. With the developer tools, you get access to most of the data (level scripts, configuration files) in readable format. However, the tools are in executable format, and the engine is distributed as a bunch of DLL files. The directories, particularly with regards to the AI and level scripts, are laid out as follows:
Binary Tools — The tools that build the game are in the ./bin/ directory, including the COD4 editor derived from id’s Q3Radiant.
Engine Libraries — These seem to be DLL files in the ./deffiles/ directory (e.g. aitype.dll), along with scripts describing what’s inside (e.g. aitype.gdf).
Raw Assets — The bulk of the game’s data is in the ./raw/ directory, including AI configuration files as ./raw/aitypes/*.[gsc,csv] and level scripts as ./raw/maps/*.gsc files.
Whether you’re just browsing around to learn or actually building a mod, you’ll spend most of your time in that last folder with the raw assets.
Screenshot 3: Interactive helicopter scene in COD4: MW
When browsing through the developer tools, pay attention to the following in particular:
The scripting language with C-style syntax and many of its semantics too. It also has some game specific features, such as micro-threads which execute using cooperative scheduling.
A clean and well documented API for integrating the scripts with the engine, and in particular the AI. For example, functions include: PickupGrenade, MoveToWaypoint, IsKnownEnemyInRadius and CanAttackEnemyNode etc.
The API and level scripts have a heavy focus on animations, which allows the developers to pay attention to the details in every level. For instance, the AimAtPos function returns the the blend time of the aim. You can also override and use specific animation trees within the level scripts.
There’s a level editor, presumably based on Q3Radiant, but since then customized for the COD games. The bulk of the AI configuration files are generated automatically from the export process.
The rest of this article looks at how the scripts are organized and setup.
Screenshot 4: A simple level in the COD4 Radiant editor (see tutorial).
Configuration Files for AI Characters
All the character AI types are configured by two files each, one *.gsc file which is a C-like language similar to the ones used by Quake 3, and the other a *.csv file which contains Comma Separated Values to configure the AI.
The CSV approach is a rather elegant way to handle parameters for the AI. Typically, these are generated automatically from a large spread sheet (or another central data-visualization) within the game editor. Here’s a simple case for an enemy combatant:
weapon,sp/berettaThis integrates with the script below, which contains the main logic for this same enemy soldier:
self.animTree = "";
self.team = "allies";
self.type = "human";
self.accuracy = 0.2;
self.health = 150;
self.weapon = "ak74u";
self.secondaryweapon = "beretta";
self.sidearm = "beretta";
self.grenadeWeapon = "fraggrenade";
self.grenadeAmmo = 0;
self setEngagementMinDist( 128.000000, 0.000000 );
self setEngagementMaxDist( 512.000000, 1024.000000 );
}This file is auto-generated also. What’s not entirely clear is why certain parameters are handled in the CSV while others are in the GSC file, other than the explicit handling of inheritance within the second script.
Screenshot 5: A scripted car sequence in COD4: MW
Apart from these configuration files, the bulk of the AI logic is hidden inside the compiled DLL files. Luckily, the most interesting scripts (the ones for the levels) are available.
The ./raw/maps contains all the level scripts. These aren’t ordered in a particularly obvious way unless you know the names of all the levels! But here’s how it works:
Common Files — The files starting with an underscore: _*.gsc are base files that are included by the specific levels. Functionality includes a patrol behavior, animation logic, various vehicle controllers, and even an A* pathfinder!
Level Scripts — Each map has a few scripts associated with it. There’s a base GSC which references other files that start with the same base name: *_code.gsc, *_anim.gsc, *_fx.gsc and *_amb.gsc. These handle the logic, animations, particles and graphics, and sound respectively.
The bulk of the logic for each level is within the main GSC file, and the *_logic.gsc script. Typically, these files are structured as follows:
/* Load the common scripts. */
/* Include other scripts for this level. */
/* The top-level function for this map. */
// Set up the event handlers for different scenes.
default_start( ::ride_start );
add_start( "ride", ::ride_start, &"STARTS_RIDE" );
/** ... **/
// Prepare the data, presumably for streaming...
/** ... **/
// Call main functions of dependent scripts.
maps_m1a1::main( "defaultvehicle" );
/** ... **/
// Globlal variables used for the game state.
flag_init ( "player_has_flashed" );
flag_init ( "return_fire" );
/** ... **/
// Launch micro-threads for the rest of the logic.
/** ... **/
// Spawn the entities that are part of the level.
left_rooftop_enemies = getentarray(
"left_rooftop_enemies", "script_noteworthy" );
::set_threatbias_group, "left_rooftop_enemies" );
/** ... **/
}There are many custom / one-off lines that were ignored in this example, but it outlines the rough structure of these scripts. The logic controlling individual characters when necessary is done in threads, which are also script functions.
Screenshot 6: Under attack from an enemy in the distance.
Summary & Further Information
This kind of approach to level scripting gives you a lot of control, especially with a well thought out API that has matured over the course of multiple games. However, it certainly takes a lot of coding, debugging and tweaking.
With over 12.4 Mb and 205,718 lines of level scripts (not including the automatically generated configuration files), it’s even more clear than ever that the behaviors in Call of Duty 4: Modern Warfare are the result of heavy labor and intense perfectionism.
For someone willing to get into mods for story-driven games, and who doesn’t mind the process of scripting, then this engine is the perfect fit!
Screenshot 7: Squad attacks in Call of Duty 4: Modern Warfare