Coding Unreal Tournament3 Bots

Have you ever played a first person shooter? Then you've probably played against computer controlled players known as "bots" which are computer programs designed with artificial intelligence. Up until now the only way to do create your own bot for a game like Unreal Tournament 3 was to learn a bunch of C++ and complicated AI routines. Of course, what you really want to do is code up your bot using C# or VB and Visual Studio Express. So here is a way to do just that.

Your First Bot

Once you've created a new bot you'll have a very basic class with just a constructor and an overridden ProcessActions() method.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using UT3Bots;
using UT3Bots.UTItems;
using System.Threading;
using UT3Bots.Communications;


namespace UT3UserBot
{
    public class MyBot : UTBot
    {

        //Constructor for your bot
        public MyBot() : base ("174.133.254.34", "Sitting Duck", BotMesh.Harbinger, BotColor.Red)
        {
        }


        //Method to control the bot once it has connected to the server
        protected override void ProcessActions()
        {
            //Add code here to perform some actions at specific intevals
        }
    }
}
VB
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text

Imports UT3Bots
Imports UT3Bots.UTItems
Imports System.Threading
Imports UT3Bots.Communications


Namespace UT3UserBot
    Public Class MyBot
        Inherits UTBot

        'Constructor for your bot
        Public Sub New()
            MyBase.New("174.133.254.34", "Sitting Duck", BotMesh.Harbinger, BotColor.Red)
        End Sub


        'Method to control the bot once it has connected to the server
        Protected Overloads Overrides Sub ProcessActions()
            'Add code here to perform some actions at specific intevals
        End Sub
    End Class
End Namespace

Setting Up Your Bot

The first thing you need to do for your bot is configure it with a look and feel, and then actually connect to the server and get in the game. This is pretty straightforward, all you need to do is alter the parameters that are getting sent up to the base bot class in the constructor.

  • Server IPAddress - The first parameter is the IPAddress of the server to connect to. By default this points to the UT3Bots server we have running on the internet (ut.utbots.com), you'll need to alter this to point to the server you need to connect to.
  • Name – The name of your bot will be seen on the Visualizer and in game.
  • Bot Mesh – This is the appearance of your bot on the server.
  • Bot Color – This is the color of your bot.

Now you are ready to join a UT3 game.

Pressing F5 will build and run your bot. The bot project will load up a little console application which provides info about what your bot is doing.

Bot's First Sight

Now that we have a bot in the game we need to make it actually do something. The first thing we are going to make it do is move to a UTNavPoint. This is a location in the game which might hold something interesting. A series of UTNavPoints provide a path through the level to interesting items. A bot can travel around a game level by moving from one UTNavPoint to another.

Within the game framework (UT3RemoteBot.dll), an instance of the UTVector class can be used to express the actual location of something. The location of a UTNavPoint is given by its Location property, which is given as a UTVector value.

Our bot needs to have a way of keeping track of where it is going so in the UT3UserBot class create a new private UTVector called destinationLocation

C#
private UTVector destinationLocation;
VB
Private destinationLocation As UTVector

We want our bot to head towards the first navpoint that it “sees”. To do this we place the following code into the ProcessActions() method.

C#
this.destinationLocation = this.GameState.NavPointsVisible[0].Location;
VB
Me.destinationLocation = Me.GameState.NavPointsVisible(0).Location

The GameState property of our bot contains information on the current state of the game. NavPointsVisible is a list of references to UTNavPoint instances which refer to all of the UTNavPoints a bot can currently see. The above code simply takes the UTVector at position 0 (the first navigation point your bot can see) and sets destinationLocation to refer to it.

So at this point the bot has identified the location it wants to move towards, now we have to make it move in that direction.

Bot's First Steps

Now we are going to make our bot move to the destination it has selected. Place the following code into the ProcessActions() method just below the code written in the previous example.

C#
this.Commands.RunTo(this.destinationLocation);
VB
Me.Commands.RunTo(Me.destinationLocation)

The Commands property provides a set of methods which are the commands that your program can give to the bot. There are a wide range of commands, some of which are listed below. For full details you should investigate the API reference.

  • Jump() - Jumps in the air
  • RotateBy() - Rotates by a specific number of degrees
  • RunTo() - Runs to a specific location
  • StartFiring() - Attacks a target or location
  • StopFiring() - Stops the bot from shooting
  • StrafeTo() - Strafes to a specific location while looking at another

The RunTo() command is provided with a destination location. When this method is called your bot will start running towards the destination.

If you execute this program you will see your bot start running towards a navigation point.

Bot's First Shot

For the purpose of this example we will next make our bot shoot at the location it is running towards, it is recommended that you change this when creating your own implementation as shooting at an empty UTNavPoint is unlikely to get you many frags.

Place the following code into the ProcessActions() method just below the code written in the previous example.

C#
this.Commands.StartFiring(this.destinationLocation, false);
VB
Me.Commands.StartFiring(Me.destinationLocation, false)

If you execute the program you will see that your bot now shoots at the location as it runs towards it. It will continue running and shooting until you call a method to instruct it to stop, or it runs out of ammo!

Place the following code into the ProcessActions() method just below the code written in the previous step.

C#
this.Commands.StopFiring();
VB
Me.Commands.StopFiring()

Your bot will now stop shooting.

So you now know how to get your bot to do something in the game. Running around and shooting things is as easy as using the GameState property to access what your bot can see, and the Commands property to call methods that perform actions.

Bot's First Reaction

Now we are going to make the bot react to things that happen in the game. This is done by subscribing to any of the events that the bot exposes through its Events property. We normally want to subscribe to the game events as soon as the bot starts, so that we get all the juicy information that we can use to make a clever bot. You can do this by attaching an event handler to an event in the constructor for your bot.

In this example we will subscribe to the OnSpawned event which is trigged whenever the bot spawns in the game, whether this is the first time, or after it has died.

Place the following code into the constructor of the MyBot class.

C#
this.Events.OnSpawned += new EventHandler<BotSpawnedEventArgs>(Events_OnSpawned);
VB
AddHandler Me.Events.OnSpawned, AddressOf Events_OnSpawned

You also need to add a new method to the class that will be called when the bot spawns.

Place the following method code into the MyBot class.

C#
void Events_OnSpawned(object sender, BotSpawnedEventArgs e)
{
    this.Commands.PerformEmote(Emote.PelvicThrust);
} 
VB
Private Sub Events_OnSpawned(ByVal sender As Object, ByVal e As BotSpawnedEventArgs)
    Me.Commands.PerformEmote(Emote.PelvicThrust)
End Sub

Your bot will now start performing some fetching pelvic thrusts whenever it spawns in the game. This won't actually help you get any extra frags, but maybe it'll start a new craze!

There are many different events you can attach handlers to which will allow you to change your bot behavior to react to different circumstances. For full details you should investigate the API reference or check out Visual Studio's intellisense.

Viewing Your Bot In Action

You can easily find out what your bot is up to by using the special Silverlight 2 visualizer we have created. When you open the visualizer web page in your browser, you can automatically see the status of the server running the Bot game type and get a bird's eye view of the game in progress. You can see the waypoints which are marked by green dots and the active players which have their name next to moving circles with a line indicating which way they are facing. From here you can view the game and see what your bot is doing as shown in the visualizer screenshot.

clip_image002

What To Do Next

Now that you have got your bot into the game and made it move around a bit you can start thinking about making it into a decent player of the game. Take a look at the other members of the GameMap class so that your bot can look for weapons and health packs and move towards them. Then take a look at the members of the GameState class for the information that your bot is given about the game around it.

One thing you will need to add is some way that your bot can be in a particular state at any given time. Sensible states might be "Roaming", "Hunting", "Idle", "Recovering", etc. Depending on the state your bot is in it will do different things each time ProcessActions is called.

If it is in the roaming state, for example, it will be looking for a navigation point. If it is in the hunting state it will be chasing other bots. If it is in the recovering state it will be avoiding other bots and looking for a health pack, and so on. You can keep track of the state of your bot by creating an enumerated type with the different values. Then your ProcessActions method can contain a switch statement which makes it behave differently, depending on what it is doing.

A state machine is just one way you could program your AI, you could make a sophisticated bot that had a way of determining if a result had a positive or negative consequence and then have the bot perform more actions that had a positive consequence. Essentially a learning bot, be careful though if your bot takes too long executing ProcessActions it will get out of touch with the game as messages will sit on the queue unprocessed waiting for your code to finish.

Conclusion

With this quick getting started guide you should be able to go about creating your own UT3 Deathmatch player. There are also some very handy hints in the FAQ below about getting your bot on the road to stardom.

If you're feeling particularly brave join our project on CodePlex at http://www.codeplex.com/UT3Bots and help pitch in with improving the bot client, the visualizer, or even the server mutator.

Happy Fraggin'!

Tags:

Follow the Discussion

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.