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
- BoxPokemon (48-byte encrypted)
- Pokemon (party, with computed stats)
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.struct Pokemon extends BoxPokemon with the unencrypted computed battle stats (HP, Attack, Defense, Speed, Sp. Atk, Sp. Def), the current HP, level, STATUS1, and mail index.Party Pokémon are kept in gPlayerParty[PARTY_SIZE] and gEnemyParty[PARTY_SIZE].// include/pokemon.h
struct BoxPokemon {
u32 personality;
u32 otId;
u8 nickname[POKEMON_NAME_LENGTH];
u8 language;
u8 isBadEgg:1;
u8 hasSpecies:1;
u8 isEgg:1;
u8 otName[PLAYER_NAME_LENGTH];
u8 markings;
u16 checksum;
u16 unknown;
union PokemonSubstruct secure[4]; // XOR-encrypted with personality ^ otId
};
struct Pokemon {
struct BoxPokemon box;
u32 status; // STATUS1 bitmask
u8 level;
u8 mail;
u16 hp;
u16 maxHP;
u16 attack;
u16 defense;
u16 speed;
u16 spAttack;
u16 spDefense;
};
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:| Substruct | Contents |
|---|---|
PokemonSubstruct0 | Species, held item, experience, PP bonuses, friendship |
PokemonSubstruct1 | Moves (4 slots), PP (4 slots) |
PokemonSubstruct2 | HP/Atk/Def/Speed/SpAtk/SpDef EVs; contest stats (Cool/Beauty/Cute/Smart/Tough/Sheen) |
PokemonSubstruct3 | Pokérus, met location, met level, met game, Poké Ball, OT gender, all 6 IVs (5 bits each), isEgg, abilityNum, all contest ribbons, champion/winning/victory ribbons, fateful encounter bit |
GetMonData / SetMonData
All Pokémon attribute access goes throughGetMonData and SetMonData, which handle decryption, substruct routing, and re-encryption automatically.
// Read a species
u16 species = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES);
// Read a nickname string
u8 nickname[POKEMON_NAME_LENGTH + 1];
GetMonData(&gPlayerParty[0], MON_DATA_NICKNAME, nickname);
// Write a friendship value
u8 friendship = 255;
SetMonData(&gPlayerParty[0], MON_DATA_FRIENDSHIP, &friendship);
MON_DATA_* enum
The complete list of property labels accepted byGetMonData / SetMonData (from include/pokemon.h):
enum {
MON_DATA_PERSONALITY, // u32 — personality value
MON_DATA_OT_ID, // u32 — original trainer ID
MON_DATA_NICKNAME, // u8[] — nickname string
MON_DATA_LANGUAGE, // u8
MON_DATA_SANITY_IS_BAD_EGG, // u8
MON_DATA_SANITY_HAS_SPECIES, // u8
MON_DATA_SANITY_IS_EGG, // u8
MON_DATA_OT_NAME, // u8[] — OT name string
MON_DATA_MARKINGS, // u8
MON_DATA_CHECKSUM, // u16
MON_DATA_ENCRYPT_SEPARATOR, // u16
MON_DATA_SPECIES, // u16
MON_DATA_HELD_ITEM, // u16
MON_DATA_MOVE1, // u16
MON_DATA_MOVE2, // u16
MON_DATA_MOVE3, // u16
MON_DATA_MOVE4, // u16
MON_DATA_PP1, // u8
MON_DATA_PP2, // u8
MON_DATA_PP3, // u8
MON_DATA_PP4, // u8
MON_DATA_PP_BONUSES, // u8
MON_DATA_COOL, // u8 — contest Cool stat
MON_DATA_BEAUTY, // u8 — contest Beauty stat
MON_DATA_CUTE, // u8 — contest Cute stat
MON_DATA_EXP, // u32
MON_DATA_HP_EV, // u8
MON_DATA_ATK_EV, // u8
MON_DATA_DEF_EV, // u8
MON_DATA_SPEED_EV, // u8
MON_DATA_SPATK_EV, // u8
MON_DATA_SPDEF_EV, // u8
MON_DATA_FRIENDSHIP, // u8
MON_DATA_SMART, // u8 — contest Smart stat
MON_DATA_POKERUS, // u8
MON_DATA_MET_LOCATION, // u8
MON_DATA_MET_LEVEL, // u8 (7 bits)
MON_DATA_MET_GAME, // u8 (4 bits)
MON_DATA_POKEBALL, // u8 (4 bits)
MON_DATA_HP_IV, // u8 (5 bits)
MON_DATA_ATK_IV, // u8 (5 bits)
MON_DATA_DEF_IV, // u8 (5 bits)
MON_DATA_SPEED_IV, // u8 (5 bits)
MON_DATA_SPATK_IV, // u8 (5 bits)
MON_DATA_SPDEF_IV, // u8 (5 bits)
MON_DATA_IS_EGG, // u32 (1 bit — inside substruct3)
MON_DATA_ABILITY_NUM, // u8 (1 bit) — 0 or 1, selects ability slot
MON_DATA_TOUGH, // u8 — contest Tough stat
MON_DATA_SHEEN, // u8 — contest Sheen
MON_DATA_OT_GENDER, // u8 (1 bit)
MON_DATA_COOL_RIBBON, // u8 (3 bits) — highest Cool contest rank
MON_DATA_BEAUTY_RIBBON, // u8 (3 bits)
MON_DATA_CUTE_RIBBON, // u8 (3 bits)
MON_DATA_SMART_RIBBON, // u8 (3 bits)
MON_DATA_TOUGH_RIBBON, // u8 (3 bits)
MON_DATA_STATUS, // u32 — STATUS1 bitmask (party only)
MON_DATA_LEVEL, // u8 (party only)
MON_DATA_HP, // u16 (party only)
MON_DATA_MAX_HP, // u16 (party only)
MON_DATA_ATK, // u16 (party only)
MON_DATA_DEF, // u16 (party only)
MON_DATA_SPEED, // u16 (party only)
MON_DATA_SPATK, // u16 (party only)
MON_DATA_SPDEF, // u16 (party only)
MON_DATA_MAIL, // u8 (party only)
MON_DATA_SPECIES_OR_EGG, // u16 — species or EGG_SPECIES if egg
MON_DATA_IVS, // u32 — all 6 IVs packed
MON_DATA_CHAMPION_RIBBON,
MON_DATA_WINNING_RIBBON,
MON_DATA_VICTORY_RIBBON,
MON_DATA_ARTIST_RIBBON,
MON_DATA_EFFORT_RIBBON,
MON_DATA_MARINE_RIBBON,
MON_DATA_LAND_RIBBON,
MON_DATA_SKY_RIBBON,
MON_DATA_COUNTRY_RIBBON,
MON_DATA_NATIONAL_RIBBON,
MON_DATA_EARTH_RIBBON,
MON_DATA_WORLD_RIBBON,
MON_DATA_UNUSED_RIBBONS,
MON_DATA_MODERN_FATEFUL_ENCOUNTER,
MON_DATA_KNOWN_MOVES,
MON_DATA_RIBBON_COUNT,
MON_DATA_RIBBONS,
MON_DATA_ATK2,
MON_DATA_DEF2,
MON_DATA_SPEED2,
MON_DATA_SPATK2,
MON_DATA_SPDEF2,
};
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 inPokemonSubstruct2. Ribbon ranks (Normal, Super, Hyper, Master) are stored as 3-bit values in PokemonSubstruct3.
| Property | Description |
|---|---|
MON_DATA_COOL | Cool contest stat (0–255) |
MON_DATA_BEAUTY | Beauty contest stat (0–255) |
MON_DATA_CUTE | Cute contest stat (0–255) |
MON_DATA_SMART | Smart contest stat (0–255) |
MON_DATA_TOUGH | Tough contest stat (0–255) |
MON_DATA_SHEEN | Sheen — limits Pokéblock feeding |
MON_DATA_COOL_RIBBON | Highest Cool contest rank achieved |
MON_DATA_BEAUTY_RIBBON | Highest Beauty contest rank achieved |
MON_DATA_CUTE_RIBBON | Highest Cute contest rank achieved |
MON_DATA_SMART_RIBBON | Highest Smart contest rank achieved |
MON_DATA_TOUGH_RIBBON | Highest Tough contest rank achieved |
MON_DATA_CHAMPION_RIBBON | Given when defeating the Champion |
MON_DATA_WINNING_RIBBON | Battle Tower Lv. 50 streak of 56+ |
MON_DATA_VICTORY_RIBBON | Battle Tower Lv. 100 streak of 56+ |
MON_DATA_ARTIST_RIBBON | Master Rank contest with 800+ points; portrait placed in museum |
MON_DATA_EFFORT_RIBBON | Given at Slateport to Pokémon with maximum EVs |
MON_DATA_MARINE_RIBBON | Never distributed |
MON_DATA_LAND_RIBBON | Never distributed |
MON_DATA_SKY_RIBBON | Never distributed |
MON_DATA_COUNTRY_RIBBON | Distributed at Pokémon Festa ‘04 and ‘05 |
MON_DATA_NATIONAL_RIBBON | Given to purified Shadow Pokémon in Colosseum/XD |
MON_DATA_EARTH_RIBBON | Given for clearing Mt. Battle in Colosseum/XD |
MON_DATA_WORLD_RIBBON | Distributed at Pokémon Festa ‘04 and ‘05 (winners) |
Status conditions
STATUS1 — persistent (saved)
STATUS1 — persistent (saved)
MON_DATA_STATUS returns the STATUS1 bitmask from struct Pokemon. This persists between battles.// include/constants/pokemon.h
#define STATUS1_SLEEP 0x7 // bits 0-2: sleep turn counter
#define STATUS1_POISON (1 << 3)
#define STATUS1_BURN (1 << 4)
#define STATUS1_FREEZE (1 << 5)
#define STATUS1_PARALYSIS (1 << 6)
#define STATUS1_TOXIC_POISON (1 << 7)
STATUS2 — volatile (in-battle only)
STATUS2 — volatile (in-battle only)
STATUS2 is stored in struct BattlePokemon and tracks volatile in-battle effects. It is not saved in struct Pokemon.// include/constants/pokemon.h
#define STATUS2_CONFUSION 0x00000007
#define STATUS2_FLINCHED (1 << 3)
#define STATUS2_UPROAR 0x00000070
#define STATUS2_BIDE (1 << 8)
#define STATUS2_LOCK_CONFUSE (1 << 9)
#define STATUS2_MULTIPLETURNS (1 << 10)
#define STATUS2_WRAPPED 0x00003800
#define STATUS2_INFATUATION 0x000F0000 // bits per battler
#define STATUS2_FOCUS_ENERGY (1 << 20)
#define STATUS2_TRANSFORMED (1 << 21)
#define STATUS2_RECHARGE (1 << 22)
#define STATUS2_RAGE (1 << 23)
#define STATUS2_SUBSTITUTE (1 << 24)
#define STATUS2_DESTINY_BOND (1 << 25)
#define STATUS2_ESCAPE_PREVENTION (1 << 26)
#define STATUS2_NIGHTMARE (1 << 27)
#define STATUS2_CURSED (1 << 28)
#define STATUS2_FORESIGHT (1 << 29)
#define STATUS2_DEFENSE_CURL (1 << 30)
#define STATUS2_TORMENT (1u << 31)
Creating Pokémon
// include/pokemon.h
// Standard creation — random IVs and personality
void CreateMon(struct Pokemon *mon, u16 species, u8 level,
u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality,
u8 otIdType, u32 fixedOtId);
// Specify nature
void CreateMonWithNature(struct Pokemon *mon, u16 species, u8 level,
u8 fixedIV, u8 nature);
// Specify exact IVs and personality
void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level,
u32 ivs, u32 personality);
// Recalculate stats after modifying data
void CalculateMonStats(struct Pokemon *mon);