Hey this is my first tutorial and it will teach you some basic type of animal ai(hopefully)
. I always see people wanting to learn some basic ai and i hope you can learn from this tutorial. Its not the best tutorial but this should get you started on learning ai.
DOG AI TUTORIAL
INTRODUCTION
AI stands for artificial intelligence. Most games have AI for there bad guys, allies, animals, ect.
In this tutorial i will teach you how to setup your dog AI, Create a basic world for our dogs to roam in, Starting some basic ai, and moving objects around using the ai.
•PART 1: Setting up the Dog AI
First start a new project named Dog AI. You must start with this in your new project
First thing you should do is a nice command type and endtype this will create our dog type. Within type and endtype will be variables for our dog. Variables for our dog that will go in our things dogs do. Like eat, drink, and sleep so we will create a variable for each. We will also create a variable name for these too. Object, state, speed, desx, desy, and desz will be those varibles. We will also define them as a float or integer. I will explain why we need and how we use them later on in the tutorial. Write this
Type dogs
eat as float
drink as float
sleepeness as float
object as integer
state as integer
speed as float
desx as float
desy as float
desz as float
Endtype
Next we need to create our 6 dogs. Were going to do it with a simple command called dim.
This command as you should know creates an array so copy this into the next line.
What is the extra stuff you ask well let me tell you. Usually you would have something like this Dim dogs(4) which is the command, the array name, and the array dimensions but we want to link the type with the with the array. Now that we did that we can have different variables with the same name.
Now we will give them values an easy way to do this is in a for next loop. We are also going to give them a small random value so each dog is different. Type in this
for x=0 to 4
dogs(x).eat = 60+rnd(40)
dogs(x).drink = 60+rnd(40)
dogs(x).sleepeness = 50+rnd(50)
dogs(x).object = x+1
dogs(x).state = 4
dogs(x).speed = 0.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
make object cube x+1,1
color object x+1,rgb(0,120,0)
set object emissive x+1,rgb(0,255,0)
position object x+1,rnd(99),0.5,rnd(99)
next x
You should know most of these commands like make object, color object, ect That will be our dogs for our ai. Do you know this type of command dogs(x).eat. This command is like a variable but since I linked it to an array I have to put dogs(x). in front because it is linked to the array called dogs. Same goes for the other ones. If you want more information of type and endtype go to this newsletter tutorial-
http://www.thegamecreators.com/data/newsletter/newsletter_issue_28.html#9
and more in this-
http://www.thegamecreators.com/data/newsletter/newsletter_issue_29.html#9.
You should have this so far
Sync on
Sync rate 60
Type dogs
eat as float
drink as float
sleepeness as float
object as integer
state as integer
speed as float
desx as float
desy as float
desz as float
Endtype
Dim dogs(4) as dogs
for x=0 to 4
dogs(x).eat = 60+rnd(40)
dogs(x).drink = 60+rnd(40)
dogs(x).sleepeness = 50+rnd(50)
dogs(x).object = x+1
dogs(x).state = 4
dogs(x).speed = 0.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
make object cube x+1,1
color object x+1,rgb(0,120,0)
set object emissive x+1,rgb(0,255,0)
position object x+1,rnd(99),0.5,rnd(99)
next x
We are now done setting up our dog Ai.
•
PART 2: Basic World
To start we need to know what we need and we need a ground, a water bowl, a food bowl. Since I don’t want to waste too much time on this I will use a plain and boxes.
We will use a plain for the ground. Since it is vertical we have to rotate it on its x axis by 90 degrees. Then we will color it with a brown color, to make brown use red=128, green=64, blue=0. You will also have to set the objects emissive color otherwise it will look gray. We will also offset it from its original position for future use because I’m lazy in doing something else in another part of this tutorial.
So put in this code this will create the ground.
make object plain 6,100,100
xrotate object 6,90
color object 6,rgb(128,64,0)
set object emissive 6,rgb(128,64,0)
position object 6,50,0,50
Now we will create the water and food bowl which are boxes of different color. All we have to do is make it using a make object command, color it, and position it somewhere on the ground we made earlier.
So put this in to create both the food box and water box
make object box 7,5,2,5
color object 7,rgb(128,40,0)
set object emissive 7,rgb(50,100,0)
position object 7,80,1,80
make object box 8,5,2,5
color object 8,rgb(0,0,200)
set object emissive 8,rgb(0,0,200)
position object 8,20,1,20
Now to see our world use this command
You should have this so far
Sync on
Sync rate 60
Type dogs
eat as float
drink as float
sleepeness as float
object as integer
state as integer
speed as float
desx as float
desy as float
desz as float
Endtype
Dim dogs(4) as dogs
for x=0 to 4
dogs(x).eat = 60+rnd(40)
dogs(x).drink = 60+rnd(40)
dogs(x).sleepeness = 50+rnd(50)
dogs(x).object = x+1
dogs(x).state = 4
dogs(x).speed = 0.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
make object cube x+1,1
color object x+1,rgb(0,120,0)
set object emissive x+1,rgb(0,255,0)
position object x+1,rnd(99),0.5,rnd(99)
next x
make object plain 6,100,100
xrotate object 6,90
color object 6,rgb(128,64,0)
set object emissive 6,rgb(128,64,0)
position object 6,50,0,50
make object box 7,5,2,5
color object 7,rgb(128,40,0)
set object emissive 7,rgb(50,100,0)
position object 7,80,1,80
make object box 8,5,2,5
color object 8,rgb(0,0,200)
set object emissive 8,rgb(0,0,200)
position object 8,20,1,20
position camera 0,10,0
We are now done setting up our world
•PART 3: Start our Ai
Now we are going to start using the Ai we have already setup in our main loop so put this command.
You should know this will start our main loop. Now end it and put sync within the loop.
The next few things you will have to put in the main loop so put everything in the main loop unless I say don’t put it in the main loop.
We are going to use the set cursor command to put everything we print in the same places instead of going down the screen.
Now to run all our dogs at once we will have to use a for next loop again. This will continually run in our main loop. So place this in your code.
As you can see it goes from 0 to 4 because that is what our array goes up to and starts from.
Now we are going to create our first function called tire. This will lower the variables from the type and endtype so our Ai runs on variables that always change.
So don’t put it in the main loop because this is a function.
function tire(dog)
dogs(dog).eat = dogs(dog).eat-0.01
dogs(dog).drink = dogs(dog).drink-0.01
dogs(dog).sleepeness = dogs(dog).sleepeness-0.01
endfunction
As you can see this lowers it by a very tiny amount each time it is called.
Now we are going to call it in the for next loop. Place this in your for next loop
Now this will always lower the variable eat, drink, and sleepeness of each dog. If you look you see x as the parameter. Since this is in the for next loop it will go from 0 to 4 every time. Like when we were setting up the Ai.
Now we want to see its values so put this in the for next loop too, above the tire(x) command so we know what it is before it is called
print "Hunger: ";dogs(x).eat
print "Thirst: ";dogs(x).drink
print "Sleepeness: ";dogs(x).sleepeness
Now it should look like this
Sync on
Sync rate 60
Type dogs
eat as float
drink as float
sleepeness as float
object as integer
state as integer
speed as float
desx as float
desy as float
desz as float
Endtype
Dim dogs(4) as dogs
for x=0 to 4
dogs(x).eat = 60+rnd(40)
dogs(x).drink = 60+rnd(40)
dogs(x).sleepeness = 50+rnd(50)
dogs(x).object = x+1
dogs(x).state = 4
dogs(x).speed = 0.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
make object cube x+1,1
color object x+1,rgb(0,120,0)
set object emissive x+1,rgb(0,255,0)
position object x+1,rnd(99),0.5,rnd(99)
next x
make object plain 6,100,100
xrotate object 6,90
color object 6,rgb(128,64,0)
set object emissive 6,rgb(128,64,0)
position object 6,50,0,50
make object box 7,5,2,5
color object 7,rgb(128,40,0)
set object emissive 7,rgb(50,100,0)
position object 7,80,1,80
make object box 8,5,2,5
color object 8,rgb(0,0,200)
set object emissive 8,rgb(0,0,200)
position object 8,20,1,20
position camera 0,10,0
Do
Set cursor 0,0
for x=0 to 4
print "Hunger: ";dogs(x).eat
print "Thirst: ";dogs(x).drink
print "Sleepeness: ";dogs(x).sleepeness
tire(x)
next x
Sync
Loop
function tire(dog)
dogs(dog).eat = dogs(dog).eat-0.01
dogs(dog).drink = dogs(dog).drink-0.01
dogs(dog).sleepeness = dogs(dog).sleepeness-0.01
endfunction
Now what you have been waiting for and if you haven’t pretend you have. You can run this code and see what happens to the values.
If you saw the values were all different and they were getting lower.
•PART 4: States and basic movement
Now that you know how to lower the variables where going to make that into movement. Since we have 3 different things a dog does we will have 3 different states. Then we will have another one called idle/wander which is what they do if there not doing the other different states. So put this in your for next loop.
if dogs(x).state=1
endif
if dogs(x).state=2
endif
if dogs(x).state=3
endif
if dogs(x).state=4
endif
As you can see we have 4 different states to choose from state 1 is eat, state 2 is drink, state 3 is sleepeness, and state 4 is idle/wander. Remember in the beginning we had this dogs(x).state = 4 this means idle/wander so we will put the movement for that first.
We are going to set a destination target for our dog. Remember this part. This alreadly set us a destination to start with.
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
But what happens when it gets to its target or goes toward that target to long it has to switch or it will stay there so were going to add something at the top of our for next loop. This will be our temp variables for the dogs position so we won’t have to write it out.
px#=object position x(dogs(x).object)
pz#=object position z(dogs(x).object)
If you look we use this dogs(x).object instead of something like this x I did that because x can equal 0 but an object number cannot. If you remember we made dogs(x).object equal x+1 so it will control the object that equals dogs(x).object.
Now go to if dogs(x).state=4 endif part and put this in it
if idletime > 1 or px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5
endif
This will check its idletime variable which is a timer or if its at its destination. If it is true then set a new destination using this
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
Then reset the timer by using the command
Now to move the dog to its destination we are going to put in a new function called movedog. I was kind of lazy so I did a cheap movement but if you can do it better do it. Just stick with this for now. First we need to face our target using the point object command. Then use the move object command to move it towards its destination. This will go under the other function we had which is outside the loop.
function movedog(dog)
point object dogs(dog).object,dogs(dog).desx,dogs(dog).desy,dogs(dog).desz
move object dogs(dog).object,dogs(dog).speed
endfunction
Call the movedog function in the if dogs(x).state=4 endif part but not in the
if idletime > 1 or px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5
endif
At the end of the if then statement so it can get the destination if it needs to. We also need to check the idle time so we will use idletime=(timer()-t)/1000. We also want it to say that it is idling so we will make it print it using the print command. So using those commands should look like this
idletime=(timer()-t)/1000
movedog(x)
print "DOG ";x;" is idling"
The whole statement should look something similar or exactly like this
if dogs(x).state=4
if idletime > 1 or px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
t=timer()
endif
idletime=(timer()-t)/1000
movedog(x)
print "DOG ";x;" is idling"
endif
We also want to move the camera around so use this command somewhere in the main loop not the for next loop.
control camera using arrowkeys 0,2,1
The code should look like this
Sync on
Sync rate 60
Type dogs
eat as float
drink as float
sleepeness as float
object as integer
state as integer
speed as float
desx as float
desy as float
desz as float
Endtype
Dim dogs(4) as dogs
for x=0 to 4
dogs(x).eat = 60+rnd(40)
dogs(x).drink = 60+rnd(40)
dogs(x).sleepeness = 50+rnd(50)
dogs(x).object = x+1
dogs(x).state = 4
dogs(x).speed = 0.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
make object cube x+1,1
color object x+1,rgb(0,120,0)
set object emissive x+1,rgb(0,255,0)
position object x+1,rnd(99),0.5,rnd(99)
next x
make object plain 6,100,100
xrotate object 6,90
color object 6,rgb(128,64,0)
set object emissive 6,rgb(128,64,0)
position object 6,50,0,50
make object box 7,5,2,5
color object 7,rgb(128,40,0)
set object emissive 7,rgb(50,100,0)
position object 7,80,1,80
make object box 8,5,2,5
color object 8,rgb(0,0,200)
set object emissive 8,rgb(0,0,200)
position object 8,20,1,20
position camera 0,10,0
Do
Set cursor 0,0
for x=0 to 4
print "Hunger: ";dogs(x).eat
print "Thirst: ";dogs(x).drink
print "Sleepeness: ";dogs(x).sleepeness
px#=object position x(dogs(x).object)
pz#=object position z(dogs(x).object)
tire(x)
if dogs(x).state=1
endif
if dogs(x).state=2
endif
if dogs(x).state=3
endif
if dogs(x).state=4
dogs(x).speed=0.2
if idletime > 1 or px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
t=timer()
endif
idletime=(timer()-t)/1000
movedog(x)
print "DOG ";x;" is idling"
endif
next x
control camera using arrowkeys 0,2,1
Sync
Loop
function tire(dog)
dogs(dog).eat = dogs(dog).eat-0.01
dogs(dog).drink = dogs(dog).drink-0.01
dogs(dog).sleepeness = dogs(dog).sleepeness-0.01
endfunction
function movedog(dog)
point object dogs(dog).object,dogs(dog).desx,dogs(dog).desy,dogs(dog).desz
move object dogs(dog).object,dogs(dog).speed
endfunction
You can run your code to see it wander around.
If the dogs move to fast then just change the dog speed in this variable dogs(x).speed at the top it was set at a speed of 0.5 but you can change it to something lower or higher. You can also set it just for idling if you put it in the if then statement. Just remember to change it back. In the code above I put in dogs(x).speed in the idle mode with a speed of 0.2
•PART 5: More on States and movement
Now we will do more on states and movement. The states that we have to do will run on the variables we were keeping track of earlier. You could call that the dogs motivation, like if the eat variable gets to low it will need to eat so it is motivated to eat. That is exactly what we are going to do.
So what do you do when your hungry you go eat right, how about drinking you go drink right, same thing with sleeping to right? So we are going to do that with the dog. Remember we were using the tire function to make the dogs hungrier, thirstier, and sleepier. Now we are going to check to see if it is to hungry, thirsty, or sleepy. Put this in your code under all the state if then’s
if dogs(x).eat < 40 and dogs(x).state=4 then dogs(x).state=1
if dogs(x).drink < 50 and dogs(x).state=4 then dogs(x).state=2
if dogs(x).sleepeness < 30 and dogs(x).state=4 then dogs(x).state=3
If you look you can see we added something else to check if it was true. We added this and dogs(x).state=4. This will check to see if it is in idle mode. We added this because what if it was both hungry and thirsty. They would keep on switching between them and it would try to get to both without going to ether one of them. We also switch them to different states because each one is going to go and do something different.
Now that we will be able to switch we will make it go do something. First we will do the state=1 if then statement. We will first set a destination which is the position of the object if you remember it was when we were creating our world. Object number 7. Now put this in state 1 if then statement
dogs(x).desx=object position x(7)
dogs(x).desy=object position y(7)
dogs(x).desz=object position z(7)
Under that put in the movedog command we made.
Now we will have to check if it is there. We will also be setting a little range because it will never get to the exact coordinates. This is where our temp variables come in handy. Put in this under movedog(x)
if px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5 then inc dogs(x).eat,20+rnd(40) : dogs(x).state=4
As you can see if it gets to its destination it increases the eat variable so it won’t be hungry and changes back to state 4(idle state). This will be pretty much the same for state 2 too. We will also want to know if it is hungry so we will print it. So put this under the check distance statement.
print "DOG ";x;" is hungry"
We will now do the same thing with state 2(drink variable). Lets do the exact same thing except it won’t be object 7 were going to but object 8. We will still use the movedog(x) command. Put this in State 2
dogs(x).desx=object position x(8)
dogs(x).desy=object position y(8)
dogs(x).desz=object position z(8)
movedog(x)
The distance check will almost be the same except this will increase the drink variable and by a different amount.
if px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5 then inc dogs(x).drink,20+rnd(30) : dogs(x).state=4
Last part of state 2 is to print if it is thirsty so put this in
print "DOG ";x;" is thirsty"
Now to our final state 3(this is our final state because we already finish state 4). We are going to do something a little different because this is a sleep state which means he won’t move. Since this is a cube an easy way of showing he is sleeping is to position him lower then he was. So put in this command in the state 3 if then statement.
position object dogs(x).object,px#,0,pz#
If you remember the y position was at 0.5 so this is .5 lower this will make it seem like it is laying down(if not PRETEND)
Now we are going to increase its sleepeness value a little at a time so it seems like it is sleeping for a little while. For a little while we don’t mean forever so we need something to stop it so we will stop it when its well rested like 90. Put in this under the position object command.
dogs(x).sleepeness = dogs(x).sleepeness+0.2
if dogs(x).sleepeness > 90 then dogs(x).state=4
Now print that it is sleeping so we know put this under the sleep check.
print "DOG ";x;" is sleepy"
You should now have this as your final code
Sync on
Sync rate 60
Type dogs
eat as float
drink as float
sleepeness as float
object as integer
state as integer
speed as float
desx as float
desy as float
desz as float
Endtype
Dim dogs(4) as dogs
for x=0 to 4
dogs(x).eat = 60+rnd(40)
dogs(x).drink = 60+rnd(40)
dogs(x).sleepeness = 50+rnd(50)
dogs(x).object = x+1
dogs(x).state = 4
dogs(x).speed = 0.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
make object cube x+1,1
color object x+1,rgb(0,120,0)
set object emissive x+1,rgb(0,255,0)
position object x+1,rnd(99),0.5,rnd(99)
next x
make object plain 6,100,100
xrotate object 6,90
color object 6,rgb(128,64,0)
set object emissive 6,rgb(128,64,0)
position object 6,50,0,50
make object box 7,5,2,5
color object 7,rgb(128,40,0)
set object emissive 7,rgb(50,100,0)
position object 7,80,1,80
make object box 8,5,2,5
color object 8,rgb(0,0,200)
set object emissive 8,rgb(0,0,200)
position object 8,20,1,20
position camera 0,10,0
Do
Set cursor 0,0
for x=0 to 4
print "Hunger: ";dogs(x).eat
print "Thirst: ";dogs(x).drink
print "Sleepeness: ";dogs(x).sleepeness
px#=object position x(dogs(x).object)
pz#=object position z(dogs(x).object)
tire(x)
if dogs(x).state=1
dogs(dog).speed=0.5
dogs(x).desx=object position x(7)
dogs(x).desy=object position y(7)
dogs(x).desz=object position z(7)
movedog(x)
if px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5 then inc dogs(x).eat,20+rnd(40) : dogs(x).state=4
print "DOG ";x;" is hungry"
endif
if dogs(x).state=2
dogs(dog).speed=0.5
dogs(x).desx=object position x(8)
dogs(x).desy=object position y(8)
dogs(x).desz=object position z(8)
movedog(x)
if px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5 then inc dogs(x).drink,20+rnd(30) : dogs(x).state=4
print "DOG ";x;" is thirsty"
endif
if dogs(x).state=3
position object dogs(x).object,px#,0,pz#
dogs(x).sleepeness = dogs(x).sleepeness+0.2
if dogs(x).sleepeness > 90 then dogs(x).state=4
print "DOG ";x;" is sleepy"
endif
if dogs(x).state=4
dogs(x).speed=0.2
if idletime > 1 or px# > dogs(x).desx-2.5 and px# < dogs(x).desx+2.5 and pz# > dogs(x).desz-2.5 and pz# < dogs(x).desz+2.5
dogs(x).desx=rnd(100)
dogs(x).desy=0.5
dogs(x).desz=rnd(100)
t=timer()
endif
idletime=(timer()-t)/1000
movedog(x)
print "DOG ";x;" is idling"
endif
if dogs(x).eat < 40 and dogs(x).state=4 then dogs(x).state=1
if dogs(x).drink < 50 and dogs(x).state=4 then dogs(x).state=2
if dogs(x).sleepeness < 30 and dogs(x).state=4 then dogs(x).state=3
next x
control camera using arrowkeys 0,2,1
Sync
Loop
function tire(dog)
dogs(dog).eat = dogs(dog).eat-0.01
dogs(dog).drink = dogs(dog).drink-0.01
dogs(dog).sleepeness = dogs(dog).sleepeness-0.01
endfunction
function movedog(dog)
point object dogs(dog).object,dogs(dog).desx,dogs(dog).desy,dogs(dog).desz
move object dogs(dog).object,dogs(dog).speed
endfunction
Like before you can change the speed in state 1 and 2. You can’t change the speed in 3 because he is not moving in that state. I have already put in speed changes in state 1 and 2 so go and make it faster and slower.
That is my first tutorial so tell me what you think.
If I missed something, something isn't right, or something isn't clear post here.