Done HP Percentage mod inaccuracies

What type of bug are you reporting? Unsure

What is the bug?
Before you stop reading, this is not about cartridge accuracy!

HP Percentage Mod typically rounds up all percentages up (unless that would incorrectly round up to 100%). When the HP percentage is an exact %, sometimes the game incorrectly rounds up.

This happens at:
  • 7% (shows 8%)
  • 14% (shows 15%)
  • 28% (shows 29%)
  • 55% (shows 56%)
  • 56% (shows 57%)
I tested this on 100 and 20 max HP.

Are you able to replicate it? If so, how?
100 Max HP: https://replay.pokemonshowdown.com/gen9natdexdraft-2152720944-6ktxtu0jbn0a21xvxvjeeqfag16xlwwpw

20 Max HP: https://replay.pokemonshowdown.com/gen9natdexdraft-2152706527-r31ypg08n0vxtqkra4lte748wj3tycjpw

When reproducing, make sure you're in a format which doesn't show exact HP values to both players (i.e. NOT Custom Game!)
 
This is a server-side bug; the protocol the client is receiving is incorrect. The battle in this case demonstrates a 1-damage hit 100 times.

Lvl 1 0 Atk Smeargle Beat Up (7 BP) vs. Lvl 40 100 HP 0 IVs / 0 Def Tera Fighting Cloyster: 1-1 (1 - 1%) -- possibly the worst move ever

|upkeep
|turn|8
|
|t:|1719761413
|move|p2a: Cloyster|Withdraw|p2a: Cloyster
|-boost|p2a: Cloyster|def|0
|move|p1a: Smeargle|Beat Up|p2a: Cloyster
|-resisted|p2a: Cloyster
|-damage|p2a: Cloyster|57/100
|-resisted|p2a: Cloyster
|-damage|p2a: Cloyster|57/100
|-resisted|p2a: Cloyster
|-damage|p2a: Cloyster|56/100
|-resisted|p2a: Cloyster
|-damage|p2a: Cloyster|54/100
|-resisted|p2a: Cloyster
|-damage|p2a: Cloyster|53/100
|-resisted|p2a: Cloyster
|-damage|p2a: Cloyster|52/100
|-hitcount|p2a: Cloyster|6

The reason this happens is because of floating-point imprecision in Javascript. To take your example of 56/100:
1719880236193.png


This is how HP Percentage Mod calculates the value to send to the client.

JavaScript:
let percentage = Math.ceil(ratio * 100);
if ((percentage === 100) && (ratio < 1.0)) {
   percentage = 99;
}
shared = `${percentage}/100`;

So the issue is due to floating-point imprecision.
 
Does the game suffer from floating-point imprecision when calculating the health bar colour? Currently the sim use this.hp / this.maxhp > 0.2 as its test. (It also tests for 0.5 but obviously that's precise in floating point arithmetic.)
 
Does the game suffer from floating-point imprecision when calculating the health bar colour? Currently the sim use this.hp / this.maxhp > 0.2 as its test. (It also tests for 0.5 but obviously that's precise in floating point arithmetic.)
If you're asking about SV, looks like what it does is calculate 200 - 200 * (currhp / maxhp) without any floor/ceil/round. If this value is >= 160, it's red; else if it's >= 100, it's yellow; otherwise it's green.

For example, 62/307 gives 159.6091205 which is yellow, and 61/307 gives 160.2605863 which is red.

This is handled in lua so it's not clear to me if it's single- or double-precision floating point since it looks like it can be specified.
 
Last edited:
Can't we just change the order of the operations?
JavaScript:
const ratio = this.hp / this.maxhp;
...
let percentage = Math.ceil(100 * this.hp / this.maxhp);
if ((percentage === 100) && (ratio < 1.0)) {
    percentage = 99;
}
shared = `${percentage}/100`;
I'm not sure what you're asking. Apparently at least some of the time the game itself doesn't take steps to avoid floating-point inaccuracy, so it's possible that the sim shouldn't try either.
We're not even using the cartridge 200 value. If we want cartridge accuracy, then let's send decimal values to the client in SV. If not, we've already agreed that PS will use percentages, so we can just fix this accordingly.
I just don't see a reason to have inaccuracies that are also inconsistent with the cartridge.
 
Last edited:
Back
Top