• Follow our Instagram!
  • Curious about what we're currently doing about bots? Check out the latest updates from staff in this thread.

Needs Triage Bug Report - Mechanics

What type of bug are you reporting? Mechanics

What is the bug?
[Gen 3] Impossible damage amount in battle: https://replay.pokemonshowdown.com/gen3orrecolosseum-2546663533-xdjesq2c4mk38hxtvrou36wmyox29q3pw

In the replay on turn 2, a modest 252 spa ev zapdos uses tbolt to OHKO a 160 hp ev starmie behind a light screen. According to the damage calculator, the max roll for this scenario is 300 dmg which should not kill starmie at 301 hp. pic of damage calc

!showteam commands are run at the end of the game to verify the sets. Zapdos was not holding magnet.

Are you able to replicate it? If so, how?
I have not been able to replicate. I tried a couple other times to run this scenario and the tbolt does not kill, but I might not be getting max roll.
 
Months later, I thought this was interesting BobaFett so I recreated it in Desmos. If anybody else occasionally pops in to the Smogon forums to read old bug reports, this one's for you! I am not a dev!

Here's an example where the damage calculator and sim's damage tables don't overlap at all.
1790953581480.png


The simulator is not accurate for gens 1-4, apparently, as discussed here, here, and elsewhere I'm sure. After checking out how Emerald, the PS Damage Calculator, and Showdown handle Gen 3, I've learned that Showdown applies stat and damage modifiers in a few different ways but the real offender is this monstrosity, modify():
1790948582769.png

DUN DUN DUN...!
I guess this is the math that Gen 5+ uses? I believe the purpose is to round down at 0.5 or lower and round up otherwise, whereas the early generations aggressively truncate to integers after every single divide. Even if the multiplier is "* 2", Emerald will usually do something like "* 20 / 10".
Look at the difference! Math!
1790949168376.png

But modify() is used frequently in the sim, like every time runEvent() is called to modify damage, including for the Light Screen event
1790949421847.png

which grabs a multiplier from here:
1790949879614.png

and applies it to baseDamage within runEvent() here:
1790949933566.png


modify() is used for STAB in the above situation as well.
1790949533219.png


Now I had thought that chainModify() might be introducing rounding errors as well since it uses similar math. It turns the doubles Light Screen multiplier of 2/3 into an approximation of 2/3, but the singles multiplier of 1/2 still equals 1/2. However, the difference in the doubles multiplier doesn't introduce further error in the Desmos demonstration as you can see in the formulas folder. (Feel free to play with the sliders!)
1790950709766.png

1790950986444.png


I recall Hydrametr0nice saying fixing the early gen situation would be time-consuming and yeah, what a pain this would be. As far as the functions I was interested in for this project, the Damage Calculator's code looks accurate to Emerald and is a fair bit easier to read, but this isn't really a situation where swapping in new functions would help, right? Adding something like integerModify() and integerChainModify() would help with accuracy, but the big obstacle is the event system. You'd have to branch depending on gen1-4 or gen5+ within runEvent() or even within modify() to point at new functions and I don't how possible that is because I can barely understand it. Another option would be to forego events for early gens and just hardcode everything in scripts.ts, moves.ts, abilities.ts, and so on for gen 1 to 4 and that sounds soul-crushing to me. But I wonder if it makes sense to backport the current system. Like, if there's such a difference between the eras, should they be connected in the sim in the first place? It isn't really working now.

.
.
.
I just did this for fun. I don't even go here.
 
Back
Top