summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Make-wild-Pokémon-encounter-levels-vary.md155
1 files changed, 149 insertions, 6 deletions
diff --git a/Make-wild-Pokémon-encounter-levels-vary.md b/Make-wild-Pokémon-encounter-levels-vary.md
index 539446c..176f63b 100644
--- a/Make-wild-Pokémon-encounter-levels-vary.md
+++ b/Make-wild-Pokémon-encounter-levels-vary.md
@@ -1,15 +1,34 @@
-Sometimes, you might want to create custom encounter tables. For example:
+Pokémon Crystal, and the rest of the Gen 2 games use a slot-based encounter table,
+rolling against the current area's table to generate a wildmon for the player to fight.
+
+You can only fit so many Pokémon in an area's wild encounter table, and specify the level of each slot.
+If you wanted to have variance in levels, you would have to use another slot for the same Pokémon at a different level,
+thus limiting the amount of unique wildmon in that location. (Example: A Level 3 Rattata, and a Level 4 Rattata require two slots)
+
+This tutorial will teach you how to get around that and be able to use fewer slots (freeing up more for more unique species!), via two different methods:
+* Custom encounter table with level probabilities
+
+or
+
+* Hijacking the surf variance code
+
+Each has their benefits; The former allows more fine-tuned control over the level variance, albeit a more invested change,
+while the latter is much simpler to implement across the game, while requiring less setup and lacking more control over the levels.
+
+I'd recommend starting with the easier method first, to understand how this works and what exactly it does,
+before moving on to a more complex implementation.
+
+You decide what works best for you and your vision for your fangame!
-![Custom Encounter Rates](https://user-images.githubusercontent.com/38602758/110269446-b6c95280-7ffe-11eb-9ac0-1de06894094e.png)
-If you add [wild Pokémon slots](Add-a-new-wild-Pokémon-slot) to accommodate all encounters in the morning, you need to use 19 slots because each level is placed in one slot. So for example, you need to use 3 slots for Abra: Lv. 13 Abra, Lv. 14 Abra, and Lv. 15 Abra. In this tutorial, we can use fewer slots while keeping the variety of wild Pokémon in an area.
## Contents
1. [Understanding Bug Catching Contest Encounter Code](#1-understanding-bug-catching-contest-encounter-code)
2. [Add max levels in probabilities](#2-add-max-levels-in-probabilities)
3. [Change wild encounter algorithm](#3-change-wild-encounter-algorithm)
-4. [Other notes](#4-Other-notes)
+4. [Other notes for Method 1](#4-Other-notes-for-Method-1)
+5. [Method #2: Hijack the surf variance code](#5-Method-2-hijack-the-surf-variance-code)
## 1. Understanding Bug Catching Contest Encounter Code
@@ -91,6 +110,7 @@ ContestMons:
We can see that there's a minimum and maximum level for every wild Pokémon. The last slot, occupied by Venomoth, signals the end of the list. We can use a part of the algorithm of Bug Catching Contest encounters in (events.asm)[https://github.com/pret/pokecrystal/blob/master/engine/overworld/events.asm] to randomize regular wild encounters.
+
## 2. Add max levels in probabilities
Edit [data/wild/probabilities.asm](https://github.com/pret/pokecrystal/blob/master/data/wild/probabilities.asm).
@@ -115,6 +135,7 @@ Edit [data/wild/probabilities.asm](https://github.com/pret/pokecrystal/blob/mast
The `MaxLevelGrass` and `MaxLevelWater` contain the level buffs to obtain the highest leveled encounter on that area. For example, if the first slot in the encounter table is Lv. 2, then the max level for the wild mon is Lv. 4.
+
## 3. Change wild encounter algorithm
Finally, we change the wild encounter algorithm in [engine/overworld/wildmons.asm](https://github.com/pret/pokecrystal/blob/master/engine/overworld.wildmons.asm):
@@ -189,6 +210,128 @@ Finally, we change the wild encounter algorithm in [engine/overworld/wildmons.as
And there you have it! Wild encounters have been randomized.
-## 4. Other notes
-Take note that the slots in `MaxLevelGrass` and `MaxLevelWater` in [data/wild/probabilities.asm](https://github.com/pret/pokecrystal/blob/master/data/wild/probabilities.asm) is the same as the probability slots in probabilities.asm. Also, each slot is tied to the wild Pokémon slots in [data/wild](https://github.com/pret/pokecrystal/blob/master/data/wild)/<johto_grass/johto_water/kanto_grass/kanto_water>.asm. Thus if you use the tutorial to [add a wild Pokémon slot](Add-a-new-wild-Pokémon-slot), you also need to add slots in `MaxLevelGrass` and/or `MaxLevelWater`. \ No newline at end of file
+## 4. Other notes for Method 1
+
+Take note that the slots in `MaxLevelGrass` and `MaxLevelWater` in [data/wild/probabilities.asm](https://github.com/pret/pokecrystal/blob/master/data/wild/probabilities.asm) is the same as the probability slots in probabilities.asm. Also, each slot is tied to the wild Pokémon slots in [data/wild](https://github.com/pret/pokecrystal/blob/master/data/wild)/<johto_grass/johto_water/kanto_grass/kanto_water>.asm. Thus if you use the tutorial to [add a wild Pokémon slot](Add-a-new-wild-Pokémon-slot), you also need to add slots in `MaxLevelGrass` and/or `MaxLevelWater`.
+
+Sometimes, you might want to create custom encounter tables. For example:
+
+![Custom Encounter Rates](https://user-images.githubusercontent.com/38602758/110269446-b6c95280-7ffe-11eb-9ac0-1de06894094e.png)
+
+If you add [wild Pokémon slots](Add-a-new-wild-Pokémon-slot) to accommodate all encounters in the morning, you need to use 19 slots because each level is placed in one slot. So for example, you need to use 3 slots for Abra: Lv. 13 Abra, Lv. 14 Abra, and Lv. 15 Abra. After following this tutorial, you no longer need so many of the same Pokémon occupying multiple slots in the table, so extra slots can now mean more unique species in an area!
+
+
+## 5. Method #2: Hijack the surf variance code
+
+The former tutorial made use of the surf variance code in a more complex way, allowing for more finer control over the tables. This method is a lot simpler to implement, and has a similar effect, but lacks that deeper control of the encounter levels.
+
+Head on over to `ChooseWildEncounter` in [engine/overworld/wildmons.asm](https://github.com/pret/pokecrystal/blob/master/engine/overworld.wildmons.asm):
+
+```
+; If the Pokemon is encountered by surfing, we need to give the levels some variety.
+ call CheckOnWater
+ jr nz, .ok
+; Check if we buff the wild mon, and by how much.
+ call Random
+ cp 35 percent
+ jr c, .ok
+ inc b
+ cp 65 percent
+ jr c, .ok
+ inc b
+ cp 85 percent
+ jr c, .ok
+ inc b
+ cp 95 percent
+ jr c, .ok
+ inc b
+; Store the level
+.ok
+```
+
+Let's break it down.
+
+As you can see, there IS level variance code right in the original game! It calls `CheckOnWater` to see if player is currently surfing and if so, falls through to call `Random`.
+`Random` will randomly choose one of these percentages, and then add that percentage to `b`, adding the rolled variance level to the level of the currently encountered surfing Pokémon inside `b`.
+
+The slots for surfing Pokémon are the minimum level for that slot, as is the logic for any encounter table slot. Through the use of `Random`, however, surfing Pokémon have a chance to be
+encountered at levels higher than their set level in the encounter slot.
+
+See below:
+* +0: 35% chance
+* +1: 30%
+* +2: 20%
+* +3: 10%
+* +4: 5%
+
+These probabilities are approximate, as an 8-bit register is limited in the range of values it can take!
+
+Well, now we know what exactly the game does when you encounter a surfing Pokémon...
+
+What happens if we just... remove that `CheckOnWater`?
+
+```diff
+-; If the Pokemon is encountered by surfing, we need to give the levels some variety.
+- call CheckOnWater
+- jr nz, .ok
+; Check if we buff the wild mon, and by how much.
+ call Random
+ cp 35 percent
+ jr c, .ok
+ inc b
+ cp 65 percent
+ jr c, .ok
+ inc b
+ cp 85 percent
+ jr c, .ok
+ inc b
+ cp 95 percent
+ jr c, .ok
+ inc b
+; Store the level
+.ok
+```
+
+Wow! Now any encountered wild Pokémon can vary up to 0-4 levels, in grass, in caves, in water... anywhere!
+That is all you need to do to achieve this functionality, but it also has some caveats. Anywhere does mean anywhere...
+Including Legendary Pokémon.
+
+What if you don't want special wild encounters to have level variance?
+
+Just load `wBattleType` into `a`, and check for the specific special encounter type before the first `Random` call.
+
+```diff
++; If the Pokemon is encountered in a special way, skip randomizing level.
++ ld a, [wBattleType]
++ cp BATTLETYPE_SUICUNE
++ jr z, .ok
+; Check if we buff the wild mon, and by how much.
+ call Random
+ cp 35 percent
+ jr c, .ok
+ inc b
+ cp 65 percent
+ jr c, .ok
+ inc b
+ cp 85 percent
+ jr c, .ok
+ inc b
+ cp 95 percent
+ jr c, .ok
+ inc b
+; Store the level
+.ok
+```
+
+Now when the player encounters a wildmon, it will now check the `wBattleType` and see if it is `BATTLETYPE_SUICUNE`. If it is `BATTLETYPE_SUICUNE`, then it will skip the random level variance and jump down to `.ok`.
+You can add multiple checks for different encounter types, or even specify special encounter types that DO make use of the level variance.
+
+Armed with this new level variance technology, entering an unedited Route 29 during the day and rummaging through the grass, you could now encounter:
+* Rattata: Levels 2-6
+* Sentret: Levels 2-7
+* Pidgey: Levels 2-7
+* Hoppip: Levels 3-7
+
+Whichever way you decide to implement level variance, it makes for a much more diverse experience exploring the overworld.
+ \ No newline at end of file