Each step or turn in place in grass, or anywhere in a cave, rolls the map's rate out of 256, then one of ten slots weighted from 51 down to 3; a Repel turns away only Pokémon below the first Pokémon's level, so it saves battles, not steps.
A step in grass starts a wild battle 251 times in 256 on Route 1, about once every 10.22 steps, and only 83 times in 256 in Viridian Forest, once every 322,1,2. Each battle then draws one of ten slots, some far rarer than others, and each slot holds one species at one level4,5. A Pikachu fills two of Viridian Forest’s slots, 5.53% of its battles, so finding one takes about 6203 steps of grass on average, a turn in place counting as a step3.
A Repel doesn’t bring it sooner. It turns away only wild Pokémon below the level of the first Pokémon in the party, after the step has already picked them, so it spares the battles in between but not the steps6,7. A Repel can even turn away the Pokémon wanted: ahead of anything stronger than the weaker of Viridian Forest’s two Pikachu, it stretches the walk to about 28003 steps3.
In Red, with no Repel and a level 5 Pokémon first in the party, each step or turn in place in Viridian Forest's grass starts a battle 3.1% of the time. Of the wild Pokémon that turn up there, 5.5% are a Pikachu that gets to battle, so a step or turn meets one 0.2% of the time.
In caves, Pokémon Tower, the Power Plant, and Pokémon Mansion every step off the water can start a battle; on routes, in Viridian Forest, and in the Safari Zone only a step in grass or on water can8. A turn counts as a step: pressing a new direction while standing turns the player in place first, and the turn rolls on the tile underfoot8. Surfing on open water meets only Tentacool, and only on Routes 19, 20, and 21, the three places with a water list; the water in Seafoam Islands and Cerulean Cave meets nothing9. A shore whose water shows only in the bottom-right corner of the player’s square, as on Cinnabar Island’s east coast, rolls the water rate but draws from the grass list10.
Some steps can’t start a battle anywhere: the first two after a battle, a ledge jump, a step out of a door, and a step onto a door or a warp11,12. A turn in place doesn’t count toward those two, and can’t start a battle before they’re taken11. Those two steps after each battle are part of the averages above3.
Every place has its own ten slots, and the slots’ weights are the same everywhere, 51 · 51 · 39 · 25 · 25 · 25 · 13 · 13 · 11 · 3 (of 256)4,4. A species in the last slot alone comes up about once in 85.37 battles, as Mt. Moon’s Clefairy does7. Red and Blue fill many slots differently, Route 4’s Ekans in Red with Sandshrew in Blue among them, and almost always the level stays the same5.
A Repel lasts 10013 steps, a Super Repel 20013, and a Max Repel 25013; a new one replaces whatever was left13. Steps and turns in towns and on paths count as well as those in grass, but the two steps after a battle and the other steps that can’t start one don’t13,11. The step on which it wears off meets nothing13.
While it lasts, a wild Pokémon at or above the first party Pokémon’s level still appears; one below it is turned away, and that step meets nothing6. Battles get rarer, but the roll and the slot are the same as without a Repel6. The first Pokémon counts even if it has fainted6. On Mt. Moon 1F, a Repel ahead of a Pokémon at the Clefairy’s level cuts the battles per Clefairy from 85.37 to 607, but the walk only from about 23507 steps to 23007,7.
A rod works facing water or a shore, outside battle, and not while surfing. A hooked Pokémon starts its battle at once, so neither a Repel nor the steps after a battle stop it14. The Old Rod always hooks a level-5 Magikarp15. The Good Rod bites 33.316% of the time, a Goldeen or a Poliwag, on any map16,17.
The Super Rod hooks from a list of two to four Pokémon that depends on the map, and finds nothing on maps without one18. The longer the list, the more often it bites: 5019% with four, 42.919% with three, and 33.319% with two19. Its only Dratini are in the Safari Zone18.
^ abCodepret/pokeredwild_encounters.asm 26–53; Route1.asm 1–2How we knowengine/battle/wild_encounters.asm at af51989Our readingthe step's tile picks the rate (not all quoted)26–33a random byte not below the rate: no battle50–53
^ abcCodepret/pokeredwild_encounters.asm 54–62; probabilities.asm 11–28How we knowengine/battle/wild_encounters.asm at af51989Our readingb ← the second random byte54–55read the slot table (pokered-wild/slot-pick)56
^ abCodepret/pokeredRoute1.asm 1–16; Route2.asm 1–25; +58 filesHow we know
1Route1WildMons:
2 def_grass_wildmons 25 ; encounter rate
3 db 3, PIDGEY
4 db 3, RATTATA
5 db 3, RATTATA
6 db 2, RATTATA
7 db 2, PIDGEY
8 db 3, PIDGEY
9 db 3, PIDGEY
10 db 4, RATTATA
11 db 4, PIDGEY
12 db 5, PIDGEY
⋮
data/wild/maps/Route1.asm lines 1–16 at af51989 · upstream ↗
1Route2WildMons:
2 def_grass_wildmons 25 ; encounter rate
3 db 3, RATTATA
4 db 3, PIDGEY
5 db 4, PIDGEY
6 db 4, RATTATA
7 db 5, PIDGEY
8IF DEF(_RED)
9 db 3, WEEDLE
10 db 2, RATTATA
11 db 5, RATTATA
12 db 4, WEEDLE
⋮
data/wild/maps/Route2.asm lines 1–25 at af51989 · upstream ↗
1Route3WildMons:
2 def_grass_wildmons 20 ; encounter rate
3 db 6, PIDGEY
4 db 5, SPEAROW
5 db 7, PIDGEY
6 db 6, SPEAROW
7 db 7, SPEAROW
8 db 8, PIDGEY
9 db 8, SPEAROW
10 db 3, JIGGLYPUFF
11 db 5, JIGGLYPUFF
12 db 7, JIGGLYPUFF
⋮
data/wild/maps/Route3.asm lines 1–16 at af51989 · upstream ↗engine/overworld/wild_mons.asm at af51989Our readingfind the map's entry in the pointer table1–12grass rate ← the list's first byte13–14rate 0: skip to the water part15–16else copy the 20 bytes after it to the grass list17–23water rate ← the next byte25–26rate 0: done27–28else copy the 20 bytes after it to the water list29–31
^ abcdCodepret/pokeredwild_encounters.asm 81–89How we knowengine/battle/wild_encounters.asm at af51989Our readingno Repel steps left: battle81–83b ← the first party Pokémon's level84–85the wild level below b: no encounter86–88else battle89
^ abCodepret/pokeredwild_encounters.asm 26–47; tileset_headers.asm 1–36; +34 filesHow we knowengine/battle/wild_encounters.asm at af51989Our readingtile ← the half-block's bottom-right tile (by the comment)26–29the tileset's grass tile: rate ← the grass rate30–33tile $14, water (by the comment): rate ← the water rate34–37an outdoor map (by the comment): no encounter41–43the forest tileset: no encounter44–46otherwise: rate ← the grass rate47
data/maps/headers/ViridianForest.asm line 1 at af51989 · upstream ↗home/overworld.asm at af51989Our readingno direction held: turn check ← 1136–137 a direction was held: last direction ← it138–142 held direction ← none143–144a direction pressed: new direction ← it180scripted movement: no turn, walk181–183turn check 0 (already moving): no turn, walk184–186the last direction again: no turn, walk187–191a reversal: face a side first (by the comment)192–223turn check − 1, to 0; face the new direction224–231try a battle with no step (NewBattle, its check)232a battle happened: the after-battle handling233else back to the loop234
^Codepret/pokeredwild_mons.asm 24–28; wild_encounters.asm 34–37, 48–53How we knowengine/overworld/wild_mons.asm at af51989Our readingwater rate ← the list's water byte25–26rate 0: no water list27–28engine/battle/wild_encounters.asm at af51989Our readingtile $14 (water, by the comment): rate ← the water rate34–37a random byte not below the rate: no encounter50–53
^Codepret/pokeredwild_encounters.asm 63–73How we knowengine/battle/wild_encounters.asm at af51989Our readingthe slot's offset into the list (from the slot table)65list ← the grass list66the bottom-left tile is $14: list ← the water list67–70
^ abcCodepret/pokeredwild_encounters.asm 1–18; core.asm 6661–6664How we knowengine/battle/wild_encounters.asm at af51989Our readingan NPC movement script is set (by its label): none4–6a door exit, ledge jump, or fishing (by the comment): none7–9on a door or warp tile (by its label): none10–15just outside the map (by its label): none17–18engine/battle/core.asm at af51989Our readingno-battle steps left: no encounter check6661–6663else the encounter check (wild_encounters.asm)6664
^Codepret/pokeredend_of_battle.asm 46–70; overworld.asm 341–358, 756–770, 6–17, 291–320, 321–340, 362–371; +2 filesHow we knowengine/battle/end_of_battle.asm at af51989Our readingclear the low-health alarm and channel 5's sound47–49clear the in-battle value, the battle type, and other values50–62clear the battle status block, a byte at a time63–68set the encounter cooldown flag69–70home/overworld.asm at af51989Our readingset the battle-over-or-blackout flag341–342if the map is Oak's lab: skip the fainting check343–345if the party-alive test (its lines not quoted) returns 0: black out346–349no fainting check: wait 10 frames (the delay's lines not quoted)351–352 load the map (EnterMap, below)353black out: in-battle value ← lost355–356 run the map's script (its lines not quoted)357 go to the blackout routine (below)358fade to black and stop the music (their lines not quoted)759–761clear the battle-over-or-blackout flag762–763switch to the reset routine's ROM bank (by the comment, the warp's too)764–766call routines (their lines not quoted) named for: resetting status and halving the money767 preparing the special warp768 the map's music769go to the warp's map load (SpecialEnterMap, below)770engine/menus/main_menu.asm at af51989Our readingclear the button bytes and the Cable Club destination328–332start the game timer counting333–334reset the player's sprite (its lines not quoted); wait 20 frames335–337if the entering-Cable-Club flag is set: return338–340load the map (EnterMap, below)341home/overworld.asm at af51989Our readingignore all buttons8–9load the map's data, clear the map-entry values (their lines not quoted)10–11if the cooldown flag is set: no-battle steps ← 312–16if the movement is scripted (simulated button presses): skip the counting292–294step counter (a separate one) − 1296–297if the cooldown flag is set:298–300 no-battle steps − 1301–302 if that reaches 0: clear the cooldown flag303–305in the Safari Zone:307–308 check its step limit (its lines not quoted)309 if the Safari game is over: warp out310–312if the in-battle value isn't 0: go to the warp check314–316apply poison damage outside battle (its lines not quoted)317if the out-of-battle blackout flag is set: black out318–320try a battle (NewBattle, below)322clear the standing-on-warp flag323–324if no battle happened (carry clear): go to the warp check325after a battle: clear the talked-to-trainer and trainer-battle flags327–330 set the two map-loaded flags; clear the held buttons331–335 in Cinnabar Gym: set event $2A7 (unnamed upstream)336–339if the player is on a dungeon warp: no battle363–365if the game is moving the player (its test's lines not quoted): no battle366–367if the no-battles flag is set: no battle368–370go to the battle setup (InitBattle, below)371engine/battle/core.asm at af51989Our readingif the opponent byte is 0 (no set opponent): pick a wild one (below)6643–6645if debug mode is on and B is held: return, no wild battle6654–6659if the no-battle steps aren't 0: return, no wild battle6661–6663try a wild encounter (its lines not quoted)6664if the subtraction before it (not quoted) set carry: go to the wild battle's setup6676go to the shared battle setup (below)6693
6734; common code that executes after init battle code specific to trainer or wild battles
6735_InitBattleCommon:
engine/battle/core.asm lines 6733–6735 at af51989 · upstream ↗engine/battle/core.asm at af51989Our readingrun the battle (its lines not quoted)6763then the end of battle (EndOfBattle, the first entry)6764
^Codepret/pokereditem_effects.asm 1891–1916, 2826–2851, 1866–1877; overworld.asm 64–66; +1 filesHow we knowengine/items/item_effects.asm at af51989Our readingin battle: can't fish1894–1898the tile ahead isn't shore or water (below): can't fish1900–1901surfing: can't fish1902–1904else print the use text, play a sound, wait 80 frames1905–1913a tileset without water: no2830–2834Vermilion Dock's tileset: water only2835–2838an eastern shore tile ($48 or $32): yes2839–2842the water tile, $14: yes2844–2845a bite: the opponent ← the species, at its level1866–1877home/overworld.asm at af51989Our readingan opponent is set: start a battle64–66engine/battle/core.asm at af51989Our readingno opponent set: the wild encounter check6643–6645else battle that opponent6647–6651
^Codepret/pokereditem_effects.asm 1826–1831How we knowengine/items/item_effects.asm at af51989Our readingcan't fish here: refuse (by its label)1827–1828level 5, Magikarp; a bite1829–1831
^ abCodepret/pokereditem_effects.asm 1833–1857How we knowengine/items/item_effects.asm at af51989Our readingcan't fish here: refuse (by its label)1834–1835draw a random byte; shift out its low bit1836–1838low bit 1: no bite1839n ← the next two bits; n of 2 or 3: draw again1840–1842level, species ← the list's entry n1844–1851carry clear: a bite; set: none1852–1857
^ abcdCodepret/pokereditem_effects.asm 2855–2898, 1861–1865How we knowengine/items/item_effects.asm at af51989Our readingthe map has no list: nothing here2859–2865b ← the list's size2867–2877draw a random byte; low bit 1: no bite2880–2883n ← the next two bits; n not below b: draw again2885–2887level, species ← entry n; a bite2889–2898can't fish here: refuse (by its label)1862–1863read the map's list (above)1864–1865