Greetings, you probably don’t know who I am. I’m Falirion, one of the Programmers for Rejuvenation. So if I work on Rejuvenation what am I doing on Reborn’s devblog? Well since Reborn, Rejuvenation and Desolation all share our primary codebase I was asked (yes, asked, please ignore the banging on the barricaded door in the background) to talk a bit about one of the more major code reworks that have been done during 19.6’s development, the rework of the move resolution in battle, a part of the Code that was essentially rewritten from scratch. I will give the warning right now, this is going to get technical.
So let’s start with the obvious first question. Why? Why fully rewrite a section of the code that was already working fine? Well, because while in the grand scheme of things it was working correctly, about 95% of cases or so, there were several existing bugs that were ultimately deeply rooted in how we actually handle the resolution of moves. We had a collection of bugs that all ultimately boil down to a certain older bug that has plagued the codebase since before I was even part of this community and probably even since the start of Reborn’s development.
Our older Players may remember the so-called “spread damage bug”, a bug in which, when using a damaging move that affected multiple opponents, the second affected target would take more damage than it should, if the first affected target fainted to the attack. This was due to the double battle spread damage reduction not applying to the second target because, due to the first target fainting, the game didn’t recognize anymore that it should reduce this damage for being spread damage. Now of course this bug has been fixed for a while so why is this relevant? The fix to this bug is what a programmer colloquially refers to as “duct tape”, a more or less sloppy fix that resolves the issue but doesn’t really address the root cause, like using duct tape to try and keep your headphones from falling apart instead of replacing them. In the earlier mentioned bug collection almost all of them were a variation of this: something happened when dealing damage to target 1, and this would then affect how the move interacts on target 2 (typically the damage) when it in fact shouldn’t do this. Some examples are Moxie, Beast Boost, Soul-Heart and Water Spout or Eruption vs Rowap Berry.
And the root cause is the same we were for all these years doing move resolution wrong, simple as that. The issues can be boiled down to 3 key points: Timing, Referentiality and Structure.
Before explaining these, a quick aside. When explaining these I am going to refer to 2 Moves in particular Stomping Tantrum and Dragon Darts. This is because the functionality of these 2 moves taught me a fair bit about how the move execution needs to be to work correctly. And while I assume that most people reading this are familiar with Pokémon mechanics, for clarity a quick rundown:
- Stomping Tantrum is a damaging ground type move which doubles in power if the previous move the attacker used has failed… for most reasons, hitting protect for example does not activate this power boost.
- Dragon Darts in single battles is just a 2 hit attack, kinda like dragon type double hit. In double battles however this move has a quality we will call smart targeting, it will attempt to hit both opponents once each, if however the move would fail against one of the targets, it will ignore that target and instead hit the remaining target twice.
So since we are now on the same page...
Of the primary issues Structure is by far the most important one, but I will keep it for last so let’s start with Timing. Now, in the old move execution the general order of things isn’t inherently wrong; first check that the move doesn’t fail, then calculate and apply the damage and then handle the effects. It’s just the logical order of things. However the failure check was happening way too late, in particular for dragon darts, by the time the failure check was happening we had already determined which targets we are hitting and how often. Which is a problem for Dragon Darts because it needs to know whether it would fail or not to determine who to hit and how often in the first place. As such we had to move failure checks a lot earlier and while doing so we noticed, a lot of specific failure conditions were checking at the wrong time entirely, in fact type immunities and primal weathers were part of the damage calculation which is just wrong on so many levels.
So let’s talk real quick about failure conditions, in Reborn 19.5 code they are generally in 2 places, at the start of move execution in a method called “pbTryUseMove”, which covers things like being asleep, paralyzed and other things that prevent the move from happening and as such not using PP, and “pbSuccessCheck” which covers just about all the rest just before the move would deal damage. If only it was so easy… After the rework we categorize them into 4 categories (numbered 0 to 3 because we are programmers so we start counting at 0).
- category 0 is “pbTryUseMove” and is largely the same as before so moving right along.
- category 1 is new entirely, timing wise it happens after subtracting PP, but before the activation of protean for example. This includes things like primal weathers and queenly majesty, the move is canceled in its entirety, usually irrespective of the explicit target (queenly majesty is a side effect ability, who actually has the ability is irrelevant). Only exceptions here are sucker punch and poltergeist, which directly check for the target here.
- category 2 and category 3 are both equivalent to “pbSuccessCheck” and are still in this method. Why are these categories separate if they are in the same place? Well I personally also call Category 3 "the group of random move specific failure conditions that exists because Pokémon code always has to be weird and wacky" but that’s a mouthful. The difference between Category 2 and 3 is that Category 2 conditions are checked before checking Accuracy while Category 3 conditions are checked afterwards. To be frank I was tempted to ignore this but there is a quirk about this that is relevant to Stomping Tantrum.
Which leads us to Referentiality, an issue largely specific to Stomping Tantrum, as mentioned earlier not all failure conditions actually activate Stomping Tantrum’s power boost. Hitting into a target’s Protect (or equivalent) for example. Another group of failure conditions which don’t count for Stomping Tantrum are in fact all Category 3 failures. Any Failure condition that happens after the accuracy check will not activate the damage boost. Which brings us to the key problem, how do we even recognize why a move failed? Can we even? In the old move execution, we could not, the move failed and there was no reference as to why.
Additionally in the Timing category I mentioned that we are checking move failure before determining who and how often we hit them. There is a problem with this, when we check whether a move fails against a certain target now, we are before the point where we handle anything, so we have to delay the effects and player feedback for these failures. Which means we need to know why a move failed after the check is finished. As such we are using what we call hit flags.![]()
In the above screenshot you see a bit of the failure handling, along with a lot of examples of these hit flags. They are kept for each target the move targets and make note of what happens to the move against that target. For Stomping Tantrum’s case we can check against these hit flags and make the effect not activate if any of the ones that shouldn’t trigger it are included.
So lastly Structure. The primary problem was that when handling moves damaging multiple targets, we were handling targets sequentially, which is to say one after the other. We were checking failure conditions, calculating damage, applying damage, applying effects and so on for one target fully before moving on to the next. Which is the root cause for most of the bugs I mentioned at the start. So if that is wrong what is actually correct? The targets in canon are handled in parallel so we first check for move failure for all targets before then handling those failures for all relevant targets, before calculating damage on all targets, before applying… you get the idea. This approach prevents what happens to the first target affecting what happens to the second, because the damage you are dealing to the second target has already been calculated. This also lets us remove the Duct tape fixes and have overall cleaner code. So how do we actually know that canon works this way? Dragon Darts is a big hint. Not only do we need to know whether the move fails against all targets before calculating damage, we can also tell that failure checking works similarly in parallel based on how Dragon Darts acts when it fails against both targets. When Dragon Darts fails against both targets the player will only receive the feedback for one of those targets, the other target being ignored entirely. The feedback received relates to the target whose failure condition has the least priority when checking failure conditions
Let’s look at the reworked pbSuccessCheck real quick.![]()
What we see here is that first it creates an Array of hit flags, one hit flag for every target the move targets. Initially the hit flag is on “:Success”, indicating a move that connects with the target. Then it checks each possible failure condition, in order for all targets before checking the next one, in order on this screenshot, whether the target is hidden via the effect of the ability Commander (gen 9 ability jumpscare!), whether the target is in a semi-invulnerability turn (like Fly or Phantom Force), whether a priority move is blocked by psychic terrain and whether the move is blocked by Wide Guard. Between each of these it runs a method called “successCheckFinished?” which ends the check when it detects that the move would fail against all targets at this point and also does some filtering for Dragon Darts to remove the first target that failed. The point here is that the failure condition check also runs in parallel and has a very specific order it checks these conditions for and this order matters.
Structure was also significant in a different way, fixing this required a ton of work.
Depicted here is the method "pbEffect" as it is in 19.5 Reborn the primary method of move handling, each move with an effect subclasses (overwrite it with their own modified version which can still call into this higher level version of the method) this method. The issue is this method bundles together, everything; damage calculation, damage application, move animation, move effects, literally everything. And to make the previously mentioned fixes to the structure we had to untangle this method, separate the components so we can do each step separately for all targets instead of doing it all for one target. Which due to the subclassing meant, we had to rewrite every single move, all the several hundred moves that exist in the game, we had to fully rewrite in a new structure. I have to give a shoutout to the Community Cooperation Initiative, modders that signed up to work directly on the codebase without being part of the dev teams, maybe even canonize their mods and such things. Without the help of all of them, rewriting all these moves in the new structure would have taken much longer than it did. Thank you for your help in this and everything else since.
Now there is more I could talk about here, but I have probably already been rambling way too much. As a TLDR: we rewrote the entirety of the move execution because the rebornian games had some key things wrong here for several years if not more than a decade, which allowed us to fix some long standing bugs which were not fixable otherwise.
So why should you, the player, care? Under the hood it changed completely but for gameplay it remained essentially the same except we fixed some bugs, right? Essentially yes, but all this also allowed us to streamline things, for example this:

You can probably tell by the UI that this clip is from Rejuvenation not Reborn, but it works just the same in Reborn too.
Nice, right? enu asked me to ensure when rewriting the move execution that we can implement simultaneous damage dealing and health bar movement. Doesn’t just look nice but also speeds up move execution a fair bit.
Uhh… looks like the door barricade isn’t gonna hold much longer, so I gotta bounce, hope you found this interesting, I know I can get way too much into details, so excuse the long explanation. Have a nice day!
Sounds of a door breaking open
You will never take me alive!
-
9








Recommended Comments
There are no comments to display.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.