Home Creators Posts Import Register Favorites Logout

Content

all right, so i spent pretty much all of yesterday going through your-- well... azery's feedback, since he was 95% of it, and making various changes to teams per recommendations-- not that i did everything he said, but he did have a lot of good points, and pointed out a couple things i either didn't know or had forgotten, like king's rock not stacking with serene grace. the lad knows his pokemons.

aside from that-- more AI. i've gone through just about everything except some generalized switching problems + a certain e2 compendium of problems, and i just ran out of time and energy hard last night and hit the floor like a let body

but what did i actually do?
i don't have a clue
but that's what my notes are for

U-Turn Moves

the ai has been super friendly with them. way tooooo friendly. sooooo friendly. we have handlers for looking at if we have dropped or lowered stats and switching more or less often accordingly, so i multipled those by like.... five so it cares a lot more about stats. and i turned down the multipliers on pretty much everything else about the move... and then i realized the real issue. 

one of the things we ask for u-turn is if the attacker is confused/toxic'd/attracted or seeded. if we are it's pretty helpful to get the hecko out of dodge... and among those it's especially helpful to break leech seed because that is both definitely hurting you and healing them every turn and will be completely invalidated by switching out. so, we weight leech seed a little higher. score *1.5. well it turns out! that part of the code wasn't finished. it looked like marcello had copy pasted it and then forgotten to tweak it so it was actually just always applying that *1.5. oops. no wonder it liked u-turn moves so much! i thought this was just a matter of our numbers overshooting the move's effect, and maybe it was, but we found a bug here too.

Protect Moves (and specifically King's Shield)

okay, so from what i hear pokemon are using protect move wayYyYyYyYy too much right? they just spam it and dont give a fuck about anything. well, we have code that's supposed to make them less and less likely to use it as the rate of protect failure goes up, so what's up with that homie. the code boiled down to something like "total at end of scoring / protectrate"

i thought something about this might be bugged so i had the cellist take a look at it. i don't exactly remember what he changed, but what i do remember is that we decided to have that cut scale much more harshly than we were. like say, triple the protect rate and divide by that -- chotto matte kudasai-- so that instead of having it divide -- ch-chotto!!-- by 1/2/4 after successive uses it would divide by 3/6/12-- i said wait!!!!

did you say
divide?
:eyes:

...so yeah we had yet another instance of our world-famed division error.

that said since it was at the end of scoring usually the score had already become a decimal by that point so it wasn't actually the root of all evil but it was something that needed to be caught. 

so i was testing to see what numbers i could tweak for king's shield specifically after marcello made the *3 change and i was noticing something really strange... everyone was saying it liked protect way too much, but... it really didn't want to use it against me at all. why was that?

i put down some debug messages and traced the problem back to-- that same ending protectrate line. what? it was just always dividing by 3, even if it hadn't been used yet. as i checked on it, i noticed that the reason was as such-- it's supposed to only do that division if there is a protectrate, aka if a protect move has been used and it's likely to fail. 

in that case, we thought the protectrate variable would be 1. so we were asking it to divide when protectrate was more than 0. turns out protectrate actually starts at 1, so we were asking it to divide by 3 in the first place. instead of 0/3/6/12 it would be 3/6/12/24. oops. no wonder it didn't want to use the move. by asking it to start when it's more than 1, we get 0/6/12/24-- which is more correct since we aren't cutting it by default, but perhaps a little too harsh, so i trimmed down the multiplier to compensate. 0/4/8/16 is our final result division piece. i think this works out well.

so now that we've got that line actually working, how about the rest of the scores... it certainly seemed to like protecting so i shouldn't need to do too much in that condition but with king's shield in particular i noticed it would get pretty risky with attacking vs pokemon that were just sent out. so we're adding in an extra condition to make it more likely to protect, get aegislash back to stance change, and lower contact sweepers atk right after sending one out.
but that's still not a guarantee it'll do that, so you know, don't get too comfy with your set-up moves or whatever.

Poison Attacks

i mentioned in an older post that i'd caught a problem with poison moves where it just really would never want to use them. so i was a little disheartened when i noticed incidentally that it was really harshing the vibe on attacks like Poison Jab that had it as a secondary effect even where it should have been a good decision. whatup homie.

debug messages fan out. turns out the root of the issue is right where i should have expected it to be-- in the part of the function code that only activates for damaging moves that have it as a secondary effect. this part of the code is supposed to divide (don't worry-- we got that covered by now) the resulting score by the chance of the secondary effect occuring. it's something like
miniscore = result
miniscore-=100
miniscore / effect chance
miniscore+=100
miniscore/100
to convert it from a score like, 70, or 120 to 0.7 or 1.2 that'll play nice with our normal scoring. i've mentioned it a bit before but those operators, like -=, += set the initial variable to the result of the math automatically-- they're super handy.
only.
turns out that "miniscore-=100" had been typo'd as "miniscore=-100". subtle difference to see, but huge in math. instead of subtracting 100, we're just setting it equal to negative 100. that means it was throwing out all of the calculation and was just so sure that the poisoning the opponent would be an awful idea. oops. easy fix though.

Hyper Beam returns!

one of the reports we got for alpha was that PULSE Abra didn't much like to use hyper beam. we talked about this yesterday, 'member? considering that hyper beam is the only thing that makes PULSE Abra practical to beat-- the AI is right to hate it. buuut considering that hyper beam is the only thing that makes PULSE Abra practical to beat-- we really need ZEL to use it anyway. 

our fix for this after internal was doubling the hyperbeam score to make up for cutting it in half since it's a two turn move. i wrote yesterday about how this broke the function code for doubles. after reflecting on it more, the numbers i was seeing didn't seem like a *2 was going to make up for them so i decided to test a little more-- and glad i did.

i had forgotten that aside from cutting it for the recharge turn, i also have the AI thinking about how many pokemon the player has left-- if they've got a bunch, it's a bad idea to use because they'll send something in to punish. more pokemon they have, more likely they have something to really make a beamer suffer. when the player has fewer pokemon left it dislikes hyper beam left. technically it should only use hyper beam to finish off the player's last pokemon-- but i didn't mind adding a little lee way into the AI since the result of a free turn might be something more like the player beats the beaming pokemon with one pokemon left-- feels clutch. feels good. even though it's inefficient, i don't mind making those scenarios.

...anyway because it scaled based on pokemon left it was clear to me that a flat *2 or *3 wasn't going to cut it. i'd either undershoot it or overshoot it almost every time. sooooo what's a gal to do.
well, she's to make the condition of the battler being ZEL skip calculation for the function code entirely. who cares if it's an awful idea, let's just look at the base damage and hope for the best-- then again ZEL is pretty much trying to lose that battle anyway so i guess that's fine. but yes, i had it switch to solely the base damage for hyper beam instead of thinking about the recharge turn at all.

...but the scores were still so low. why??? it's like what i was doing to it was having no effect at all--
oh. it wasn't.
because the code used to ask who the opponent trainer is is busted. i should've noticed that yesterday. marcello should've noticed it before too. but we didn't. ka-whoops.

so, how was it busted?
simple--
instead of asking if the trainer was ZEL, it was actually incorrectly asking if the player is ZEL. 

so you know, there you go, ama.

...it also applies to adrienn. any adrienn-kin in the room? no? well, all right... adrienn is the only other trainer we currently ask for by name since xe needs to blow the misty field away to get fairy tale field-- but normally we tell the AI that you probably shouldn't blow your own mist away if you've got a team full of fairy types. adrienn does not care. xe's got something better planned.
except xe doesn't because it depends on the player being adrienn which just isn't going to happen. 

shucks.

--

so when i started taking notes for and writing this post, i was thinking all of our posts so far have been about ai bugs-- this time i can finally talk about just tweaking scores that are actually working as intended.
turns out all of these are bugs too.
huh.
awkward.

Comments

ZEL

"instead of asking if the trainer was ZEL, it was actually incorrectly asking if the player is ZEL. so you know, there you go, ama" w-whaddaya mean, 'incorrectly'. The only real error I see here is that it'll assume the answer is 'no'. ...Kidding, but that's the best thing I've read all night.