Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

FPSC Classic Scripts / AI Scripting Tutorial

Author
Message
Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 14th Mar 2008 09:34
Hello, everyone! I got bored tonight and decided that I'd make another scripting tutorial.



Plystire's AI Scripting Tutorial


Let's start by brainstorming. (As with all creations, this is the best place to start)

Most people want to simply make AI but don't know where to start, so let's start by imagining what we want our AI to do.

I think a smart AI should be able to patrol an area via waypoints, shoot at the player if it sees them, and follow the player once it has already started shooting. Also, I believe a smart AI won't stand there taking hits all day, so I want it to strafe around randomly so that it'll be harder for the player to get a hit in. I bet a further target would be a harder to hit target, so I don't want the AI to get very close to the player.

Alright, brainstorming over with for now, let's make a list! (Because I know you all love lists, am I right? )

Things our AI should do:

- Patrol Waypoints
- Start shooting player if it sees them
- Strafe randomly if close enough to player
- Follow player around, but don't get too close.

That sure SOUNDS easy, but let's start scripting and find out how easy it's really going to be.


STEP #1: Patrolling Waypoints

Alrighty, first thing on the list is to make it patrol waypoints.

Let's take a look into the manual and see what scripting commands we can find that are related to waypoints.

.
.

Conditions:
Quote: "WAYPOINTSTATE=X

is true when the waypoint state value equals X.

State 0 means the entity has not yet started following
waypoints

State 1 means the entity is looking for the nearest waypoint
marker to start from

State 2 means the entity is following a waypoint line to its
current waypoint marker

State 3 means the entity has reached the waypoint marker and
needs to decide what to do

State 4 means the entity has reached the waypoint marker and
it splits off in more than one other direction

State 5 means the entity has reached the very end of the
current waypoint structure and requires a decision to be made.

A state of 999 means the entity has been placed in zero-
waypoint mode where the entity simply ignores waypoints."


Wow, that's a lot to read, but the more detailed the description the better, as I always say.

Actions:
Quote: "WAYPOINTSTART
instructs the entity to find the closest waypoint

WAYPOINTSTOP
stops the entity following waypoints

WAYPOINTREVERSE
makes the entity reverse course and go the other way

WAYPOINTNEXT
instructs the entity to find the next waypoint

WAYPOINTPREV
instructs the entity to find the previous waypoint

WAYPOINTRANDOM
instructs the entity choose a random waypoint direction"


Awesome! We got lots of actions to choose from, so this will make it easier on us.


I think we have enough information now to start coding our Waypoint Patrolling section of the script.

To start off, let's think of how we can mesh these commands together to get our AI doing what it should be doing.

When it first spawns it should begin it's patrol. We know that when it first spawns, it isn't following a waypoint, right? So, then we can safely assume that our AI's "waypointstate" is going to be 0, according to what the manual says.

With that in mind, we can come up with this piece of code:



Deng, that was easy.

Now that he's on his way to the nearest waypoint, his "waypointstate" should be equal to 1. That's fine, we don't want him to be doing anything different while he's already walking.... WAIT! Walking? We need to make him walk, too! Otherwise, he'll just glide along his merry way.

Let's find us some animation commands to make our AI look like he is walking.

The manual gives us lots of commands to deal with animating, but only one in particular will do what we want here:

Quote: "ANIMATE=X

automatically play animation X.
In regards to characters provided, there are a number of
animations built in which can be played. These are:
0 = Spawn
1 = Idle
2 = Move Slow
3 = Strafe Left
4 = Strafe Right
5 = Move Fast
6 = Reload Weapon (or Toss)
10 = Climb
11 = Impact Front
12 = Bounce Front
13 = Get Up Front
14 = Impact Back
15 = Bounce Back
16 = Get Up Back
17 = Impact Left
18 = Bounce Left
20 = Impact Right
21 = Bounce Right
31 = Crouched Idle
32 = Crouched Move Slow (same)
33 = Crouched Strafe Left (same)
34 = Crouched Strafe Right (same)
35 = Crouched Move Fast (same)
36 = Crouched Reload Weapon (or toss)
40 = Freeform Idle
41 = Freeform Move
50 = Weapon Spawn
51 = Weapon Idle
52 = Weapon Move Slow
53 = Weapon Strafe Left
54 = Weapon Strafe Right
55 = Weapon Move Fast
56 = Weapon Reload Weapon (or Toss)
57 = Weapon NEW Climb
61 = Weapon Impact Front
62 = Weapon Bounce Front
63 = Weapon Get Up Front
64 = Weapon Impact Back
65 = Weapon Bounce Back
66 = Weapon Get Up Back
67 = Weapon Impact Left
68 = Weapon Bounce Left
70 = Weapon Impact Right
71 = Weapon Bounce Right
81 = Weapon Crouched Idle
82 = Weapon Crouched Move Slow (same)
83 = Weapon Crouched Strafe Left (same)
84 = Weapon Crouched Strafe Right (same)
85 = Weapon Crouched Move Fast (same)
86 = Weapon Crouched Reload Weapon (or toss)
90 = Weapon Freeform Idle
91 = Weapon Freeform Move"


Whoa! That's some heavy stuff goin on right there! But, we got what we wanted. A single command to automatically play (and loop) any animation that the entity has!

Hmmm, looking in the list, animation number 52 (Move Slow) looks like what we want, so let's put it in.



Awesome, now our Ai will have a walking animation while he goes to his first waypoint!

Now, once he gets there, what is he going to do? And how can we tell if he's there or not?

Well, the "waypointstate" should be equal to 3 if it reached the waypoint. So, once it gets there let's have it move to the next one in line. And, while we're at it, let's make him animate the walk also.



Alright, that takes care of that! Now our Ai should be finding waypoints and following them until the end. Speaking of end, we gotta make sure the AI knows what to do when it gets there!

If the AI is at the end of the waypoints, the "waypointstate" should be equal to 5, right? Welp, once it does equal 5, let's have it reverse direction and go back.



There, that should do it. However, this will only work if our AI is following a stream of waypoints that don't have multiple paths to take. Let's make our AI follow a random waypoint if it comes to a fork in the road... so to speak.

If it finds a branch, then the "waypointstate" will be equal to 4, according to what the manual says:



Okay, that looks like it'll handle pretty much everything we want it to.


What's next on the list?


Step #2: Shoot Player if Seen

Now that our AI is a Waypoint walking fool, let's have it shoot the player if it sees them.

As per our protocol, let us consult the manual for any useful commands!

.
.

Conditions:
Quote: "PLRCANBESEEN
is true when player can be seen

PLRCANNOTBESEEN
is true when player cannot be seen "


Actions:
Quote: "ROTATETOPLR
rotate the entity to face the player

SHOOTPLR
runs the internal FPI script SHOOT specified in character properties"



Okay, looks like we got our work cut out for us here. But, not to fear! Your faithful leader will get us through this!

I gotta explain a couple things here. Firstly, to keep our scripts clean, we don't want to pile ALL of our AI's code into one script. You'll notice that the action "shootplr" will call up a different script. We'll code that script as well, and it will handle the chasing and shooting of the player. Right now, we need to determine if we should start using that script or not. With that said, HERE WE GO!

First up, we gotta find out if the AI can see the player. We can use the "plrcanbeseen" condition for that. Then, if it CAN see the player we want it to rotate to the player and start shooting!

However, our AI is currently following waypoints, so we need to tell him to stop, and also to stop doing it's walk animation! Well, according to our list of animations, animation number 51 (Idle) is the one we're looking for.

Sounds like a plan, so let's script it!

As per proper scripting, we don't want everything to happen at the same time, so we need to break it up into states:



Okay, so now our AI knows that if it sees the player it should stop walking the waypoints, play the Idle animation, and run it's "Shoot" script, which is given to it in it's properties.


Alright! Now, we'll assume that our AI has spotted the player is now running it's "Shoot" script, so now we have to make it!


Step #3: The Shoot Script, Following and Firing

Let's open up another Notepad (or your preferred FPI editting tool ) and start to work on our Shoot script.

In this script, we already know that the player has been spotted and we should have already rotated to face the player.

What should happen now?

Well, we need to take some situations into account, and for this, we're gonna make a list:

- The Player is far away
- The Player is very close
- The Player is within desired range
- The Player disappeared from view

Okay, let's look at our first situation. If the player is far away, we want to get into range. I think the range of our AI should be between 4 segments away and 5 segments away, translating into a distance of 400 to 500.

If the player is further than 500 units away, we should move in closer.

Coupling with this situation we have the other situation that the player is very close to us. So, if the player is closer than 400 units, we're gonna want to back up.

Remember, when making the AI move, it has to animate correctly as well. During combat a nice run seems like a good animation, so animation number 55 (Move Fast) would be nice for this.

Consulting the manual we come up with some commands to help us out here:

Conditions:
Quote: "PLRDISTWITHIN=X
is true when player is within X units

PLRDISTFURTHER=X
is true when player is further than X units"


Actions:
Quote: "MOVEFORE=X
moves the entity forward by X units

MOVEBACK=X
move the entity back by X units"


Now, let's start our script before our heads get too full of ideas and we start to forget things.



Alright, now our AI can move forward and back up if necessary. But as of right now, our AI doesn't know how to STOP moving, so let's put that in there and satisfy situation 3 where the AI is within the desired range.



Okay, now, our AI will do the Idle animation if it's in the desired range.

With that in place, let's look at our last situation, where the player disappears from the AI's view. We don't want our AI to try shooting through the wall, so let's look in the manual and see what we can find.

.
.

Actions:
Quote: "FOLLOWPLR
follows the players trail if one exists"


Wow, that seems rather specific to our needs, doesn't it?

We want the AI to follow the player if the player can't be seen, and once it finds the player again, to resume what it was previously doing. We'll want to make the following part of our AI a seperate state.

We already have an action to check if the player disappeared from view, so let's code this:



Okay, now that we have our AI following the player around and dauntlessly staring them in the eyes, let's have it start shooting.

Again, we must consult the mighty manual for advice:

Conditions:
Quote: "PLRINGUNSIGHT=X
is true when an entity has the player is gun sights [and X equals 1]"


Actions:
Quote: "USEWEAPON
fires any weapon half by an entity in the direction of the target"


Well, there we have it. If the player is in gun sight, we'll use our weapon! That sounds pretty simple. Point and click, really.

Remember, we only want to shoot when we have the player in sight, so this will go into state 1.



And there we have it. Our AI will now shoot the player until it runs out of ammo.

.
.

Ammo? Awwww ****, we gotta make sure that our AI reloads properly!

Okay, manual time!~

Conditions:
Quote: "IFWEAPON=X
is true when the weapon being used by entity is ready and X is one"


Actions:
Quote: "RELOADWEAPON
reloads the weapon from the entities stock of infinite ammo"


That condition sure seems cryptic, but to me it looks like we can check if the weapon is NOT ready (meaning out of ammo) but checking it against zero. Then, if our weapon isn't ready, we gotta reload!

Also, we'll need to make sure that we animate our AI to reload it's weapon. Animation 56 (Reload) is perfect.

Now, remember that reloading is instantaneous for AI, and that's not very fair to the player, so we'll need to animate this one ourselves instead of autoplaying it.

Here's what the manual gives us about animating manually:

Conditions:
Quote: "FRAMEATEND=X
is true when animation X is at an end

FRAMEATSTART=X
is true when animation X is at the beginning"


Actions:
Quote: "SETFRAME=X
set animation X start frame

INCFRAME=X
increment another frame in animation X"


This one is going to be a little more complicated than our auto-playing action. Oh well, it's for a good result, right? RIGHT!

First things first, we'll want to check if our AI is out of ammo, then we'll want to set up a "Reload State" that the AI can go to when it runs out of ammo. In that state, we'll show the reload animation and after it's finished we'll return to our shooting state.

Right before moving to our reload state, we want to start up our reload animation, then once we get to the reload state, we'll want to increment through the frames until we get to the end. I'm going to make state 10 be our reload state.

And we're off!



Okay, now our Ai will show a reload animation when reloading, and return to his normal state when he's done.


Step #4: Strafing

Recall that we also wanted our AI to strafe around so that it'll be harder for our player to hit them.

Manual saaaaaays:

Actions:
Quote: "CHOOSESTRAFE
randomly selects a strafe direction (ie left/right/forward)

STRAFE
perform the previously chosen strafe to avoid player shots"


If only these commands worked as promised this would be cake! Unfortunately for us, the choosestrafe command doesn't seem to act quite right with the strafe command.

Allow to rephrase the "Strafe" command:

Quote: "STRAFE=X
Will force the entity to strafe in the direction specified by X degrees from the forward position.
Negative X will be towards the entities Left, while a Positive X value will be towards the entities Right"


So, if you gave Strafe a value of "90" it would strafe directly to the Right.

Also, the strafe command doesn't animate the entity with the proper strafe, so we'll need to do that ourselves as well.

This look like it could take some work!

First, we'll want to set up a way to tell if we're in range of the player, then if we are, we'll want to choose a random direction to strafe in. After strafing, we'll want to check our distance again.

Hmmmm, let's think about how we can set this up.

Okay, i got it! If our Ai is within range, we'll go to a "Strafe State" (we'll use state 5 for this). In this state, we will randomly choose a strafing direction by using the following condition I found in the manual:

Quote: "RANDOM=X
is true when a random value between 0 and X is equal to one"


So, basically, this condition will randomly be true. The higher the value of X, the less likely it will be true.

I'm going to use a 50/50 chance here and go with "random=1".

If our condition returns true, we'll want to go to a state specificly designed for that strafing direction, and set up the animation for it as well.

We also want to continue shooting the player and rotating to them while strafing. This means we'll have to check for reloads, as well as if the player is in gunsight.

Now, let's start scripting:



Wow, that sure added on a lot of code!

Alrighty, so our AI can strafe, shoot, follow, and walk waypoints like a reigning champ!



After all that work, we finally have something to show for it! Two whole scripts that will make a semi-smart AI.

For quick reference here they are:

Final Main AI Script


Final Shoot AI Script



There we have it. A very complicated process broken down... and we at last have something to show for it!

With this knowledge, you can probably go out and make your own, better AI (which you probably should, since it will make your games more unique)



This is your host, Plystire, signing off!

*kzzzzzzzzt!*




The one and only,
~PlystirE~

Nickydude
Retired Moderator
18
Years of Service
User Offline
Joined: 4th Nov 2006
Location: Look outside...
Posted: 14th Mar 2008 10:22
You know where this will be going don't you, if that's ok.

Flatlander
FPSC Tool Maker
17
Years of Service
User Offline
Joined: 22nd Jan 2007
Location: The Flatlands
Posted: 14th Mar 2008 10:26 Edited at: 14th Mar 2008 10:28
Thank, thank you very much, the one and only ~PlystirE~

You deserve to rest.

-- Terry

Edit: Yes, it belongs there NickyDude. BTW, I'm printin' this one out.
xplosys
18
Years of Service
User Offline
Joined: 5th Jan 2006
Playing: FPSC Multiplayer Games
Posted: 14th Mar 2008 15:26
I'm also printing this out and would like to add it to the short list of tut's at fpsFREE.com Please let me know and thanks for all the work. You've cleared up some issues for me, and provided a base for the non/new scripter to get started.

Very well done.

best.

Seth Black
FPSC Reloaded TGC Backer
19
Years of Service
User Offline
Joined: 22nd Feb 2005
Location: Pittsburgh, PA
Posted: 14th Mar 2008 16:33
...this is huge, Plystire.

Many thanks!

ARE YOU A LONE WOLF? CLICK BELOW TO JOIN THE PACK.

Keo C
17
Years of Service
User Offline
Joined: 3rd Aug 2007
Location: Somewhere between here and there.
Posted: 14th Mar 2008 16:41
Quote: "...this is huge, Plystire.

Many thanks!
"

What he said!


Image made by the overworked Biggadd.
Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 14th Mar 2008 20:30 Edited at: 14th Mar 2008 20:48
Thanks, everyone. I must have spent a little over 3 hours putting that together. Makes me feel really good to see such wonderful remarks.

@Nickydude & xplosys:

Feel free to redistribute as-is (All the way up to the *kzzzzzzzt!*, cuz I just don't feel like it'd be complete without it, lol), so long as credit is given, of course.

@Seth Black & Keo C:

Yup, after posting, I had to sit and marvel at how long it turned out to be.

I would have made it shorter, but really, this sort of topic NEEDS the extra attention to detail. As with all my tutorials, I made it up as I went along. Where ever you see the "..", that's either me looking something up or reconsidering something, lol. I learned a few things by writing this, especially about strafing.


The one and only,
~PlystirE~

Seth Black
FPSC Reloaded TGC Backer
19
Years of Service
User Offline
Joined: 22nd Feb 2005
Location: Pittsburgh, PA
Posted: 14th Mar 2008 20:41
Quote: "...I had to sit and marvel at how long it turned out to be..."


...nope. It's perfect just the way it is, PlystirE.

TGC should pick you up as the official tutor for their products (they really offer no help in the way of making anything clear, and the literature reads like a dictionary),and how to get the most out of them.

Very well written. To the point, and it the end, the reader actually has learned how to compose a functioning .fpi script, from the ground up.

Kudos, to you...

ARE YOU A LONE WOLF? CLICK BELOW TO JOIN THE PACK.

Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 14th Mar 2008 20:51
I think the only thing that could help make this more clear to people trying to learn is the ability to use Bold Face inside the code... that way I could highlight new lines to the script, and people will be able to easily find what happened and why it was put where it was.

Not sure if I'd want to be a tutorial writer, since I only do this sorta stuff when I get really bored... I'd be happier if they picked me up as a coder, but considering the kind of code Lee has to go through, I'm not sure I would want to do that either, lol!


The one and only,
~PlystirE~

Seth Black
FPSC Reloaded TGC Backer
19
Years of Service
User Offline
Joined: 22nd Feb 2005
Location: Pittsburgh, PA
Posted: 14th Mar 2008 21:26
Quote: "...since I only do this sorta stuff when I get really bored... "


...please don't take this wrong...man, do I hope that you get
bored alot, in the very near future!

ARE YOU A LONE WOLF? CLICK BELOW TO JOIN THE PACK.

CoffeeGrunt
17
Years of Service
User Offline
Joined: 5th Oct 2007
Location: England
Posted: 14th Mar 2008 21:31
Sweet job Ply! and I'm sure these would all work really good if you implemented variables to work the AI...


Quote: "they really offer no help in the way of making anything clear, and the literature reads like a dictionary"


Yeh, you should try being a DGDK beginner, the tutorials suck for that, I've been through them all and am still confuzzled....

Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 14th Mar 2008 22:57
Thanks, CG.


As for the manual literature:

Quote: "USEWEAPON
fires any weapon half by an entity in the direction of the target"


How can you "half" a weapon?

Lol


The one and only,
~PlystirE~

General powell11
17
Years of Service
User Offline
Joined: 7th Jul 2007
Location:
Posted: 14th Mar 2008 23:12
i finally understand!!! thanks!

Check out gang- the gangster fps
xplosys
18
Years of Service
User Offline
Joined: 5th Jan 2006
Playing: FPSC Multiplayer Games
Posted: 14th Mar 2008 23:28
Quote: "fires any weapon half by an entity in the direction of the target"


I guess thats supposed to say "held by an entity" or somthing like that. LOL

Best.

Seth Black
FPSC Reloaded TGC Backer
19
Years of Service
User Offline
Joined: 22nd Feb 2005
Location: Pittsburgh, PA
Posted: 14th Mar 2008 23:52
...literature is glitchy like the software.

ARE YOU A LONE WOLF? CLICK BELOW TO JOIN THE PACK.

CoffeeGrunt
17
Years of Service
User Offline
Joined: 5th Oct 2007
Location: England
Posted: 15th Mar 2008 00:50
Quote: ""USEWEAPON
fires any weapon half by an entity in the direction of the target"

How can you "half" a weapon? "


Indeed, although I think it's probably a typo by Lee....

Kilgore
16
Years of Service
User Offline
Joined: 22nd Feb 2008
Location: Chad Valley
Posted: 15th Mar 2008 12:55
This is fantastically helpful! Great that you've dedicated so much time and effort.
Dude232
16
Years of Service
User Offline
Joined: 18th Jan 2008
Location:
Posted: 19th Mar 2008 18:59
now i finnaly made my first script!!the character runs away when it sees the player

woot for toot
16
Years of Service
User Offline
Joined: 13th Apr 2008
Location: a box
Posted: 14th Apr 2008 03:56
sorry that was awesome but i have one request...
how could u get the guy to miss once and a while?



peace

Login to post a reply

Server time is: 2024-11-24 05:27:16
Your offset time is: 2024-11-24 05:27:16