Started by ink, January 20, 2017, 04:15:42 am

ink

AI Discussion
#1  January 20, 2017, 04:15:42 am
• inktrebuchet

• Online
I know a thread like this can get frustrating but I would like to hear opinions on the subject!

I have been looking over a ton of information on MUGEN AI for a project and have found different answers here and there but I have some questions about it still. I'm opening this thread in hopes of get to the bottom of those questions and have an open discussion on what is and isn't worth doing for a characters AI and what is and is not possible. What methods are out there?

I have found a few snippets of code that standout but I'm not sure they are really worth using. Here is an example, does it make sense to use a trigger like this?
Code:
`random< ((AiLevel)*25)`

I understand the idea behind it but I keep thinking about how all of this is effected later by using mugen's built in AI levels. What all does the built in AI levels change? Obviously its not changing the random trigger I always see when looking through other AI.

I remember reading about AI that learns or appears to learn in mugen also. Is there any character that this has been implemented in or other method of AI? I have thought of a couple ideas similar to this but I would love to dig into any existing code first.

Just No Point

Re: AI Discussion
#2  January 20, 2017, 04:36:13 am
This may be of some assistance. A quote from XGargoyle helping me and Alex understand the AI ramps in MUGEN

Quote
AILevel**2 is equivalent to AILevel*AILevel, that means values will range from 0 to 64 (more ramp) - Red line

AILevel*2 will just double the level, that means values will range from 0 to 16 (less ramp) - Blue line

We decided to have the AILEvel using this formula: (AIlevel ** 2 / 64.0) as  it gives more ladders between one level to the other, so please use this formula.

DOS/Winmugen characters used Winane's not-so-much-reliable AI routines, and we used an internal variable (var(53) or any other) to create a ramp AI.
With 1.0, it's no longer necessary, so the variable in cofig.txt needs to be removed. We are now using AILevel, which uses Mugen's internal difficulty level, and is 100% reliable

And, following JNP's post, a code like this:
trigger1 = (EnemyNear, MoveType = H) && (EnemyNear, HitFall) && Random < (50 * (AILevel ** 2 / 64.0))

Will have the following probabilities:
Level 0: (50 * (0 ** 2 / 64.0))= 0 (Human controlled)
Level 1: (50 * (1 ** 2 / 64.0))= 0.78
Level 2: (50 * (2 ** 2 / 64.0))= 3.12
Level 3: (50 * (3 ** 2 / 64.0))= 7.03
Level 4: (50 * (4 ** 2 / 64.0))= 12.5
Level 5: (50 * (5 ** 2 / 64.0))= 19.53
Level 6: (50 * (6 ** 2 / 64.0))= 28.12
Level 7: (50 * (7 ** 2 / 64.0))= 38.28
Level 8: (50 * (8** 2 / 64.0))= 50

Obviously, if you use a formula like Random < (450 * (AILevel ** 2 / 64.0)), the ramp would go from 7.03 (AI 1) to 450 (AI 8 ), a middle CPU (AI 4) will be 112.5

The image will come back when XG's site is fixed. It's having issues since Val upgraded Guild

Jesuszilla

Re: AI Discussion
#3  January 20, 2017, 04:38:59 am
• Loyal to the Game
I pull random ranges out of my ass, make sure they don't overlap, and hope for the best for the most part. Obviously those ranges are larger or smaller depending on the AILevel and whether or not it's a good tactic.

I'd use VarRandom like [E] mentioned in the thread for that particular SCTRL here.
Last Edit: January 20, 2017, 04:46:14 am by Jesuszilla

Niitris

Re: AI Discussion
#4  January 20, 2017, 05:17:29 am
I remember reading about AI that learns or appears to learn in mugen also. Is there any character that this has been implemented in or other method of AI? I have thought of a couple ideas similar to this but I would love to dig into any existing code first.

The only realistic way I could see adaptive AI being a thing is if variables were saved for identifying certain types of moves. And even then, the moves themselves (for P2) would have to match with the identifier. Doesn't sound possible for a standard mugen collection.

Jesuszilla

Re: AI Discussion
#5  January 20, 2017, 05:25:03 am
• Loyal to the Game
It's possible if you use helpers and bitwise operations to expand your variables.

For example, my CvS2 Felicia (and soon VC Felicia when I can be bothered to finish true turbo) has a dynamic chain builder. This is based on two things: whether a certain attack is within distance, and whether previous attempts hit or miss.

So if LP > LK >MP >MK >HK misses, I remove the one with the weakest damage/startup time/distance, then I remove the next weakest, and so on, and that becomes the "go-to" BNB chain. If MP is out of reach, but MK is in reach, skip MP and go to MK.

Then there's Kamekaze's "neutrality" helper which is in Frank and his newer creations that can help out with things such as blocking lows/highs (because you can't detect that easily), jump-in estimation, whether an opponent is "a bitch nigga that's too short" and more. My Sagat currently expands on this a little by storing up to two states for standing lows/highs. It's mostly used to reduce CMD/CNS redundancy by delegating a lot of tasks to helper variables, which makes for more readable code.
Last Edit: January 20, 2017, 05:31:41 am by Jesuszilla

PeXXeR

Re: AI Discussion
#6  January 20, 2017, 02:59:59 pm
As long it does not input read like crazy and offers a decent challenge, it should be good I suggest you do not overthink it.
Also take a peak at GM's AI, dunno how it works, but his gill switches patterns all the time, and they even do the bar dance, charging the bar. Little touches like that. If its only for 1 char and not a full game project I suggest keep it simple yet challenging.

ink

Re: AI Discussion
#7  January 20, 2017, 07:10:47 pm
• inktrebuchet

• Online
This may be of some assistance. A quote from XGargoyle helping me and Alex understand the AI ramps in MUGEN

Spoiler, click to toggle visibilty
That's the first time I've seen that formula, I never would have thought to do it that way. Thanks for sharing this one!
Would you say random<112.5 will trigger an attack an average amount then, as in not to much not to little? Is there a range that is recommended to use with random? *Really, is it recommended to stay under a certain amount?

I pull random ranges out of my ass, make sure they don't overlap, and hope for the best for the most part.
A quick question on this. I have thought about this overlapping bit but if random fires off a different number each time it's used how could you really prevent it, Isn't it unavoidable in most cases?

Spoiler, click to toggle visibilty
I'm really interested in this! Thanks for pointing out Kamekaze's "neutrality" helper, I will be sure to dig through his code. I think he is actually the creator I was reading about for an learning AI.

I have recently wrote some code that adjusts during a match, which is the project I'm working on and one of the reasons I made this thread. So far it is successfully working on KFM, he survives longer and longer on average with each round. I will be researching what you guys have posted and adjusting my code.

I'm excited to learn more, if any other methods or pieces of code or characters stand out I would love to hear about them! I'm looking for more ideas than tips. This isn't really a help topic.

Last Edit: January 20, 2017, 09:35:50 pm by ink

Jesuszilla

Re: AI Discussion
#8  January 20, 2017, 08:29:01 pm
• Loyal to the Game
I pull random ranges out of my ass, make sure they don't overlap, and hope for the best for the most part.
A quick question on this. I have thought about this overlapping bit but if random fires off a different number each time it's used how could you really prevent it, Isn't it unavoidable in most cases?
Yes, which is why I mentioned to use [E]'s method which uses the Random trigger and stores its value in a variable. I should really do this for my characters since it wouldn't be that hard to patch in.

Bastard Mami

Re: AI Discussion
#9  January 20, 2017, 11:24:17 pm
• [E]
to expand a bit mroe on what jesuszill said (wihtout posting actual mugen code), my method involves two things, the one being mentioned is that instead of using random triggers in the change states, it uses the value of a variable. so if varX =0,100 it does one thing, if var x = 101-800 it does another, you can even leave ranges empty so the ai does nothing but wait until the next tick/cycle. this should eb adaptable to the common ways to code ai, since in the worse case you keep most code the same, but you can control the ranges perfectly (while ignoring the fact that the random trigger itself is not perfect)

there's another part to this ai code which ws what initially made me use ranges, but tthat involves big changes on hwo the ai is coded; instead of using player change states directly, what it does is change the state of a helper, the state of the helper is checked in the cmd as if it was a command (so the ai is acutally inputting commands, not changing states),  the helper itself follow a state map depending on the character, difficulty, etc.. the simplest version has the same map regardless off difficulty and the difficulty is used to amke the helper change state faster, thus giving the ai "faster reflexes".

ink

Re: AI Discussion
#10  January 22, 2017, 03:45:23 am
• inktrebuchet

• Online
Okay after looking over this a good amount, I don't understand how these pieces of code can be different. I would think storing a random amount in a variable would just make things slower. What am I missing here?

Code:
`[state n, 1]type = varsettrigger1 = var(1) = random[state n, 2]type =changestatetrigger1 = var(1) = [0,100]value = n`

Code:
`[state n]type =changestatetrigger1 = random < 100value = n`

Edit:
Are you saying you would give each state a completely different var range trigger to ensure no overlap?

I'm glad I'm such an ignorant old man, that will keep this discussion informative!
Last Edit: January 22, 2017, 03:48:44 am by ink

Jesuszilla

Re: AI Discussion
#11  January 22, 2017, 05:28:52 am
• Loyal to the Game
VarSet: trigger1 = 1

And yes, different ranges.

Cyanide

Re: AI Discussion
#12  January 23, 2017, 12:33:04 am
• Legendary XIII
• I am the eye of the storm to come!
Using E's method allows you to have the game pick from 1 of multiple options each tick and there is an almost equal chance it will be any one of the options. Good if you want SOMETHING to happen in a specific situation, but don't care which of the 3 it is. Random on it's own won't guarantee that, or grant an equal chance to all 3.

Using random by itself you technically have decreasing probability for each attack as the cmd is read sequentially. Each one is read, and either activated or discarded in sequence, and there is the potential for none of them at all.

Overlaps in random don't matter at all.

In M.U.G.E.N there is no magic button

They say a little knowledge is a dangerous thing, but it's not one half so bad as a lot of ignorance.

ink

Re: AI Discussion
#13  January 23, 2017, 05:30:26 am
• inktrebuchet

• Online
Thanks for clearing that up Cyanide! I have been trying to think of a formula to change the probability for a var range and still keep them from overlapping.
Spoiler, click to toggle visibilty
The second half E's post has still got me stumped though. Just over my head at this point I guess.

I've been working on a project, a piece of code (that's not character specific) that will help the AI appear to learn. I've got it up and working now, just need to triple check everything before I post it here.

Are there any other known strategies for making a character appear to have learned? The simplest I could think of was to have a character count the seconds it was defeated in and update its "random conditions" accordingly as the match unfolds.
Last Edit: January 23, 2017, 02:28:58 pm by ink

Bastard Mami

Re: AI Discussion
#14  January 23, 2017, 06:05:37 pm
• [E]
The second half E's post has still got me stumped though. Just over my head at this point I guess.

the varrandom part is used to make sure the changestates trigger the way it's expected, now onto the second part, it's the way the ai is coded that is different to the regular way mugen ais are coded.

first we havea state map,s by that I mean, a series of states that have a meaning, I'll use examples:

state10000 is the base state for the ai helper. now state 10100 means that the character is close to p2 while state 10200 means that the character is far to p2, so in state 10,000 there are to change states to go to either 10200 or 10100.

now in 10200 we have 3 change states, 10210 is a projectile attack, 10220 is a jab, 10230 is "nothing" ; once the change states to 10200 is done we do the varset form 0 to 999. if the var = [0,500] we change to 10210, if it's =[501,600] we change to 10220 and if it's [601,999] we change to 10230.
now after some test you think your ai is jabbing a lot so maybe you change the range to 501,551 so it jabs half the time.

+ the do nothing state is good, because, following cyanide's theory, I like making it so the custom ai does nothing and gives the mugen ai a chance to move around or even block.

now, one thing with this method is that I don't have to worry about the ai breaking any rules. lets say you have your usual cms changestates code. that has no ai trigggers at all ,let's use the hadouken for an example, so you have :

triggerall = aiLevel = 0

this is not indispensable, but it's easy to do and gives better accuracy to the ai

now, what matters for real is making a copy of the hadouken change state, let's say in the bottom of the cmd file, then you take out the command trigger and instead add a

triggerall = helper(AI ), stateno = 10210
triggerall = aiLevel > 0

the rest of the change states triggers remain the same for both the player's changestates and the ai changestates so the ai won't be breaking any rules AND your ai code/state map does not need to take in account those triggers as well making the code simpler and cleaner. and simpler code means that you can use a few helper vars to make it more complex so it can learn and do other fun stuff.

there's more to this method, like making the triggers in map depend on ai level, or adding buffer states so that a hadouken takes 10 ticks to get performing instead of being instant like a jab.

Bastard Mami

Re: AI Discussion
#15  January 23, 2017, 06:12:26 pm
• [E]
I know this is a double post, but I prefer to do it like this, so the different points don't get mixed.

Are there any other known strategies for making a character appear to have learned? The simplest I could think of was to have a character count the seconds it was defeated in and update its "random conditions" accordingly as the match unfolds.

a simple thing I did was make it so the ai becomes "faster" whe it has less life left, I don't know how one would do it in the usual ai methods, but in the method I discussed previously, moving around the state map (the changestates) had a triggerall = time =5 . then i changed it to time = var(5) whiel thevalue of var 5 depends on how much life is left, sicne the max life is 1000 var5 = life / 200, so the character takes 5 ticks to react when it's life is close to the max, and reacts almost instantly when it's really low on life.

just one example, dunno how to do something like that using the regular ai coding method of putting ai-character changestates in the cmd file, tho I think someone put ca}}vars sets instead of changestates in the cmd, and thena dded a count down var for similar effects.

Jesuszilla

Re: AI Discussion
#16  January 23, 2017, 09:04:43 pm
• Loyal to the Game
Are there any other known strategies for making a character appear to have learned? The simplest I could think of was to have a character count the seconds it was defeated in and update its "random conditions" accordingly as the match unfolds.

Felicia's projectile safety check is basically trial and error. "Did I get through the projectile with this?" "Nope, try this one." "Did that work?" "Yes." "Then keep using it.

Doesn't work for pure helper projectiles though, sadly. I may put an invisible projectile in mine that stays alive as long as the helper is just so projectile detection can work.
Last Edit: January 26, 2017, 11:39:16 pm by Jesuszilla

Bastard Mami

Re: AI Discussion
#17  January 24, 2017, 01:00:42 am
• [E]
one of the basics of ai learning is:

ai does something, while the ai is dong something it checks what are the result, if it's a good result, it should do something more often, if it's a bad result it should do the something less often.

so, you will nedd to eventually use variables in the random-ranges.

ink

Re: AI Discussion
#18  January 24, 2017, 05:24:35 am
• inktrebuchet

• Online
Thanks for pointing these out guys, you've been really helpful.

Thanks again [E] for expanding on your method, It makes a lot more sense now! I wasn't thinking outside the box enough.

I will study up more and be back I'm sure. Hopefully this thread gets filled with ideas, If nothing else at least all of this info is a little easier for everyone to find now.
Last Edit: January 24, 2017, 06:41:57 am by ink

ink

Re: AI Discussion
#19  February 05, 2017, 10:10:07 pm
• inktrebuchet

• Online
Back with some good reads that seemed fitting to share here. These were my 2 favorites to read through, each have a good amount of ideas and strategies used in games. (not specifically fighting games.)
https://web.archive.org/web/20141112121924/http://www.gamasutra.com/blogs/JonShafer/20120910/177436/The_Recipe_for_Good_AI.php

From reading up on strategies that programmers use for AI, I have found a lot of the ones I really liked and wanted to work towards are a little more difficult, the main obstacle being the amount of time a user actually spends with the AI... Most people spend maybe 3 rounds with the AI, for around 3 minutes max each round. This doesn't give the AI much time to pick up on patterns or playstyles. So any "learning AI" at that point would be mostly guessing since hardly any data on the user can be collected in that amount of time.

*I'm not saying that there's any reason to not try and make such an AI, just that longer time with the user would be better.
Last Edit: February 06, 2017, 12:14:33 am by ink

Cyanide

Re: AI Discussion
#20  February 05, 2017, 10:30:46 pm
• Legendary XIII
• I am the eye of the storm to come!
Mugen has an incomplete, and non functional AI file type that is meant to learn and save across games. If you add ai = file.ai into the .def file it gets created and gradually fills up as the AI uses the character.

Sadly, as per previous testing it does absolutely nothing in gameplay terms, or what it does do is absolutely negligible. We're talking like 51% win percentage vs something with no AI at all.

In M.U.G.E.N there is no magic button

They say a little knowledge is a dangerous thing, but it's not one half so bad as a lot of ignorance.