Game Creation with XNA/AI/AI Engines
Today it is a common approach to create solutions which are an overall package for specified topic. These solutions are often called engines. Every day there mushroom new ones. For example for 3D graphics, sound, network and even for artificial intelligence which is especially for games. These AI-Engines for games solve several problems, which often appear in the procedure of creating games, like pathfinding, decision making, learning, movement, tactical and steering behavior, etc. So there are even several AI-Engines and libraries which provide some of those algorithms. These give you the ability to make your games more intelligent and challenging.
Available AI Engines for XNA
SharpSteer by Bjoern Graf and Michael Coles is a C# portation of OpenSteer(C++) which is an open source library to help construct steering behaviors for autonomous characters in games and animation and it is distributed in accordance with the MIT License . Its last release was in March 2008 and it is designed for XNA 2.0, but it also works at 3.1. There is a demand to port it on XNA 4.0, but the conversion has not happened yet . As the name implies SharpSteer's responsibility relies on steering behaviors like cohesion, separation, alignment and many more. Its actual version includes a demonstration of 200 simulated flocking bird like objects which are also called boids . In SharpSteer boids can be everything (a football player, an enemy soldier, a car) in a game. It must at least have the SharpSteer's interface IVehicle. The most important class is the SteerLibrary.cs. It is the heart of SharpSteer which consists the main algorithms for the steering behavior:
- The alignment behavior: Move in the average direction of other nearby vehicles
// Alignment behavior public Vector3 SteerForAlignment(float maxDistance, float cosMaxAngle, List<IVehicle> flock)
- The cohesion behavior: Move the average position of nearby vehicles.
// Cohesion behavior public Vector3 SteerForCohesion(float maxDistance, float cosMaxAngle, List<IVehicle> flock)
- The separation behavior: Move away from other nearby vehicles to avoid crowding
// Separation behavior -- determines the direction away from nearby boids public Vector3 SteerForSeparation(float maxDistance, float cosMaxAngle, List<IVehicle> flock)
These 3 functions get 3 equal parameters: The float value maxDistance defines the proximity area in which other vehicles affect this vehicle. The float value cosMaxangle defines angular borders in which other vehicles do not affect this vehicle. Obviously the list of IVehicle contains all the vehicles that may have the ability to influence this vehicle. But that is not the end of the story. There are also:
- The evasion behavior: Move away from a specific vehicle.
// evasion of another this public Vector3 SteerForEvasion(IVehicle menace, float maxPredictionTime)
The value menace is the vehicle that should be avoided. The value maxPredictionTime is the point of time to forecast the menace's future position.
Furthermore ther dozens of other behaviors:
public Vector3 SteerForWander(float dt) // Seek behavior public Vector3 SteerForSeek(Vector3 target) // Flee behavior public Vector3 SteerForFlee(Vector3 target) // Path Following behavior public Vector3 SteerToFollowPath(int direction, float predictionTime, Pathway path) public Vector3 SteerToStayOnPath(float predictionTime, Pathway path) // Obstacle Avoidance behavior public Vector3 SteerToAvoidObstacle(float minTimeToCollision, IObstacle obstacle) // avoids all obstacles in an ObstacleGroup public Vector3 SteerToAvoidObstacles<Obstacle>(float minTimeToCollision, List<Obstacle> obstacles) where Obstacle : IObstacle // Unaligned collision avoidance behavior: avoid colliding with other // nearby vehicles moving in unconstrained directions. Determine which // (if any) other other this we would collide with first, then steers // to avoid the site of that potential collision. Returns a steering // force vector, which is zero length if there is no impending collision. public Vector3 SteerToAvoidNeighbors<TVehicle>(float minTimeToCollision, List<TVehicle> others) where TVehicle : IVehicle // Given two vehicles, based on their current positions and velocities, // determine the time until nearest approach public float PredictNearestApproachTime(IVehicle other) // Given the time until nearest approach (predictNearestApproachTime) // determine position of each this at that time, and the distance // between them public float ComputeNearestApproachPositions(IVehicle other, float time) // avoidance of "close neighbors" -- used only by steerToAvoidNeighbors // XXX Does a hard steer away from any other agent who comes withing a // XXX critical distance. Ideally this should be replaced with a call // XXX to steerForSeparation. public Vector3 SteerToAvoidCloseNeighbors<TVehicle>(float minSeparationDistance, List<TVehicle> others) where TVehicle : IVehicle // ------------------------------------------------------------------------ // pursuit of another this (& version with ceiling on prediction time) public Vector3 SteerForPursuit(IVehicle quarry) public Vector3 SteerForPursuit(IVehicle quarry, float maxPredictionTime) public Vector3 SteerForTargetSpeed(float targetSpeed)
Simple AI is an engine for XNA written by Piotr Witkowski and features gridded maps, a pathfinding algorithm, pathfollowing and behaviours such as find path, follow path, goto, stay in formation. Contrary to SharpSteer which specialises in steering behavior like cohesion, alignment and separation this engine focuses on various graphs and pathfinding with A*. Thus the behaviors are linked to the graphs which are represented as a grid and they rely on pathfinding algorithms.
This library is a lightweight. It just offers A*, Depth and Breadth search. It works with XNA 3.1 and 4.0. Based on its small size it is highly adaptable.
Other AI Engines
If you want to write your own engine, you have to think about its structural design. You should consider the purpose which invokes if it is a more general solution or special one for a specific kind of game. Furthermore there must be a general mechanism for the decisions which behavior is the actual one equal which AI algorithm is used. So every algorithm has to subordinate this mechanism. Nonetheless your AI-Engine's mechanism includes an interface for your algorithms interacting with your game world, because without senses(input)ther is no appropriate reaction(output). Of course there should be a connection between the behavior and the animation of your intelligent acting game objects. In addition your engine's architecture makes it applicable to extend the engine itself and their algorithms by anybody who wants to write his own behavior or who wants to install a new AI-technology. As always you should esteem re-usability, adaptability and maintainability. So the complete AI engine will have a central pool of predefined AI algorithms that can be applied to any kind of game objects for any kind of game, whether it is a shooter or textbased adventure, if the AI-Engine is a general solution.
Should talk about available engines (maybe not only XNA) for dealing with AI.
For instance the Nelxon Website lists the following engines for artificial intelligence:
- Engine Nine – has a Path Finding and steering behaviors included
- SharpSteer – I found a million and 1 uses for this…
- State machine-based behavior models - Good Article, sample old..
- Steering Behaviors, Obstacle Avoidance – good Example (in spanish)
Some interesting code examples can be found here: http://create.msdn.com/en-US/education/catalog/?devarea=11
nexuschild gets into it
- Artificial Intelligence for Games by Ian Millington
- http://www.nelxon.com/681/xdsk2/ Nelxon, XSDK2-Resources for Developers using XNA 4.0