Don't gain experience at level 100 - pret/pokecrystal GitHub Wiki

At level 100, Pokémon can't usefully gain experience. But until Gen 5, they did so anyway, taking a share from other battle participants who would actually benefit (and wasting time with messages about their gains).

This tutorial shows how to disable experience gain at level 100. It does not affect stat experience (the Gen 1 and 2 precursor to EVs), so you can still use the box trick to raise stats at level 100.

Contents

  1. Skip awarding EXP to level 100 Pokémon
  2. Don't count level 100 Pokémon in the divisor when dividing experience
  3. Discard level 100 Pokémon when counting Exp. Share holders

1. Skip awarding EXP to level 100 Pokémon

The first step is to skip level 100 Pokémon when the game is giving experience to battle participants and Exp. Share holders. For this, let's edit engine/battle/core.asm:

 GiveExperiencePoints:
 ; Give experience.
 ; Don't give experience if linked or in the Battle Tower.

 	...

 .stat_exp_awarded
 	inc de
 	inc de
 	dec c
 	jr nz, .stat_exp_loop
+	pop bc
+	ld hl, MON_LEVEL
+	add hl, bc
+	ld a, [hl]
+	cp MAX_LEVEL
+	jp nc, .next_mon
+	push bc
 	xor a
 	ldh [hMultiplicand + 0], a
 	ldh [hMultiplicand + 1], a
 	ld a, [wEnemyMonBaseExp]
 	ldh [hMultiplicand + 2], a
 	ld a, [wEnemyMonLevel]
 	ldh [hMultiplier], a
 	call Multiply
 	ld a, 7
 	ldh [hDivisor], a
 	ld b, 4
 	call Divide
 	...

Notice how, even though we're stopping max level Pokémon from getting experience, they're still being awarded stat experience (which happens before giving experience to Pokémon).

2. Don't count level 100 Pokémon in the divisor when dividing experience

Even though level 100 Pokémon won't get experience, they're still accounted for when evenly dividing it among battle participants, which will make the resulting experience smaller for the other Pokémon under level 100. For this, let's edit engine/battle/core.asm again, modifying the function responsible of evenly dividing the experience:

 GiveExperiencePoints:
 
 	...
 
 .EvenlyDivideExpAmongParticipants:
 ; count number of battle participants
 	ld a, [wBattleParticipantsNotFainted]
 	ld b, a
 	ld c, PARTY_LENGTH
-	ld d, 0
+	ld de, 0
.count_loop
+	push bc
+	push de
+	ld a, e
+	ld hl, wPartyMon1Level
+	call GetPartyLocation
+	ld a, [hl]
+	cp MAX_LEVEL
+	pop de
+	pop bc
+	jr c, .gains_exp
+	srl b
+	ld a, d
+	jr .no_exp
+.gains_exp
 	xor a
 	srl b
 	adc d
  	ld d, a
+.no_exp
+	inc e
 	dec c
 	jr nz, .count_loop
 	cp 2
 	ret c
 	...

Now when counting each battle participant, it'll first check their levels as a requirement to be counted in the divisor, so all the experience points will be evenly divided among participants that can actually benefit from it.

3. Discard level 100 Pokémon when counting Exp. Share holders

Our level 100 Pokémon are no longer awarded experience and don't affect the experience distribution among battle participants... but what happens when they're holding an Exp. Share? Normally when at least one Pokémon is holding an Exp. Share both the total experience and the stat experience are halved: the first half is evenly distributed among battle participants and the other half among Exp. Share holders; this also applies when level 100 Pokémon are holding the item. This is problematic if all Exp. Share holders are level 100, since we're basically losing 50% of the total experience and stat experience.

The best approach is to discard them while counting how many Pokémon are holding the item. For this, let's go to engine/battle/core.asm again and edit the function which handles counting Exp. Share holders:

 IsAnyMonHoldingExpShare:
 	ld a, [wPartyCount]
 	ld b, a
 	ld hl, wPartyMon1
 	ld c, 1
 	ld d, 0
 .loop
 	push hl
 	push bc
 	ld bc, MON_HP
 	add hl, bc
 	ld a, [hli]
 	or [hl]
 	pop bc
 	pop hl
 	jr z, .next
 
+	push hl
+	push bc
+	ld bc, MON_LEVEL
+	add hl, bc
+	ld a, [hl]
+	cp MAX_LEVEL
+	pop bc
+	pop hl
+	jr nc, .next

	push hl
	push bc
	ld bc, MON_ITEM
	add hl, bc
	pop bc
	ld a, [hl]
	pop hl
	...

The original function had the condition where a Pokémon must be alive before being considered an Exp. Share holder; with our change we added another condition where its level must also be under the maximum.

The only downside of this step is that level 100 Pokémon won't get stat experience from only holding an Exp. Share, so make sure to make them participate in battle!

And with these changes, the tutorial is finally complete! Your fully-trained level 100 Pokémon won't steal precious experience and Stat Exp. anymore!