Back to Blog
VideogamesMay 5, 20267 min read

How Pokémon's Genetics Actually Work

A deep dive into IVs, EVs, and breeding mechanics: what these systems can teach us about designing creature progression in games.

IM
Ignacio MelendezFull-Stack & Game Developer
How Pokémon's Genetics Actually Work

I've been rebuilding the stat system for a creature collector I'm working on.

The first version was blunt: flat values per species, no variation between individuals. It worked mechanically, but the collection loop felt completely hollow. Why catch a second Slime if it's identical to the first one?

So I went back to the source and did what any self-respecting developer would do: I reverse-engineered Pokémon.

Pokémon has always had this duality: a simple RPG on the surface, an absurdly layered system underneath. Once you start digging, you realize that two Pokémon of the same species and level can have measurably different stats. This isn't a glitch. It's the entire point.

1. Three Separate Systems, One Final Number

Every stat a Pokémon has is the result of three independent inputs working together. None of them is enough on its own. Understanding each one separately is what makes the whole thing click.

  • Base stats (defined by species, never change).
  • IVs (genetic potential, fixed at creation).
  • EVs (training, earned by the player).

What I find genuinely elegant about this is that each layer solves a different design problem. They're not three ways to do the same thing. They're three completely different kinds of input that happen to combine into one number.

2. Base Stats: Species Identity

Every species has a fixed set of base stats. A Garchomp has high Attack and Speed. A Blissey has absurd HP. These values don't vary between individuals of the same species. They're the identity of the species, not of the creature.

In data architecture terms, base stats belong to the species definition, not to the individual Pokémon instance. In C# that might look like:

C#
1[Serializable]
2public class SpeciesData : ScriptableObject
3{
4    public int baseHP;
5    public int baseAttack;
6    public int baseDefense;
7    public int baseSpAttack;
8    public int baseSpDefense;
9    public int baseSpeed;
10}

Every Pokémon instance references this data rather than storing its own copy. Classic data-driven design: change the base stats for one species and every Pokémon of that species recalculates automatically. No migration, no manual updates.

3. IVs: The Genetic Roll

IVs (Individual Values) are where things get interesting. When a Pokémon is created (whether caught in the wild or hatched from an egg), each of its six stats gets a randomly assigned IV between 0 and 31.

That's it. Six integers, range 0 to 31.

C#
1[Serializable]
2public struct PokemonIVs
3{
4    public int hp;
5    public int attack;
6    public int defense;
7    public int spAttack;
8    public int spDefense;
9    public int speed;
10}

The first time I understood this properly, my reaction was something like: "that's almost insultingly simple." But those six integers solve a real design problem.

How do you make every instance of a creature feel meaningfully unique without simulating anything complex?

Two Pokémon of the same species at the same level can feel noticeably different to use, because one has a 31 in Speed and the other has a 12. No extra simulation required. No procedural generation. Just a random integer stored at creation time.

From a systems design perspective, this is extremely elegant. You get meaningful individuality from minimal computation. The system is trivially cheap to evaluate and yet creates enormous diversity.

You don't need procedural generation to make individuality feel real. A single integer stored at creation time is enough, if your formula uses it meaningfully. The elegance isn't in the number, it's in what the formula does with it.

4. EVs: What You Actually Did With It

EVs (Effort Values) are the training layer, and the only one the player has direct control over.

Unlike IVs, which are fixed at creation, EVs are earned by defeating specific Pokémon. Fighting a Machoke gives Attack EVs. Fighting a Gastly gives Special Attack EVs. The system creates a direct link between what you fight and what your Pokémon becomes.

The system has hard caps that force tradeoffs:

  • 252 EVs maximum per individual stat.
  • 510 EVs maximum across all stats combined.

You can't fully maximize everything, so specialization becomes a deliberate decision. You're not just training. You're committing to a specific build.

The separation between IVs and EVs is the most interesting design decision in the whole system. IVs are luck. EVs are intent. Both affect the same final number, but they represent completely different kinds of investment. Two genetically identical Pokémon can end up playing differently depending on how they were trained, and that's by design.

IVs and EVs solve different player emotions: one gives a reason to keep hunting, the other gives a reason to keep investing. Your game probably needs both, though they don't have to look anything like Pokémon's implementation.

5. The Stat Formula

Internally, the game calculates stats using a formula roughly like this:

Stat = floor(((2 × Base + IV + EV/4) × Level / 100) + 5)

HP uses a slightly different version. The core structure is the same.

Notice the weighting. IVs contribute directly; EVs are divided by 4. This means genetics set the ceiling that training fills in, and you'd need 4 EVs to get the same incremental benefit as 1 IV point. That isn't an accident.

In code, resolving stats on demand looks something like this:

C#
1public static class StatResolver
2{
3    public static int Resolve(
4        int baseStat,
5        int iv,
6        int ev,
7        int level)
8    {
9        return Mathf.FloorToInt(
10            ((2f * baseStat + iv + ev / 4f) * level / 100f) + 5f
11        );
12    }
13
14    public static int ResolveHP(
15        int baseStat,
16        int iv,
17        int ev,
18        int level)
19    {
20        return Mathf.FloorToInt(
21            ((2f * baseStat + iv + ev / 4f) * level / 100f) + level + 10f
22        );
23    }
24}

Storing a final stat value is the same mistake as caching derived data: it looks harmless until you need to rebalance. Store only the inputs; derive everything else on demand. Adjust the formula, and every stat in the game recalculates without touching a single Pokémon's data.

6. Breeding Is Just IV Optimization

Once you understand IVs, breeding becomes obvious. It's a convergence algorithm.

When two Pokémon produce an egg, the child inherits some IVs from its parents (three by default, more with mechanics like Destiny Knot). The rest are randomly generated. Players use this to progressively converge toward creatures with perfect IVs across all stats.

C#
1public class BreedingService
2{
3    private const int InheritedIVCount = 3;
4
5    public PokemonIVs Breed(PokemonIVs parentA, PokemonIVs parentB)
6    {
7        var child = GenerateRandomIVs();
8        var stats = GetAllStatIndices();
9        var inherited = stats.OrderBy(_ => Random.value)
10                             .Take(InheritedIVCount);
11
12        foreach (var stat in inherited)
13        {
14            var source = Random.value > 0.5f ? parentA : parentB;
15            SetIV(ref child, stat, GetIV(source, stat));
16        }
17
18        return child;
19    }
20
21    private PokemonIVs GenerateRandomIVs()
22    {
23        return new PokemonIVs
24        {
25            hp        = Random.Range(0, 32),
26            attack    = Random.Range(0, 32),
27            defense   = Random.Range(0, 32),
28            spAttack  = Random.Range(0, 32),
29            spDefense = Random.Range(0, 32),
30            speed     = Random.Range(0, 32),
31        };
32    }
33}

The algorithm is simple. What it produces is a long-term optimization loop: players breed across generations, slowly locking in perfect values stat by stat. The depth isn't in the code. It's in the goal the system creates.

7. Conclusions

Dissecting this system left me with three things I keep coming back to:

  • Potential vs. progression. IVs are what your creature could become. EVs are what you chose to do with it. Both affect the same final number, but they represent different kinds of investment, and both feel meaningful in their own way. If your game only has one of these, something is probably missing.
  • The formula as a design statement. The fact that IVs outweigh EVs isn't an implementation detail. It's a deliberate philosophy. Your creature's ceiling is mostly set at birth. You might not want that in your own game, but you should be aware of what your formula communicates.
  • Small randomness, large diversity. A range of 0 to 31 across six stats costs almost nothing to compute and produces enormous variation between individuals. You don't need complex procedural generation to make a collection feel worthwhile.

My creature system doesn't look like Pokémon's (different goals, different loop, different audience). But understanding exactly why these systems work the way they do gave me much more clarity on what I was actually trying to solve.

Sometimes the best thing you can do before designing a system is to spend a few hours carefully taking apart one that already works.

Related Articles

View all articles
Replicating Mewgenics' Genetic System in Unity

Replicating Mewgenics' Genetic System in Unity

A technical breakdown of how to design a flexible genetic system in Unity, inspired by the breeding mechanics of Mewgenics.

Fire Emblem's Stats and the Illusion of Tactical Depth

Fire Emblem's Stats and the Illusion of Tactical Depth

Fire Emblem's growth rates are simple percentage rolls, but they generate brutal variance, emotional attachment, and entire subcultures of save-state manipulation.