Research Legends: Arceus Battle Mechanics Research

With how thorough you are I feel like we're kind of quickly running out of options here, but:
-did you check every move? Maybe a random move just happens to run some number for this.
-You can get charms to help out, I dont think any of them actually deal with damage that we know of, so maybe it'd be a blind spot? Like the status charms might have secret damage reduction against moves that cause status conditions. Or is this also covered by "full playthrough" like using items on pokemon in the overworld
-it looks like you already fiddled with star ranking while playing the game and testing out the low ranks with alphas, but since I'm just running down the list what about something like "full star rank" and "all perfects" on the pokedex
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
-did you check every move? Maybe a random move just happens to run some number for this.
No, I did not test every single move in the game. Which move(s) do you feel need(s) special testing?
If you have a big list, can you help test some of them?
I did check the signature moves for Dialga, Palkia, Giratina, and their alternate forms.

what about something like "full star rank" and "all perfects" on the pokedex
You are welcome to perfect every single entry in the Pokédex and tell me if it modifies damage differently from the formula. I am not going to put in this much effort for a shot in the dark.
 
No, I did not test every single move in the game. Which move(s) do you feel needs special testing?
Moves that come to mind:
-Moves that make you "fixated". In particular I remember no one being sure what this "status" actually did since you could still freely choose moves. In particular I'd probably look at both the traditional double power moves (Ice Ball) and the "outrage" type moves (Outrage, Petal Dance, etc)
-Recoil moves. There's quite a few of them, maybe one of them had different properties. Wave Crash I'm sure you've already looked at, but perhaps Double Edge or Wood Hammer.
-Moves that both deal damage and heal you, like absorb.
-Moves that splinter. Both the move itself, the splintering, and using hte move post-splinter. Splintering is a new side effect and I didn't see it in the list of damage effects in Marty's post (unless it's meant to be "fixed offensive damage")
-Moves that don't have any extra effect whatsoever. There's not that many of those in LA that I can tell, so seems worth throwing out an extra X-Scissor if you hadn't already

It's might overkill (since most moves that work similarly in gameplay probably work similarly internally) but I'd probably test at least two from each "category" just to be safe if you hadn't already just from your full playthrough.
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
Moves that come to mind:
-Moves that make you "fixated". In particular I remember no one being sure what this "status" actually did since you could still freely choose moves. In particular I'd probably look at both the traditional double power moves (Ice Ball) and the "outrage" type moves (Outrage, Petal Dance, etc)
-Recoil moves. There's quite a few of them, maybe one of them had different properties. Wave Crash I'm sure you've already looked at, but perhaps Double Edge or Wood Hammer.
-Moves that both deal damage and heal you, like absorb.
-Moves that splinter. Both the move itself, the splintering, and using hte move post-splinter. Splintering is a new side effect and I didn't see it in the list of damage effects in Marty's post (unless it's meant to be "fixed offensive damage")
-Moves that don't have any extra effect whatsoever. There's not that many of those in LA that I can tell, so seems worth throwing out an extra X-Scissor if you hadn't already

It's might overkill (since most moves that work similarly in gameplay probably work similarly internally) but I'd probably test at least two from each "category" just to be safe if you hadn't already just from your full playthrough.
I have tried at least one of every category of these during a regular playthrough.

We already know what fixated does; refer to the modifiers in Marty's post on the previous page, or to the first option under Effects on the first page.

Splinter is also in the first post under Effects.
 
  • Like
Reactions: R_N
You are welcome to perfect every single entry in the Pokédex and tell me if it modifies damage differently from the formula. I am not going to put in this much effort for a shot in the dark.
I'll be honest my assumption was you were modifying the game into various states or pulling on different save files from others to check several of your ideas. Otherwise I'd probably have not suggested that particularl one so off the cuff.
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
I'll be honest my assumption was you were modifying the game into various states or pulling on different save files from others to check several of your ideas. Otherwise I'd probably have not suggested that particularl one so off the cuff.
The Dex is such a complex structure that the best anyone can do is manually hack every single entry one-by-one into a poor semblance of "perfect", and nobody has put in the effort to improve this. If that's enough or considered "easy", someone else can do that too.
 
  • Like
Reactions: R_N

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
I tried to figure out what formula is used in a simple example: Snorlax level 70 Double vs Blissey 44 Def. In the game, I got these rolls: [305,309,312,316,320,324,327,330,334,337,341,345,349,352,356,360] but the classic formula predicts (rounding in th end): [306, 309, 313, 316, 320, 324, 327, 331, 334, 338, 342, 345, 349, 352, 356, 360]. Has anyone figured out how the game rounds?
I get your damage values by doing the calculation this way:
  1. Calculate initial damage with the damage formula (the way the game does it has some slight differences from the empirical formula, which may affect precision a little bit). I get the max damage as 288 using Attack 204, Defense 44, Level 70, Base Power 100.
  2. Calculate the 16 damage values. This is a pretty simple multiplication by the percent and divide by 100 where we drop the decimal point. You should get 244, 247, 250, 253, 256, 259, 262, 264, 267, 270, 273, 276, 279, 282, 285, 288.
  3. STAB modifier of 5120 is applied, and then the product is divided by 4096. The rounding for this step rounds down if the decimal point is 0.5 or lower, and up otherwise. You should get 305, 309, 312, 316, 320, 324, 327, 330, 334, 337, 341, 345, 349, 352, 356, 360.
I'll be verifying my formula vs other data before posting up a writeup of the math. Thanks for sharing yours.
 
The Dex is such a complex structure that the best anyone can do is manually hack every single entry one-by-one into a poor semblance of "perfect", and nobody has put in the effort to improve this. If that's enough or considered "easy", someone else can do that too.
An unsatisfying but possible theory is that this code represents a feature that did not make it into the game, or that was removed from this game but present in the others. It may be this unknown_mod is never changed during gameplay. Maybe the devs didn't scrub all the conditions and logic for some unknown feature.
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
An unsatisfying but possible theory is that this code represents a feature that did not make it into the game, or that was removed from this game but present in the others. It may be this unknown_mod is never changed during gameplay. Maybe the devs didn't scrub all the conditions and logic for some unknown feature.
This is why I said earlier:
This is untestable. I'm looking for something that can be tested because it's easy to say it could be any number of untestable things.
Deciding it's unused is unfortunately a matter of excluding everything else we can think of that it could be. If we started by saying it's unused, then there would be no testing.
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
A few weeks ago, Marty and I put our heads together to figure out how all the damage modifiers are applied. This math is reverse-engineered from the game binary, so it should be exactly how the game calculates damage and applies all the modifiers. I finally got some time this week to verify the math in-game.

A note on rounding before we start... I will use this notation to indicate rounding 0.5 and under down to the next lowest integer, and everything else up:
1659324797032.png


Additionally, it's impossible to have every single modifier, but I'll still use alphabetical variables to show how it is applied to the damage value from previous steps.

1. Initial Damage
This is what the Japanese video determined empirically early on. The actual calculation looks like this:
Code:
initial_damage = (unsigned int)(float)((float)(unsigned int)(float)((float)(unsigned int)(float)((float)((float)(damage_atk_power_coef + (float)damage_calc_info->attacker_atk)
    + (float)(damage_atk_level_coef * (float)damage_calc_info->attacker_lvl))
    * (float)damage_calc_info->base_power)
    / (float)(damage_def_power_coef + (float)damage_calc_info->opponent_defense)) / damage_denominator);
I've simplified it to be a bit more readable. The game fetches these variables from a flatbuffer and then does float arithmetic with them, so the order of operations is important for precision.
1659321190404.png


2. Attack/Defense Modifiers
This is the offensive and defensive multipliers for "Power Boost", "Guard Boost", "Power Drop", "Guard Drop". These can only have one of 3 stages: -1, 0, and +1. If the attacking Pokémon’s attack stage is the same as the opponent Pokémon’s defense stage, skip this step. Critical hits do not affect this step.

If the attacker’s attack stage is boosted or the opponent’s defense stage is decreased, then the respective modifier is 1.5.
If the attacker’s attack stage is decreased or the opponent’s defense stage is boosted, then the respective modifier is 0.66.
1659321520381.png


3. Unknown Modifier
Potentially unused. See this post for what’s been tried. Every case where it was observed used 4096. This modifier was also present in v1.0.0. I include this for completeness sake in case someone figures out what it is in the future. If the modifier is not 4096, this is applied to it:
1659321662355.png


4. Rain Fire Damage Modifier
Active when a fire move is used in the rain. The inner calculations are done as floats. The value of this modifier is 75.

First, convert the modifier into a multiple of 4096:
1659321734499.png


If rain_fire_damage_mod_4096 is 4096, this step is skipped. Otherwise, it's applied like so:
1659321785902.png


5. Critical Hit Modifier
This is a simple 1.5x multiplier. Again, this doesn't negate defense boosts.
1659321982801.png


6. Damage Roll Modifier
Similar to the main games, this has the option to use the minimum damage roll of 85. I do not know if/where this is used in LA.
Otherwise, this ranges from 85 to 100. The RNG is Xoroshiro128+.
1659322025546.png


7. STAB (Same Type Attack Bonus)
If the attack is the same type as the user, this modifier is 5120; otherwise it is 4096.
1659322176516.png


8. Effectiveness Modifier
This is whether a move is super effective or not very effective. This uses float multiplication. In LA, the exact modifiers are:
  • 0.4 - Both types resist the attack type.
  • 0.5 - One type resists the attack type and the other is neutral.
  • 1.0 - Neutral damage.
  • 2.0 - One type is weak to the attack type and the other is neutral.
  • 2.5 - Both types are weak to the attack type.
1659322235107.png


9. Burn/Frostbite Modifier
Burn weakens physical attacks and Frostbite weakens special attacks. Both modifiers are set to 50.
1659322265957.png


10. Drowsy Modifier
Drowsy Pokémon take more damage. This modifier has a value of 133.
1659322288667.png


11. Fixated Offensive Modifier
Fixated Pokémon deal more damage. This modifier has a value of 150.
1659322361273.png


12. Fixated Defensive Modifier
Fixated Pokémon also take more damage. This modifier has a value of 133.
1659322383295.png


13. Primed Modifier
The primed status, e.g. from Double Hit, Victory Dance, or the Twice-Spiced Radish, increases damage. This modifier has a value of 150.
1659322415368.png


At this point, the final damage is dealt to the target.

I've included all the disassembly on my GitHub gist for people who are curious to see what I worked with.
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
One of the battle mechanics that interested me was how Legend form Arceus picks its type for Judgment. I believe a lot of this has been determined empirically elsewhere, but it's not on this thread, so I will write it up here.

The algorithm works like this:
  1. Starting from type 0 (Normal) to type 17 (Fairy), try each type versus the opponent's typing. If the effectiveness of the type is higher than the previous highest effectiveness, clear any previous "best types" and store the result in a new byte array.
    1. This check actually has the ability to get an effectiveness versus 3 opponent types; I assume this is left over from the main games where Trick-or-Treat and Forest's Curse can add another type.
  2. Take the opponent's first type and compare it offensively versus the list of "best types". Remove all entries that are not the most resistant.
    1. Essentially, this is checking how resistant Arceus would be against the opponent if it picks that type to transform into.
  3. Take the opponent's second type and compare it offensively versus the remaining list of "best types". Remove all entries that are not the most resistant.
    1. This uses a new resistance counter, so even if one of the "best types" is more resistant to the second type than the first type, it won't be preferred.
  4. If the remaining list of "best types" has more than one entry, Xoroshiro128+ RNG is used to randomly pick one.
  5. If there are no entries in the list of "best types", the default is to use Arceus's current type. I don't believe this is achievable.
As an example, this is how it works against Paras:
  1. Normal type (0) is checked versus Paras. There aren't any previous types in the list, so neutral is the most effective and added to the array of "best types."
  2. Fighting (1) is checked versus Paras. It's not better than Normal, so it is skipped.
  3. Flying (2) is checked versus Paras. It's more effective than Normal, so the previous array containing only Normal is reset and Flying is added as the only entry.
  4. Poison (3), Ground (4), Rock (5), Bug (6), Ghost (7), Steel (8) are all checked and not more effective than Flying, so they're skipped.
  5. Fire (9) is checked versus Paras, and equally effective as Flying, so it's added to the array. The array now contains Flying, then Fire.
  6. The rest of the types aren't more effective than Fire or Flying, so let's skip them here. The game will check them anyways.
  7. Paras's first type is Bug, which is then checked versus Flying and Fire. Both are equally resistant to Bug type, so neither is removed.
  8. Paras's second type is Grass, which is checked versus Flying and Fire. Both are equally resistant to Bug type, so again neither is removed.
  9. There are two types left, so Xoroshiro128+ RNG rolls for 50% of either.
The game creates a list of each enemy Pokémon's best type for Judgment to display in the menu, and this is calculated at the start of the battle and end of every turn (whether it's yours or the opponents') if Judgment is in play. This allows the types chosen to change between turns.

Obviously, the player would never notice that their table was regenerated after an enemy turn since you cannot use Judgment outside of your turn. The game furthermore does this after you try to run away as long as Arceus was your active Pokémon.

-----

I also checked how Hidden Power works and it is very similar except there is no defensive check. Essentially, the game iterates through type 0 to type 17, makes a list of the most effective types, and breaks any ties that come up.

Similar to the exuberant recalculating of Judgment, Hidden Power is recalculated for every battle start and end of battle turn, even when no Pokémon in the battle have Hidden Power. It is even calculated for your active Pokémon even if the opponent does not have Hidden Power.

-----

I've included all the methods that handle Judgment and Hidden Power here: https://gist.github.com/Lusamine/daa4300f5ca7e5bce674c7edef3dbc5e

One of the interesting things I noticed in the effectiveness methods is that the game checks a boolean that allows the type effectiveness to be inverted. I assume this is left over from Inverse Battles.
 
Last edited:
One of the battle mechanics that interested me was how Legend form Arceus picks its type for Judgment. I believe a lot of this has been determined empirically elsewhere, but it's not on this thread, so I will write it up here.

The algorithm works like this:
  1. Starting from type 0 (Normal) to type 17 (Fairy), try each type versus the opponent's typing. If the effectiveness of the type is higher than the previous highest effectiveness, clear any previous "best types" and store the result in a new byte array.
    1. This check actually has the ability to get an effectiveness versus 3 opponent types; I assume this is left over from the main games where Trick-or-Treat and Forest's Curse can add another type.
  2. Take the opponent's first type and compare it offensively versus the list of "best types". Remove all entries that are not the most resistant.
    1. Essentially, this is checking how resistant Arceus would be against the opponent if it picks that type to transform into.
  3. Take the opponent's second type and compare it offensively versus the remaining list of "best types". Remove all entries that are not the most resistant.
    1. This uses a new resistance counter, so even if one of the "best types" is more resistant to the second type than the first type, it won't be preferred.
  4. If the remaining list of "best types" has more than one entry, Xoroshiro128+ RNG is used to randomly pick one.
  5. If there are no entries in the list of "best types", the default is to use Arceus's current type. I don't believe this is achievable.
As an example, this is how it works against Paras:
  1. Normal type (0) is checked versus Paras. There aren't any previous types in the list, so neutral is the most effective and added to the array of "best types."
  2. Fighting (1) is checked versus Paras. It's not better than Normal, so it is skipped.
  3. Flying (2) is checked versus Paras. It's more effective than Normal, so the previous array containing only Normal is reset and Flying is added as the only entry.
  4. Poison (3), Ground (4), Rock (5), Bug (6), Ghost (7), Steel (8) are all checked and not more effective than Fire, so they're skipped.
  5. Fire (9) is checked versus Paras, and equally effective as Flying, so it's added to the array. The array now contains Flying, then Fire.
  6. The rest of the types aren't more effective than Fire or Flying, so let's skip them here. The game will check them anyways.
  7. Paras's first type is Bug, which is then checked versus Flying and Fire. Both are equally resistant to Bug type, so neither is removed.
  8. Paras's second type is Grass, which is checked versus Flying and Fire. Both are equally resistant to Bug type, so again neither is removed.
  9. There are two types left, so Xoroshiro128+ RNG rolls for 50% of either.
The game creates a list of each enemy Pokémon's best type for Judgment to display in the menu, and this is calculated at the start of the battle and end of every turn (whether it's yours or the opponents') if Judgment is in play. This allows the types chosen to change between turns.

Obviously, the player would never notice that their table was regenerated after an enemy turn since you cannot use Judgment outside of your turn. The game furthermore does this after you try to run away as long as Arceus was your active Pokémon.

-----

I also checked how Hidden Power works and it is very similar except there is no defensive check. Essentially, the game iterates through type 0 to type 17, makes a list of the most effective types, and breaks any ties that come up.

Similar to the exuberant recalculating of Judgment, Hidden Power is recalculated for every battle start and end of battle turn, even when no Pokémon in the battle have Hidden Power. It is even calculated for your active Pokémon even if the opponent does not have Hidden Power.

-----

I've included all the methods that handle Judgment and Hidden Power here: https://gist.github.com/Lusamine/daa4300f5ca7e5bce674c7edef3dbc5e

One of the interesting things I noticed in the effectiveness methods is that the game checks a boolean that allows the type effectiveness to be inverted. I assume this is left over from Inverse Battles.
Well the leftovers might just be for ease of porting the code.
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
Well the leftovers might just be for ease of porting the code.
It's incredibly common to see reused/unavailable code in Pokémon games. For example, Legends has elements of the normal capture formula, Friend Balls in Legends give 150 friendship if you manage to use one, and even the original damage formula is present. I'm just commenting that it's there, not that it means anything significant. It'd be interesting if they used the same type determination in the regular games, but only if those leftover elements are available again in those particular games.
 
Last edited:
One of my friends told me that in the Japanese version of PLA: The Complete Guide, Springtide Storm is stated to "always hit when the weather is rainstorm". I tested several moves during MMO in Obsidian Fieldlands and Coronet Highlands, and confirmed that the following moves never missed in 32 trials.
Hurricane
Thunder
Bleakwind Storm
Wildbolt Storm
Sandsear Storm
Springtide Storm

The book only mentioned this effect for Springtide Storm and not for Hurricane or Thunder. Since these do not appear to be stated in game, more research is required to reveal whether there are other hidden effects on weather.
 
This check actually has the ability to get an effectiveness versus 3 opponent types; I assume this is left over from the main games where Trick-or-Treat and Forest's Curse can add another type.
Since the game has the unique modifiers of 2.5 for double weakness and 0.4 for double resistance, I wonder if there are unused modifiers for triple weakness and triple resistance?
 

Anubis

HONK
is a Community Contributoris a Top Researcheris a Battle Simulator Admin Alumnusis a Community Leader Alumnusis a Smogon Discord Contributor Alumnus
Since the game has the unique modifiers of 2.5 for double weakness and 0.4 for double resistance, I wonder if there are unused modifiers for triple weakness and triple resistance?
The disassembled pseudocode is included at the end of the damage formula writeup right above the post you quoted, so you can see for yourself if there are additional modifiers. It's in the linked function "apply_damage_effectiveness_modifier".
 
Since the game has the unique modifiers of 2.5 for double weakness and 0.4 for double resistance, I wonder if there are unused modifiers for triple weakness and triple resistance?
Why would there be? Trick-or-Treat and Forest's Curse aren't in PLA.
 
Why would there be? Trick-or-Treat and Forest's Curse aren't in PLA.
The same reason the game has the ability to check effectiveness versus 3 opponent types. It's most likely a leftover from main games but there's always the chance those moves are cut late into the development after they've decided the modifiers for triple weakness/resistance.

The disassembled pseudocode is included at the end of the damage formula writeup right above the post you quoted, so you can see for yourself if there are additional modifiers. It's in the linked function "apply_damage_effectiveness_modifier".
Cheers, there isn't one unless I'm mistaken. I don't quite understand the pseudocode but I think the game just uses x1 modifier for anything that's not x2.5, x2, x0.5, x0.4, or x0.
 
Last edited:

Users Who Are Viewing This Thread (Users: 1, Guests: 0)

Top