Skip to main content
All Pokémon data flows through two structures (BoxMon and Mon) and a unified accessor interface (GetMonData / SetMonData). Understanding this layer is essential for any code that reads or modifies Pokémon attributes.

BoxMon vs Mon

struct BoxPokemon is the 80-byte form stored in the PC box and in saved party data. The secure union holds four 12-byte substructs whose order is determined by personality % 24. All fields inside secure are XOR-encrypted with personality ^ otId.Use GetBoxMonData / SetBoxMonData to access box Pokémon without decrypting manually.
Never access secure substructs directly. The substruct order varies per Pokémon and the data is XOR-encrypted. Always use GetMonData / SetMonData.

Substructs

The four substructs hold distinct data groupings, each 12 bytes:

GetMonData / SetMonData

All Pokémon attribute access goes through GetMonData and SetMonData, which handle decryption, substruct routing, and re-encryption automatically.

MON_DATA_* enum

The complete list of property labels accepted by GetMonData / SetMonData (from include/pokemon.h):
MON_DATA_STATUS and the computed stat fields (MON_DATA_LEVEL, MON_DATA_HP, MON_DATA_ATK, etc.) are only valid for struct Pokemon. They live outside the encrypted box.secure region. Using them via GetBoxMonData returns 0.

Contest stats and ribbons

Contest stats are stored in PokemonSubstruct2. Ribbon ranks (Normal, Super, Hyper, Master) are stored as 3-bit values in PokemonSubstruct3.

Status conditions

MON_DATA_STATUS returns the STATUS1 bitmask from struct Pokemon. This persists between battles.
STATUS2 is stored in struct BattlePokemon and tracks volatile in-battle effects. It is not saved in struct Pokemon.

Creating Pokémon