sega 500 intro to bot ai jeff “ezeikeil” giles jgiles@artschool.com jgiles

Post on 28-Dec-2015

215 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Sega 500

Intro to Bot AI

Jeff “Ezeikeil” Gilesjgiles@artschool.comhttp://gamestudies.cdis.org/~jgiles

What Today Is

The plan is to look into what makes the AI in UT2003 tick and figure out some of it’s dependencies.

Also to see how we can influence it’s decision process.

What Today Isn’t

This is not a lesson on how to build a whole AI system given that doing so is a course on to itself.

Starting simple

Bare in mind that the exisitng AI code and it’s dependencies are HUGE and have with little documentation.

The result is that they bring much pain and suffering in figuring out the code…

Hence today’s code changes will have small effects on the pawn as figuring out this much took over a day and a half!

The result

Hopefully a reasonable starting point from which we can implement further changes.

So, lets get started.

What’s needed?

What are the 4 known components (classes) needed to get the AI system up and running?

( We’ve talked about some of these before )

Anyone?... Anyone?...Bueller? ...Bueller?

The Pieces

A Controller A Pawn A Gametype An AI Class

And…

The AI system in UT2003 is heavily dependant on states, so a good firm grasp of states, state programming and it’s inheritance rules is very much essential.

A controller

Controller. ( We’ve already talked about these.) They are the base class of players or AI. Controllers are non-physical actors that can be

attached to a pawn to control its actions AIControllers implement the artificial intelligence for

the pawns they control. Controllers receive notifications for many of the

events occurring for the Pawn they are controlling. This gives the controller the opportunity to implement the behavior in response to this event, intercepting the event and superceding the Pawn's default behavior.

A Pawn

Something to control. (And these) Pawns are the physical representations of

players and creatures in a level. Pawns have a mesh, collision, and physics.

Pawns can take damage, make sounds, and hold weapons and other inventory.

In short, they are responsible for all physical interaction between the player or AI and the world.

A game type

To specify which controller the bots are to use.

This can also be done via a mutator, but this is not a real good idea as the AI rules may not be synonymous with the game type.

The AI Class

What team, squad or deathmatch AI methods to use.

This determines just how a specific bot will related to its team mates.

PlayerReplicationInfo

Which basically says what’s doing what & how to replicate the game over a network.

Bare Bones

This is the core requirements that I’ve found to make changes & have an impact on the AI system.

There are other items which influence the Bots are such as AIScripts and ScriptedAction’s

So roughly

If we map out the basic class dependencies, we sort of see how things relate.

Keep in mind, this is a very simplified version.

Giving UT a Lobotomy

Getting down to the code, we’re quite probable going to cause the AI to behave erratically…such is the nature of playing with one’s neural pathways.

In effect, we’re going to cut out a portion of the decision process & insert our own.

Giving UT a Lobotomy

For simplicity, I’m creating a very simple gametype which is now derived off team Game

class AITest extends xTeamGame;

Doing so, allows us to only have to create one class at this time…Which is my new AI controller class which I deriver from xBot.

class EzeAI extends xBot;

Giving UT a Lobotomy

For now, I’m not going to do anything different. We just need the definition at this point.

And then in my AITest gametype, I create the following function…

Giving UT a Lobotomy

function PreBeginPlay()

{

class'xGame.xPawn'.default.ControllerClass=class'Eze.EzeAI';

super.PreBeginPlay();

}

Which simply tells our xPawn which AI controller to use by over riding the defaults.

Giving UT a Lobotomy

If you build & run now, you won’t see any changes. But it is using our new controller.

To prove it, I kept the old killed function from this game type and inserted a log entry.

log(" ----> Player: "$Killer.pawn.PlayerReplicationInfo.PlayerName$" is a “$Killer$" controller and a "$killer.pawn);

Giving UT a Lobotomy

Which simply spits out the player name, controller and pawn type.

The log reads:

ScriptLog: ----> Player: Hyena is a eze1.EzeAI controller

and a eze1.xPawn

Where eze1 is my test map…

Giving UT a Lobotomy

So, as you can see our Ai controller is in use, but it behaves exactly like the xBot controller.

But before we go about changing the AI properties, let me show ya something.

Giving UT a Lobotomy

I’m going to whip up a large, yet very simple map so that I can be outside of the pawns line of sight.

One start point…no pathing node, objects, nothing…

Giving UT a Lobotomy

And watch the bots behaviour when I run around the back to where I can’t be seen

X Start point

Giving UT a Lobotomy

Notice that the AI gets rather dense and just tends to stand around.

(a bit less so if version 2225 and the bonus pack are installer)

Giving UT a Lobotomy

This is because the path nodes, pickups and other placeable objects are integral to how the bots path finding is calculated

Notice the difference once I add a bunch of path nodes…

Giving UT a Lobotomy

Once I build the network after clicking the build paths button I’m rewarded with this:

Which is in effect a network of pathways where the bot CAN go…watch the bots move now…

Giving UT a Lobotomy Notice how much more aggressively they

move about the map. Actively searching for opponents.

Giving UT a Lobotomy

Right, so this being said, other than watching them…Is there a way to tell just what the bot is doing or thinking.

Yes there is, but I’m not talking about logging piles of information out to file or even using the debugger.

Giving UT a Lobotomy

If you poke through the code, you’ll find a fairly frequent occurrence of a function called DisplayDebug.

Which does just that…spews debug info to the HUD.

Giving UT a Lobotomy

Oh, dear sweet lord! In all your divine wisdom and glory…Where, prey tell, do I sign up for that!!!

Actually it’s pretty easy, no contracts in blood either.

Giving UT a Lobotomy

If you look in the controller, you’ll find

function DisplayDebug(Canvas Canvas, out float YL, out float YPos)

Which does just that…sweet! It’s done for us! We just need to know how to access it.

Giving UT a Lobotomy

Which means…A simple HUD class.

Here’s the whole thing

Giving UT a Lobotomy

function DrawHUD(canvas C){ local pawn targetP; local float space, msg1;//positional space=8;

super.DrawHud(c);

foreach RadiusActorS(class'pawn', targetP, 512, PawnOwner.Location) { if(targetP.controller != none) { c.Font=c.TinyFont; targetP.Controller.DisplayDebug(c,space,msg1); } }}

Giving UT a Lobotomy

Most of this code is self explanitory, The part we’re really interested in is:

We access the nearby controllers and draw the debug info to the screen.

targetP.Controller.DisplayDebug(c,space,msg1);

Giving UT a Lobotomy

Yeah…it’s pretty simple...

Here’s all the juicy goodness we get back…

Giving UT a Lobotomy

Giving UT a Lobotomy

Dude! Lots of info, Here’s a breakdown.

My Info

Bots controller

Bots state

Giving UT a Lobotomy

Where it’s goingDestination path node

Current orders Squad leader

Giving UT a Lobotomy

As you can see, this yields us lots of information, I’ll let you poke about it at you leisure.

But why am I doing it this way? Can’t I just use the ‘showdebug’ command to display this information?

Why?

We’ll, yeah I can.

However, doing so shows all sorts of information I’m not really interested in right now.

And it’s fairly specific to my pawn and controller.

Because…

Using this method, shows me exactly what I need to see.

Right…Now to make the AI do stuff.

Giving UT a Lobotomy

Simply, we’re going to insert some functionality into our EzeAI class.

Just to see if we can get it to work, I’m going to create a new roaming state…which is the easiest to get into.

Giving UT a Lobotomy

And once in there, cause them to bunny hope about the level, searching for an opponent.

Giving UT a Lobotomy

state myRoaming extends Roaming{Begin:

SwitchToBestWeapon();WaitForLanding();

<SNIP!>

Pawn.doJump(True);

DoneRoaming:WaitForLanding();WhatToDoNext(12);if ( bSoaking )

SoakStop("STUCK IN ROAMING!");}

Giving UT a Lobotomy

So, here’s what’s going on. We’re using and abusing the state inheritance rules so that we don’t have to write the whole state structure again…that would be bad.

state myRoaming extends Roaming

Giving UT a Lobotomy

Remember our state inheritance rules: If a state doesn't override a state of the same

name in the parent class, then you can optionally use the "extends" keyword to make the state expand on an existing state in the current class

What this means to us is that we keep all the functions, but override the labels… Hooray for inheritance.

Giving UT a Lobotomy

But how do we get into our state?... The bot class has 2 functions for causing

a state change to roaming function Restart() & function

SetAttractionState() It’s inside these where I found gotostate(‘Roaming’), I changed it to gotostate(‘myRoaming’).

Giving UT a Lobotomy

At this point, don’t really care what these functions do, we’re lobotomizing UT remember?

Giving UT a Lobotomy

When they enter myRoaming state, they get all giddy and start hopping about the map.

Giving UT a Lobotomy

For additional states & functions to over ride to cause changes in the bot.uc class & have a look.

Most (but not all) of the bots are behaviours are done here.

Additional changes are done at the squad level, which we’ll look at tomorrow.

top related