2,310 stat values, confirmation runs locked in before checking, and one rounding detail most estimates miss
Every Pal in Palworld has hidden talent values (the community calls them IVs). Players want to know what their Pal really has, so they can decide which one to breed from. The question sounds simple: given a Pal's level, talent, stars, Souls, trust and passives, what HP, Attack and Defense does the game show?
The usual answer is a decimal formula, something like stat * (1 + passive / 100) and then round. It is close. It is also wrong in a lot of small places, and small is enough when you want to recover a hidden number from a displayed one. I wanted the exact version, so I worked it out and then checked it against the game.
Why estimates miss
Two things.
First, float32. Every step of the calculation behaves like a 32-bit float, and each step rounds on its own. Decimal constants such as 0.075 or 0.01 are not exact in float32. A percentage like 5% becomes 104.99999237060546875, not 105. When the true answer sits on a rounding boundary, a decimal formula lands on the wrong side.
Second, order. There are three separate integer truncations in the growth part: after level growth, after stars, after Souls. Do them in another order, or merge two, and you are off by one often enough to matter. For example, a level 40, two-star Mammorest shows Defense 440, not 441. Multiplying level by 0.075 first puts the grown value just under 401 before the first cut, and the three cuts keep that difference.
Method
I modelled the formula from the in-game stat breakdowns, then tried to break it.
- I built test worlds from my own save, so every Pal had known inputs: level, talent, stars, Souls, trust, passives.
- Before each round of checks I wrote down my predictions, froze them and published a SHA-256 hash of the sheet. The first confirmation set was committed at 18:17 UTC on 12 November 2026, before I looked at a single number in game.
- Then I compared my numbers with what the game shows on screen. Maximum HP comes from the Palbox. Attack and Defense come from the summary screen.
- Wrong predictions stay in the record. If a rival hypothesis lost, it is still in the data, marked as lost.
Result: the formula matches 2,310 checked stat values. That is 2,128 values in the historical IV-only set (including 58 frozen confirmation values) plus 182 new values from modifier checks. 1,771 are individual readbacks and 539 are outcomes explicitly confirmed equal to a named prediction. I keep those two kinds apart in the data, on purpose.
One honest note: this is v3.0 of the paper, for one game build (25246127). Most of the early rows were compared retrospectively; only 58 values in the historical set are frozen predictions in the strict sense, and the L-series modifier checks were frozen separately. The dataset says which is which, row by row.
The formula
Let q mean "round to float32". In JavaScript that is Math.fround. Every operation rounds separately, in a fixed order. Here is the Attack and Defense display step, as the paper states it:
const q = Math.fround;
// round to nearest integer, exact ties to even
function evenRound(y) {
const f = Math.floor(y), d = y - f;
if (d < 0.5) return f;
if (d > 0.5) return f + 1;
return f % 2 === 0 ? f : f + 1;
}
// S = growth integer after the three cuts, P = sum of eligible passive percent
function shownAttack(S, P) {
const rho = Math.max(q(0.1), q(q(q(P) * q(0.01)) + q(1))); // passive rate, floor 0.1
const p = q(q(100) * rho);
const w = q(q(S) * p);
const d = q(w * q(0.02)); // doubled stat value
const y = q(d + q(0.5));
return Math.floor(evenRound(y) / 2);
}
shownAttack(1050, -47); // 556, the in-game value (decimal maths says 557)
shownAttack(1510, 5); // 1585
shownAttack(2805, 30); // 3647
The growth integer S comes from three truncations. Level growth is L * 0.075, then multiplied by the talent-adjusted base, plus 100 for Attack (50 for Defense). Stars add 0.05 each to a factor, Souls add 0.03 per rank, and each factor multiplies and is cut to an integer. Talent adds 0.003 per point to the factor on the base. Trust adds a per-rank increment to the base, and awakening multiplies the base by 1.1 before trust. HP has its own order: add 10 after the talent product, multiply by 0.5, then by level, then add 500. HP skips the percent round trip and truncates to thousandths. The paper has every equation.
What modifiers do
I checked these in game too, with predictions frozen first. The rules, as the paper states them:
- Food and hunger. Hunger multiplies the passive rate (100 normal, 90 hungry, 80 starving) before the stat product. Food multiplies the 0.02 constant before the doubled-value product. Applying decimal food and hunger factors to an already rounded stat gives wrong numbers. HP ignores both.
- Own Attack Up and Defense Up passives. Once a Pal has been summoned in the party, its own Attack Up and Defense Up passives (levels 1 to 4) stop contributing, and this stays after recall. Other stat passives, good or bad, keep working.
- Emblems. The player's emblem adds to the party Pal's passive percentage, including while the Pal is in its sphere. Example: +16% Attack and +20% Defense for the emblems I tested. It adds to the other eligible percentages. During testing I also saw the Pal part of the emblem bonus vanish from the displayed stats mid-session until I reloaded the world. I could not find the trigger, so I report it as observed, not explained.
- Partner skills. Helper bonuses add linearly per eligible helper (four Dragon helpers gave 4 times 8%, not a multiplier). A helper of the same species does not count. When several Pals of the same species supply one bonus, only the maximum is used: 15% and 30% gives 30%, not 45%.
- Level Sync. The game shows a synced level (for example "Level Sync Lv55 >> Lv50"). Attack and Defense follow the synced level, and HP keeps the real one. I checked 12 values against predictions frozen beforehand, and all matched (paper v3.1).
What is open
- Calculator, free, no account: https://lorearmory.com/palworld/iv-calculator/ . Enter a Pal's numbers to get its possible IVs, or go the other way.
- Paper with every equation and the worked example: https://doi.org/10.5281/zenodo.24189999
- Dataset (2,582 CSV rows, frozen prediction sheets, hashes, screenshot manifest): https://doi.org/10.5281/zenodo.24190003 . CC BY 4.0. The DOIs are the all-versions links.
- Save reader: the calculator can read your own Pals from a save file you choose, entirely in your browser, with nothing uploaded. The decompressor behind it is open: https://github.com/anantoni/palworld-save-decoder/releases/tag/v1.0.0 . The code is a WebAssembly build of the ooz decompressor, about 120 KB. The reader is MIT; the bundled ooz decompressor is GPLv3, so if you ship the wasm file, offer its source with it.
Closing
The lesson for me was how much a small rounding rule matters when you want to run a formula backwards. If you build tools for any game, freeze your predictions and hash them before you look. It keeps you honest, and it makes the result worth citing.
If you find a case where the formula is wrong, I want to know. Questions and corrections are welcome in the comments.
Top comments (0)