Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Generation VII Glitch Discussion

Damage rollover - Page 1

Damage rollover

Posted by: SadisticMystic
Date: 2018-05-11 22:23:01
So it turns out that the damage formula that's been in place ever since BW is structured so that if the damage figure, or any intermediary result at any point in the formula, exceeds 2^32, only the lowest 32 bits of precision are kept and anything above that is simply discarded without incident. Even as this capacity has apparently been in the game for quite a while, it became much easier to reach the rollover point with the uncovering of Rollout storage, and in fact that mechanic is what first led me to hypothesize the existence of this one, and then to concoct the test suites that would definitively prove it was a real thing. I have three separate battle videos, all recorded on the Ultra games (under the battle protocol version that corresponds to patch 1.1-1.2), that demonstrate this in various ways.

AHMW-WWWW-WWWL-YQN7
Here the attacker is a level 95 Pikachu, with a raw attack stat of 239 after a Power Split (since 239 is too high for Pikachu to reach without that help), then +6, Light Ball, Huge Power, and Flower Gift all applied on top of that. The defender is a minimum-defense Smeargle at -3 (the smallest change that makes it possible to reduce a stat to 1 point), and Pikachu (who was turned into a Water-type specifically to remove STAB) is using Bolt Strike with the help of a Charge last turn, two Helping Hands this turn, and a latent 32x boost from rollout storage. Those numbers were carefully calibrated so that upon multiplying all the main factors together, the result would be 4,295,116,800. But the registers in the 3DS can't hold a number that big, so it really counts as just 149,504, and this scenario sees to it that everything in the damage formula that comes after that point is focused on knocking the number down, not building it up. Between the burn, the double resist, the usual division by 50, and the random variation roll, the damage range would have been around 10 million if rollover wasn't a thing, but if it was, I would expect a damage range of 317 to 374. Sure enough, the actual damage ended up being 347, which could fit within Mew's health bar (after it transformed into Smeargle) without being a KO. In the battle video, you can observe that it survives in red health.

55VG-WWWW-WWWL-UQGX
This one is especially egregious. Mewtwo goes Mega-X (increasing its attack stat from 346 to 522 in the process), steals a Belly Drum, and gets its ability changed to Huge Power, before a level 74 Mew transforms into it (because I specifically wanted the combo of 74 and 522, and this was the most convenient way to do it). Later on, a level 1 Growlithe gets to -6, and with the help of Sunny Day and Flower Gift, Mewtwo proceeds to use Flare Blitz (via Me First, for a 50% bonus) against Growlithe. This time, if you multiply together all the factors that led to rollover in the first video, you only get 34,953,120, which fits with plenty of room, but we're not done yet. Weather boosts don't apply until after that big multiplication, and they're also not implemented in the most intuitive way: instead of being "multiply by 3, then divide by 2", a positive weather boost is actually "multiply by 6144, then divide by 4096". Normally there's not much of a difference between those two operations, but of course it's possible to get a rollover in between those two steps, and the 6144 version is far more susceptible to it. In fact, this test was again carefully engineered so that the rollover after the multiplication would reduce the number to 81920, and the division further knocks it down to 20, enough so that with just the single resist afterward, the level 1 Growlithe survives with its standard health bar, as the damage range is 8-10.

GBXG-WWWW-WWWL-YQNC
This setup was built along similar lines to the first one, but with slightly tweaked numbers. Pikachu is now level 100 instead of 95, its attack stat after the Power Split is 269 instead of 239, and instead of a Charged Bolt Strike, the attack it uses is Power Trip with 10 boosts (for 220 power). This was intended to produce the number 4,295,047,680, which would roll over to the smaller margin of just 80,384, and after the burn and the resist, the damage range was supposed to be 170-201. But upon trying it out in practice, the damage dealt was only 74, which is smaller than my prediction by enough of a margin that even an extra factor of 1/2 wouldn't be enough to get down that far. I suspect the culprit here is something that has to do with the inner workings of Power Trip, which hasn't yet been documented, but since it takes a pretty precise landing spot to roll over by just enough of a margin that the remainder doesn't exceed a Pokemon's health bar, it's unclear what that mechanism could be. Increasing the move power to 221, for instance, would cause the margin of rollover to exceed 40,000 damage, which is way too much to be detectable. Any ideas?

Re: Damage rollover

Posted by: SadisticMystic
Date: 2018-08-28 09:46:10
The explanation for that third battle (which was actually, chronologically, the first) comes in two parts. First, if you have Rollout stored and you use a move with variable power, the formula's "determine a variable power" step will apply that Rollout multiplier to whatever the move's raw power is in the data table, to the exclusion of any other effect for setting power. For example. Low Kick's power is normally clamped to multiples of 20, between 20 and 120, but its raw power is actually coded as 1. If you use Rollout in such a way that it has a lingering multiplier, and follow that up with Low Kick, the 16x or 32x multiplier will be applied to 1, rather than to any multiple of 20, and this obviously isn't a very impressive effect. Return, Frustation, Gyro Ball, Electro Ball, Fling…all those moves are listed as 1 power in the table. Not all variable-power moves use 1, though: Eruption/Water Spout start at 150, Rollout/Ice Ball use 30 (which is why their escalating turns give them the correct power under normal circumstances at all), and Power Trip/Stored Power use 20 as the default. So instead of 220x32, that test is only using 20x32 as the power…but that, by itself, moves the damage estimate up from 170-201 into the high six figures. That's only further away from the observed data point at 74!

To explain what's going on there, and why overflow is actually easier to reach than ever imagined, we need one more test.

UJ8W-WWWW-WWWS-9YPA
This test needs just one turn of setup: a level 94 Lucario goes mega (to get a SpA stat of 350) and uses Calm Mind once (to 525), while the other side sets up a Leech Seed for a level 1 Aron to use as a source of eternal health recovery. Lucario can then fire off Aura Spheres turn after turn, while Aron and Gliscor just waste time. The first twelve Aura Spheres drop Aron down to Sturdy range (before Leech Seed recovers all the way back to full), while the unlucky 13th hit does…nothing at all!

A naive accounting of the damage formula here indicates that, depending on the random roll, the range is (55704, 56360, 57016, 57664, 58320, 58976, 59632, 60288, 60944, 61600, 62256, 62912, 63568, 64224, 64880, 65536). Of course, what's actually happening is these hits are quick and repeatable ways of fishing for that top-end random roll, and given the conspicuous number that it is, this test proves there's one final step to the damage formula: trimming the damage all the way down to fit in 16 bits (not just 32). Further, based on the fact that it's allowed to result in 0 damage, this step must take place after they think they've constrained the damage minimum to 1. The probable reason for this is that each stat only has 2 bytes allocated to it (HP will never be more than 714, which is a 10-bit number, for instance) and when it actually comes time to deal the damage, they don't want to try subtracting a 4-byte number from a 2-byte number.

That said, if we apply these two morsels of knowledge to the Power Trip case, the revised damage rolls there are (43293, 53054, 62816, 7041, 16803, 26564, 36326, 46087, 55849, 74, 9836, 19597, 29358, 39120, 48881, 58643). That means the 74 was just a 1/16 shot, and any of the other 15 shots would have been a clean KO and I would never have had reason to suspect that this final 16-bit truncation existed at all. But it did land on that one roll to open the rabbit hole that much deeper.

Re: Damage rollover

Posted by: Torchickens
Date: 2020-03-20 11:27:35
Hi SadisticMystic, how does this relate to Gen 4-? Thanks. In Gen 3 you can heal Pokemon with Water Spout/Eruption using Pomeg Pokemon with high HP. https://m.youtube.com/watch?v=OdHRxG9jC0U

Re: Damage rollover

Posted by: SadisticMystic
Date: 2020-03-23 08:32:46
If you want to play around with a detailed breakdown of the damage in 5+, https://docs.google.com/spreadsheets/d/14XBTYYRp1OK5epQzB3SF2ccdSkuA6Jv7UlRQi66pxkY/edit?usp=sharing exists and should take into account every place it's possible to roll over. I'm not aware of any disassembly for 4, and haven't put together the steps for 3 in the right order to be able to make sheets for those (and don't even have any games from 4 or 5 to be able to test in them). However, I do know of a few relevant data points from them:

At least the 16-bit overflow at the end is present in gen 4, in common with the current formula structure.

Having 0 defense in the current games is impossible without hacking (can't go lower than 4 x 0.25), but if you do, a 0 defensive stat counts as an infinitely high stat as the game hits the panic button rather than attempt to divide by 0, and the only damage you get comes from the +2 term and whatever comes afterward. In gen 3, the 0 stat can be realized by Leering a level 2 wild down to 1 defense, then hitting it with Explosion–which shows that the game handled it the same way even back then! (I suspect that hacking a stat up to exactly 6554 in gen 3 may also cause it to count as 0, due to the ground-state stat fraction being 10/10 there instead of 2/2 like it is in more recent games.)

Has that Water Spout scenario been stepped through in a debugger to see what's going on? The Water Spout power variable is documented as a u8, but stock tests with Wailord are sufficient to prove that they at least hardened it against naive 8- and even 16-bit rollovers early on. 65534/401 HP could be counting as 193 power, 24513, or some totally unexpected number–any pointers there?

Re: Damage rollover

Posted by: Torchickens
Date: 2020-03-23 09:42:31
Thanks for the input :). Umm when I tried it, it was from a suggestion from a viewer but I haven't stepped it through with a debugger unfortunately, sorry. (Ah like the Protect chance thing)