YesNoOk
avatar

Coding A.I (Read 3843 times)

Started by mkfreak89, June 03, 2020, 08:57:32 pm
Share this topic:
Coding A.I
#1  June 03, 2020, 08:57:32 pm
  • avatar
  • **
Hi everyone, i am working on my project and adding new special moves to Characters, while i am in able to give Characters new moves i cant seem to understand how to make the A.I. perform these moves more often when i fight against them. Any help would be aprecciated.
Re: Coding A.I
#2  June 03, 2020, 09:10:10 pm
  • ****
  • CPU Purple Heart
    • USA
    • https://www.pixiv.net/en/users/8108265
 The chances of an AI performing specific actions is very much dependent on not only the values of random triggers, but the ordering of their changestates since MUGEN parses state controllers from top to bottom (therefore, AI changestates that are higher up are more likely to occur. If you've seen an AI block too much, for example, it may be due to their guard changestate being placed too high). There's other major nuances such as conditions that will allow a changestate to occur (i.e.: p2dist/p2bodydist, what statetype and movetype P2 is in, stateno that P1 and/or P2 are in, etc) that will also. There is no such thing as a universal method in achieving this, it's a very trial and error kind of thing that will have you spend hours testing frequency of how the AI chooses actions.
Re: Coding A.I
#3  June 03, 2020, 09:18:41 pm
  • avatar
  • **
The chances of an AI performing specific actions is very much dependent on not only the values of random triggers, but the ordering of their changestates since MUGEN parses state controllers from top to bottom (therefore, AI changestates that are higher up are more likely to occur. If you've seen an AI block too much, for example, it may be due to their guard changestate being placed too high). There's other major nuances such as conditions that will allow a changestate to occur (i.e.: p2dist/p2bodydist, what statetype and movetype P2 is in, stateno that P1 and/or P2 are in, etc) that will also. There is no such thing as a universal method in achieving this, it's a very trial and error kind of thing that will have you spend hours testing frequency of how the AI chooses actions.

Could you give me any example of what i need to change in order to have the A.I use that move more often as all the others moves it uses. Maybe copy paste something here and explain it a bit more.
As far as i know there has to be some kind of random number which you can set up to make the char use the move more likely or less, but i just cant figure it out as for now.
Re: Coding A.I
#4  June 03, 2020, 09:37:51 pm
  • ****
  • CPU Purple Heart
    • USA
    • https://www.pixiv.net/en/users/8108265
 Not really, no, because it varies by each character, hence why I said no universal standard exists. I did give you a very basic example, however, such as guard AI chantestates will make an AI block too much if the changestate is too high up.

 I mostly draw from Muteki's guide of AI coding, which generally has AI changestate order in statedef -1 look something like this.

Spoiler, click to toggle visibilty

 If you want a character to perform something more often, just increase the value of their random triggers and put that specific AI changestate higher in statedef -1. Likewise, if you want an AI to perform something less frequently, just put the changestate lower in the statedef -1 ordering and lower its random value. Trust me, there is no shortcut, it takes me 1 to 2 months to actually complete an AI and I've been making AI since June of last year, although the result does end up making them particularly brutal to deal with.
Re: Coding A.I
#5  June 03, 2020, 10:11:42 pm
  • avatar
  • **
Not really, no, because it varies by each character, hence why I said no universal standard exists. I did give you a very basic example, however, such as guard AI chantestates will make an AI block too much if the changestate is too high up.

 I mostly draw from Muteki's guide of AI coding, which generally has AI changestate order in statedef -1 look something like this.

Spoiler, click to toggle visibilty

 If you want a character to perform something more often, just increase the value of their random triggers and put that specific AI changestate higher in statedef -1. Likewise, if you want an AI to perform something less frequently, just put the changestate lower in the statedef -1 ordering and lower its random value. Trust me, there is no shortcut, it takes me 1 to 2 months to actually complete an AI and I've been making AI since June of last year, although the result does end up making them particularly brutal to deal with.

Yes this is what i actually meant, i am a beginner when it comes to coding, but here is the part of the move which i would like the A.I to perform more often when fighting against me, please show me what i need to change here as i do not really see any "statedef - 1" or "random".



;========================================

[Statedef 1119]; Butterfly Kick
type    = S
movetype= A
physics = N
juggle  = 4
anim = 1119
Velset = 0, 0
sprpriority = 2
ctrl = 0


[State 2000, 2]
type = Varset
trigger1 = time = 0
v = 11
value = 0

[State 2000, 2]
type = Varset
trigger1 = backedgebodydist < 12
v = 11
value = 1

[State 2000, 0.5]
type = Playsnd
trigger1 = time = 0
value = 4,13
volumescale = 200
channel = 0

[State 2000, 0.5]
type = Playsnd
trigger1 = time = 0
value = 999,0
volumescale = 200
channel = 0


[State 2000, 0.5]
type = Playsnd
trigger1 = movecontact
value = 4,19
volumescale = 200
persistent = 0

[State 2000, 2]
type = Veladd
trigger1 = animelem = 3
x = 10

[State 600, 1.5]
type = varset
trigger1 = animelem = 3
fv = 2
value = 1
ignorehitpause = 1

[State 600, 1.5]
type = varset
trigger1 = animelemtime(3) > 4
fv = 2
value = fvar(2)*0.96875
ignorehitpause = 1

[State 2, Roundhouseblood]
type = Helper
triggerall = movehit
trigger1 = anim = 1119
triggerall = numhelper(28) < 1
ID = 28
stateno = 27
postype = p1
persistent = 0
ignorehitpause = 1



[State 2000, 2]
type = Veladd
trigger1 = animelemtime(3) > 4
trigger1 = vel x > 6.017181396484375
x = -0.3125*fvar(2)

[State 2000, 2]
type = Veladd
trigger1 = animelemtime(3) > 0 && animelemtime(6) < 0
trigger1 = enemy,backedgebodydist < 3
trigger1 = p2bodydist x < 12 && p2statetype = C && !movecontact
x = -1.265

[State 2000, 2]
type = Velset
trigger1 = movehit
x = 4

[State 2000, 2]
type = Velset
trigger1 = moveguarded
x = 0


[State 1050, 4]
type = HitDef
trigger1 = !movecontact
trigger1 = p2statetype != C || p2stateno = [120,159]
attr = S, NA
damage    = 220,30
animtype  = back
air.animtype  = Back
hitflag = MAF
guardflag = HL
priority = 7
pausetime = 0, 2
sparkno = -1
guard.sparkno = -1
sparkxy = 18,-60
hitsound   = 5,0
guardsound = 5,14
ground.type = High
ground.slidetime = 12
ground.hittime  = 12
guard.velocity = 0
ground.velocity = ifelse(var(11) = 0,-8,-4),-6
air.velocity = ifelse(var(11) = 0,-8,-4),-6
yaccel = 0.375
guard.slidetime = 12              ;Values for guarded attack (def: ground.slidetime)
guard.ctrltime = 5               ;Time to regain control after guard (def: guard.slidetime)
guard.dist = 120
kill       = (Var(9) = 0)
fall.kill  = (Var(9) = 0)
guard.kill = (Var(9) = 0)
envshake.freq = 90
envshake.time = 12
envshake.ampl = 6
hitonce = 1


[State 2000, 0.5]
type = targetvelset
trigger1 = moveguarded = [1,12]
x = -2
ignorehitpause = 1

[State 181, DIED]
type = statetypeset
trigger1 = moveguarded > 12 || p2dist x < 0
trigger2 = animelem = 6 && p2stateno != [120,159]
trigger3 = animelem = 7
movetype = I

[State 1050, 7]
type = changeanim
trigger1 = moveguarded = 12
value = anim
elem = 7

[State 1050, 7]
type = playerpush
trigger1 = movehit || p2stateno = 5120
value = 0

[State 1050, 7]
type = selfstate
trigger1 = animtime = 0
value = 0
ctrl = 1
Re: Coding A.I
#6  June 03, 2020, 10:18:34 pm
  • ****
  • CPU Purple Heart
    • USA
    • https://www.pixiv.net/en/users/8108265
 Well, first off, AI is usually coded in statedef -1/-2/-3 (most pos-WinMUGEN coders prefer statedef -1), not the actual positive states themselves unless they involve commands. AI is basically just substituting commands with AIlevel (or a var if you're using WinMUGEN). You might actually want to study how AIlevel works in other characters (like Infinite's or Sennou-Room's PotS-inspired characters), assuming you do MUGEN 1.0 and above. If you don't even know the very basics of AI, you might want to study that first before even attempting the creation of one.
Re: Coding A.I
#7  June 05, 2020, 04:20:00 am
  • ****
Not really, no, because it varies by each character, hence why I said no universal standard exists. I did give you a very basic example, however, such as guard AI chantestates will make an AI block too much if the changestate is too high up.

 I mostly draw from Muteki's guide of AI coding, which generally has AI changestate order in statedef -1 look something like this.

Spoiler, click to toggle visibilty

 If you want a character to perform something more often, just increase the value of their random triggers and put that specific AI changestate higher in statedef -1. Likewise, if you want an AI to perform something less frequently, just put the changestate lower in the statedef -1 ordering and lower its random value. Trust me, there is no shortcut, it takes me 1 to 2 months to actually complete an AI and I've been making AI since June of last year, although the result does end up making them particularly brutal to deal with.

Yes this is what i actually meant, i am a beginner when it comes to coding, but here is the part of the move which i would like the A.I to perform more often when fighting against me, please show me what i need to change here as i do not really see any "statedef - 1" or "random".



;========================================

[Statedef 1119]; Butterfly Kick
type    = S
movetype= A
physics = N
juggle  = 4
anim = 1119
Velset = 0, 0
sprpriority = 2
ctrl = 0


[State 2000, 2]
type = Varset
trigger1 = time = 0
v = 11
value = 0

[State 2000, 2]
type = Varset
trigger1 = backedgebodydist < 12
v = 11
value = 1

[State 2000, 0.5]
type = Playsnd
trigger1 = time = 0
value = 4,13
volumescale = 200
channel = 0

[State 2000, 0.5]
type = Playsnd
trigger1 = time = 0
value = 999,0
volumescale = 200
channel = 0


[State 2000, 0.5]
type = Playsnd
trigger1 = movecontact
value = 4,19
volumescale = 200
persistent = 0

[State 2000, 2]
type = Veladd
trigger1 = animelem = 3
x = 10

[State 600, 1.5]
type = varset
trigger1 = animelem = 3
fv = 2
value = 1
ignorehitpause = 1

[State 600, 1.5]
type = varset
trigger1 = animelemtime(3) > 4
fv = 2
value = fvar(2)*0.96875
ignorehitpause = 1

[State 2, Roundhouseblood]
type = Helper
triggerall = movehit
trigger1 = anim = 1119
triggerall = numhelper(28) < 1
ID = 28
stateno = 27
postype = p1
persistent = 0
ignorehitpause = 1



[State 2000, 2]
type = Veladd
trigger1 = animelemtime(3) > 4
trigger1 = vel x > 6.017181396484375
x = -0.3125*fvar(2)

[State 2000, 2]
type = Veladd
trigger1 = animelemtime(3) > 0 && animelemtime(6) < 0
trigger1 = enemy,backedgebodydist < 3
trigger1 = p2bodydist x < 12 && p2statetype = C && !movecontact
x = -1.265

[State 2000, 2]
type = Velset
trigger1 = movehit
x = 4

[State 2000, 2]
type = Velset
trigger1 = moveguarded
x = 0


[State 1050, 4]
type = HitDef
trigger1 = !movecontact
trigger1 = p2statetype != C || p2stateno = [120,159]
attr = S, NA
damage    = 220,30
animtype  = back
air.animtype  = Back
hitflag = MAF
guardflag = HL
priority = 7
pausetime = 0, 2
sparkno = -1
guard.sparkno = -1
sparkxy = 18,-60
hitsound   = 5,0
guardsound = 5,14
ground.type = High
ground.slidetime = 12
ground.hittime  = 12
guard.velocity = 0
ground.velocity = ifelse(var(11) = 0,-8,-4),-6
air.velocity = ifelse(var(11) = 0,-8,-4),-6
yaccel = 0.375
guard.slidetime = 12              ;Values for guarded attack (def: ground.slidetime)
guard.ctrltime = 5               ;Time to regain control after guard (def: guard.slidetime)
guard.dist = 120
kill       = (Var(9) = 0)
fall.kill  = (Var(9) = 0)
guard.kill = (Var(9) = 0)
envshake.freq = 90
envshake.time = 12
envshake.ampl = 6
hitonce = 1


[State 2000, 0.5]
type = targetvelset
trigger1 = moveguarded = [1,12]
x = -2
ignorehitpause = 1

[State 181, DIED]
type = statetypeset
trigger1 = moveguarded > 12 || p2dist x < 0
trigger2 = animelem = 6 && p2stateno != [120,159]
trigger3 = animelem = 7
movetype = I

[State 1050, 7]
type = changeanim
trigger1 = moveguarded = 12
value = anim
elem = 7

[State 1050, 7]
type = playerpush
trigger1 = movehit || p2stateno = 5120
value = 0

[State 1050, 7]
type = selfstate
trigger1 = animtime = 0
value = 0
ctrl = 1

this is move not AI

AI is in def -1 which is your command.def or command.cmd file
Re: Coding A.I
#8  June 05, 2020, 05:07:07 am
  • avatar
  • **
    • USA
Ok.  I'm not going to dig through another character and try to reverse engineer it's AI.  But I'll give a brief breakdown of how an AI move can (should) work.

Basically, it's just like a normal command state, but written to work for the AI.  Some coders even combine the two into one huge mess.  I use the AILevel variable built into Mugen 1.x, but a lot of coders are still using the old winmugen style AI.  The most common AI variable then is var(59).

So, here's a really command state for a move.  It's just a basic anti-air throw.
Code:
[State -1, AAT]
type = ChangeState
value = 299
triggerall = command = "Butt"
triggerall = statetype != A
trigger1 = ctrl
trigger2 = movehit
trigger2 = stateno = [200,400]

If I do the command "butt" (dp+K), I'm not in the air, and I have ctrl (or I just hit with weak punch or weak kick), then the move will execute.  Why should an anti-air throw be cancellable?  I dunno.  Why not?

So the AI version is going to have all of the same triggers, but the AI doesn't need to check for a command input.  Instead, it will activate based on the difficulty level and location of the opponent.

Code:
[state -2, AI AAT]
type = ChangeState
value = 299
triggerall = (AILevel > 0) && (roundstate = 2)
triggerall = random < ((AILevel * (AILevel / 2.75)) + (ifelse((p2bodydist x < 30),100,50)) + (ifelse((enemynear, pos y < -45),100,50)))
triggerall = statetype != A
triggerall = p2dist y < -45
trigger1 = ctrl
trigger2 = stateno = [200,400]
trigger2 = movehit

Ok, so I check if the character is AI controlled and the match is actually going.  I should probably have added more failsafe variable checks, but whatever.  Random is going to generate a number between 0 and 255 (or something like that).  If the sum total of all of those things is greater than whatever random number, the move can execute.  Long story short, on high mugen difficulty, my AI is constantly trying to grab any opponent that is in reach of the air throw.  There is another check for p2dist y to make sure that the AI isn't going to use the move when it won't hit, even if the random generated number is 0.
Re: Coding A.I
#9  June 05, 2020, 09:59:39 pm
  • ****
  • CPU Purple Heart
    • USA
    • https://www.pixiv.net/en/users/8108265
 As I've mentioned before, changestate priority (the order in which changestates are placed in statedef -1) also factors in what choices an AI will do more or less frequently because of how MUGEN's parser works (reads from top to bottom), and considering random resets every tick in statedef -1, the higher up changestates will happen more often when factored, more so if they have higher random values than the ones below.

 If you've only started on the AI, chances are, it will perform those few actions pretty frequently because not all the changestates are there yet. At any rate, I would suggest adding more triggers to define conditions against P2 so the AI isn't doing reckless stuff like trying to grab P2 while they attempt a hyper move or attempt to block throws for example.

 Here is an example of how I define conditions for air throwing that I have in my Akari Ichijou's AI. I'll place notes in arrows to indicate the purpose of each relevant trigger.

Spoiler, click to toggle visibilty