Overview
PKHeX.Core provides generation-specific classes for creating Pokémon entities. Each generation has its own format (e.g., PK9 for Gen 9, PK8 for Gen 8) that inherits from the base PKM class.
Creating a New Pokémon
Basic Creation
To create a new Pokémon, instantiate the appropriate generation-specific class:
using PKHeX.Core;
// Create a new Gen 9 Pokémon (Scarlet/Violet)
var pk9 = new PK9();
// Create a new Gen 8 Pokémon (Sword/Shield)
var pk8 = new PK8();
// Create a new Gen 7 Pokémon (Sun/Moon)
var pk7 = new PK7();
Setting Basic Properties
Once you’ve created a Pokémon entity, you can set its core properties:
var pk = new PK9
{
Species = (ushort)Species.Pikachu,
Form = 0,
Gender = 0, // Male
Nature = Nature.Adamant,
Ability = (int)Ability.Static,
CurrentLevel = 50,
Ball = (byte)Ball.Poke,
IsNicknamed = true,
Nickname = "Sparky",
OriginalTrainerName = "Ash",
OriginalTrainerGender = 0, // Male
Language = (int)LanguageID.English
};
The Species enum contains constants for all Pokémon species. Use proper casting to ushort when assigning species values.
Setting IVs and EVs
Individual Values (IVs) and Effort Values (EVs) control a Pokémon’s stats:
// Set perfect IVs (31 in all stats)
pk.IV_HP = 31;
pk.IV_ATK = 31;
pk.IV_DEF = 31;
pk.IV_SPA = 31;
pk.IV_SPD = 31;
pk.IV_SPE = 31;
// Set EVs (max 252 per stat, 510 total)
pk.EV_HP = 252;
pk.EV_ATK = 252;
pk.EV_SPE = 6;
Setting Moves
Each Pokémon can have up to 4 moves:
pk.Move1 = (ushort)Move.Thunderbolt;
pk.Move2 = (ushort)Move.IronTail;
pk.Move3 = (ushort)Move.QuickAttack;
pk.Move4 = (ushort)Move.ElectroBall;
// Set PP (Power Points)
pk.Move1_PP = pk.GetMovePP(pk.Move1, pk.Move1_PPUps);
pk.Move2_PP = pk.GetMovePP(pk.Move2, pk.Move2_PPUps);
pk.Move3_PP = pk.GetMovePP(pk.Move3, pk.Move3_PPUps);
pk.Move4_PP = pk.GetMovePP(pk.Move4, pk.Move4_PPUps);
Configure the Original Trainer (OT) details:
pk.TID16 = 12345; // Trainer ID
pk.SID16 = 54321; // Secret ID
pk.OriginalTrainerName = "Red";
pk.OriginalTrainerGender = 0; // Male
pk.CurrentFriendship = 255;
Generating Unique Identifiers
Every Pokémon needs unique identifiers:
// Generate Encryption Constant
pk.EncryptionConstant = Util.Rand32();
// Generate PID (Personality ID)
pk.PID = Util.Rand32();
// For shiny Pokémon, use:
pk.SetShiny();
// Or force a specific shiny type:
pk.SetShinySID(Shiny.AlwaysStar); // Square shiny
pk.SetShinySID(Shiny.AlwaysSquare); // Star shiny
Generation-Specific Features
Gen 9 (Scarlet/Violet) - Tera Types
var pk9 = new PK9
{
Species = (ushort)Species.Pikachu,
TeraTypeOriginal = MoveType.Electric,
TeraTypeOverride = MoveType.Water, // Change Tera Type
ObedienceLevel = 50
};
Gen 8 (Sword/Shield) - Dynamax
var pk8 = new PK8
{
Species = (ushort)Species.Charizard,
DynamaxLevel = 10,
CanGigantamax = true // For Gigantamax-capable Pokémon
};
Gen 7 (Sun/Moon) - Hyper Training
var pk7 = new PK7
{
Species = (ushort)Species.Mew,
CurrentLevel = 100, // Must be level 100
HyperTrainFlags = 0x3F // Hyper train all stats
};
Finalizing the Pokémon
Before using or saving a Pokémon, you must refresh its checksum:
// Refresh checksum to validate the data
pk.RefreshChecksum();
// Verify the Pokémon is valid
if (pk.Valid)
{
Console.WriteLine("Pokémon created successfully!");
}
Always call RefreshChecksum() after modifying a Pokémon’s properties to ensure data integrity.
Creating from Blank Templates
PKHeX provides a utility to create blank Pokémon for any format:
using PKHeX.Core;
// Create a blank PK9
var blank = EntityBlank.GetBlank<PK9>();
// Or create from type
var blankFromType = EntityBlank.GetBlank(typeof(PK9));
Complete Example
Here’s a complete example creating a competitive Pokémon:
using PKHeX.Core;
public PKM CreateCompetitivePokemon()
{
var pk = new PK9
{
// Basic Info
Species = (ushort)Species.Garchomp,
Form = 0,
Gender = 0,
Nature = Nature.Jolly,
StatNature = Nature.Jolly,
Ability = (int)Ability.RoughSkin,
CurrentLevel = 50,
Ball = (byte)Ball.Poke,
// IVs (Perfect)
IV_HP = 31,
IV_ATK = 31,
IV_DEF = 31,
IV_SPA = 31,
IV_SPD = 31,
IV_SPE = 31,
// EVs (Optimized spread)
EV_ATK = 252,
EV_SPE = 252,
EV_HP = 6,
// Moves
Move1 = (ushort)Move.Earthquake,
Move2 = (ushort)Move.DragonClaw,
Move3 = (ushort)Move.StoneEdge,
Move4 = (ushort)Move.SwordsDance,
// Trainer Info
OriginalTrainerName = "Player",
OriginalTrainerGender = 0,
TID16 = 12345,
SID16 = 54321,
Language = (int)LanguageID.English,
CurrentFriendship = 255,
// Gen 9 Features
TeraTypeOriginal = MoveType.Ground,
ObedienceLevel = 50
};
// Generate unique identifiers
pk.EncryptionConstant = Util.Rand32();
pk.PID = Util.Rand32();
// Set PP for all moves
pk.Move1_PP = pk.GetMovePP(pk.Move1, 0);
pk.Move2_PP = pk.GetMovePP(pk.Move2, 0);
pk.Move3_PP = pk.GetMovePP(pk.Move3, 0);
pk.Move4_PP = pk.GetMovePP(pk.Move4, 0);
// Finalize
pk.RefreshChecksum();
return pk;
}
Next Steps