Technical Samples     Tutorials     Web Player Commands     Demo

Demos

Shaders
Crash Cube
HydroBoat Race
Muridae Massacre
Sound Island
Tunnel

Making of Muridae Massacre: Designing Autonomous Characters

One of the technical concerns of the MM project was the AI and motion planning brains of the characters. It was a point of focus for several reasons: much of the game’s design hinges on the capabilities of the rodents to react to their world, the brains would be the most advanced system in the game, and the project’s programmer was inexperienced in implementing AI.

To address these concerns, existing research on autonomous agents was investigated. One of the difficulties in finding applicable research was the fact that only one general programmer was on the project. Much of the body of knowledge on autonomous agents and robotics is from the academic world, and well beyond the abilities of the artist-heavy team.

However, Craig Reynold’s research into Steering Behaviors for Autonomous Characters provided “techniques for obtaining goal-directed motion in self-directed animated characters” (http://www.red3d.com/cwr/steer/). Additionally, the techniques presented in his research are designed for real-time uses and easily applied to a game environment. MM used his steering behavior model as a base for designing the rodent brains.

The locomotion model in MM relies on two vectors. One vector represents the velocity; the per-second value of this vector is added to the character’s position each frame. The second vector represents the steering force; the per-second value of this vector is added to the velocity each frame. Other variables are used to constrain aspects of locomotion; maximum velocity and maximum steering variables are used to limit speed and turning ability.

In practice, implementation of steering behaviors breaks down into two objectives. The first is to implement some sort of mover. This script will be responsible for applying the steering vector to the velocity vector, and then updating the position of the character each frame. Implementing such a script in Dev is a fairly straightforward task. The example script is Behavior: Simple Mover applied to the Characters group in the included composition. This script makes no intelligent decisions—it is assumed other scripts will set the Motion – Current Steering Force attribute value. This separation of locomotion and behavioral calculation is valuable; CPU intensive behavioral calculations can be spread over several frames without disrupting character motion.

The second objective of implementing steering behaviors is to implement logic that will set or modify the steering vector. This is where the bulk of the work is, and where most of the time developing MM was spent. Reynold’s research covers several useful behaviors as examples. MM implemented many of these behaviors as the core behaviors of the in-game characters. The included example composition demonstrates seek, wander, and collision avoidance.

The seek behavior produces a steering vector that will steer the characters towards a specified point. To calculate this vector, first a desired velocity is determined by subtracting the goal’s position from the character. This produces a vector in the direction to the target from the character. The steering vector is the difference between this vector and the character’s current velocity.

Wander is a behavior to produce just that—a wandering motion. The goal of the wander behavior is to produce random steering in such a way that the character doesn’t behave too erratically. Simply using a random steering vector each frame would produce very jittery motion. The wander algorithm used by MM is roughly the same as the method proposed by Reynold’s research. An angle is stored as an attribute on each character and modified each frame by a random amount. To produce a steering vector, this angle is converted into a position on a circle located ahead of the character. The end result is a very decent wander motion, with sweeping turns and occasional straight or wavering motion.

Collision avoidance produces a steering vector to avoid obstacles before collision occurs. The implementation in MM checks for any obstacles within a specified distance and angle from the character’s forward axis. If an obstacle is present, its import is weighted from –1 to 1 based on its distance from the character and forward axis. This weight is summed with weights from all other obstacles detected. The steering vector is the character’s side axis multiplied by the weight (such that the character turns left if obstacles are on the right side, and vice versa).

To produce the final steering vector, the component steering vectors from each of the individual behaviors are weighted and summed. The base vector is the seek vector, as the goal of the characters in the game is to reach the goal. A slight amount of the wander steering vector is added in to produce more interesting and unpredictable behavior. Finally, the collision avoidance vector is added in with heavy weighting, since the avoidance behavior only occasionally produces a non-zero value (and if there an obstacle to avoid, avoidance should take precedence).

The sample composition "brain example.cmo" toggles through various weights of the component behaviors, as well as varying amounts of obstacles to avoid. A solid trail is used to better visualize where the character has traveled. For more technical information on the implementation, browse around the commented schematic code.

Muridae